25#ifndef __SYMMETRIZE_FORCES_HPP__
26#define __SYMMETRIZE_FORCES_HPP__
33symmetrize_forces(Unit_cell
const& uc__, sddk::mdarray<double, 2>& f__)
35 auto& sym = uc__.symmetry();
37 if (sym.size() == 1) {
41 sddk::mdarray<double, 2> sym_forces(3, uc__.spl_num_atoms().local_size());
44 for (
int isym = 0; isym < sym.size(); isym++) {
45 auto const& Rc = sym[isym].spg_op.Rc;
47 for (
int ia = 0; ia < uc__.num_atoms(); ia++) {
48 r3::vector<double> force_ia(&f__(0, ia));
49 int ja = sym[isym].spg_op.sym_atom[ia];
50 auto location = uc__.spl_num_atoms().location(
typename atom_index_t::global(ja));
51 if (location.ib == uc__.comm().rank()) {
52 auto force_ja = dot(Rc, force_ia);
53 for (
int x : {0, 1, 2}) {
54 sym_forces(x, location.index_local) += force_ja[x];
60 double alpha = 1.0 / double(sym.size());
61 for (
int ia = 0; ia < uc__.spl_num_atoms().local_size(); ia++) {
62 for (
int x: {0, 1, 2}) {
63 sym_forces(x, ia) *= alpha;
66 double* sbuf = uc__.spl_num_atoms().local_size() ? sym_forces.at(sddk::memory_t::host) :
nullptr;
67 uc__.comm().allgather(sbuf, f__.at(sddk::memory_t::host), 3 * uc__.spl_num_atoms().local_size(),
68 3 * uc__.spl_num_atoms().global_offset());
Contains definition and partial implementation of sirius::Crystal_symmetry class.
Namespace of the SIRIUS library.