1#ifndef OPERATOR_FORCE_STRESS_UTILS_HPP
2#define OPERATOR_FORCE_STRESS_UTILS_HPP
37template <
typename TK,
typename TR,
typename IntegralFunc,
int ForceSign,
int StressSign>
40 const bool cal_stress,
44 const std::vector<double>& orb_cutoff,
46 IntegralFunc& integral_calculator,
51 std::vector<double> stress_tmp(6, 0);
61 std::vector<double> stress_local(6, 0);
64 #pragma omp for schedule(dynamic)
65 for (
int iat1 = 0; iat1 < ucell->
nat; iat1++)
67 auto tau1 = ucell->
get_tau(iat1);
74 gridD->
Find_atom(*ucell, tau1, T1, I1, &adjs);
76 for (
int ad = 0; ad < adjs.
adj_num + 1; ++ad)
78 const int T2 = adjs.
ntype[ad];
79 const int I2 = adjs.
natom[ad];
80 const int iat2 = ucell->
itia2iat(T2, I2);
85 if (dtau.
norm() * ucell->
lat0 >= orb_cutoff[T1] + orb_cutoff[T2])
92 if (dm_matrix ==
nullptr)
98 double* force_tmp1 = (cal_force) ? &force_local(iat1, 0) :
nullptr;
99 double* force_tmp2 = (cal_force) ? &force_local(iat2, 0) :
nullptr;
105 if (row_indexes.size() == 0 || col_indexes.size() == 0)
110 const double* dm_pointer = dm_matrix->
get_pointer();
111 double olm[4] = {0, 0, 0, 0};
114 std::vector<int> step_trace(npol * npol, 0);
118 step_trace[2] = col_indexes.size();
119 step_trace[3] = col_indexes.size() + 1;
123 for (
int iw1l = 0; iw1l < row_indexes.size(); iw1l += npol)
125 const int iw1 = row_indexes[iw1l] / npol;
126 const int L1 = atom1.
iw2l[iw1];
127 const int N1 = atom1.
iw2n[iw1];
128 const int m1 = atom1.
iw2m[iw1];
129 const int M1 = (m1 % 2 == 0) ? -m1 / 2 : (m1 + 1) / 2;
131 for (
int iw2l = 0; iw2l < col_indexes.size(); iw2l += npol)
133 const int iw2 = col_indexes[iw2l] / npol;
134 const int L2 = atom2.
iw2l[iw2];
135 const int N2 = atom2.
iw2n[iw2];
136 const int m2 = atom2.
iw2m[iw2];
137 const int M2 = (m2 % 2 == 0) ? -m2 / 2 : (m2 + 1) / 2;
140 integral_calculator(T1, L1, N1, M1, T2, L2, N2, M2, dtau, olm);
143 const double dm_current = dm_pointer[0];
149 for (
int i = 0;
i < 3;
i++)
151 force_tmp1[
i] += ForceSign * dm_current * olm[
i + 1];
152 force_tmp2[
i] -= ForceSign * dm_current * olm[
i + 1];
159 stress_local[0] += StressSign * dm_current * olm[1] * dtau.
x;
160 stress_local[1] += StressSign * dm_current * olm[1] * dtau.
y;
161 stress_local[2] += StressSign * dm_current * olm[1] * dtau.
z;
162 stress_local[3] += StressSign * dm_current * olm[2] * dtau.
y;
163 stress_local[4] += StressSign * dm_current * olm[2] * dtau.
z;
164 stress_local[5] += StressSign * dm_current * olm[3] * dtau.
z;
169 dm_pointer += (npol - 1) * col_indexes.size();
178 force += force_local;
182 for (
int i = 0;
i < 6;
i++)
184 stress_tmp[
i] += stress_local[
i];
const std::complex< double > i
Definition cal_pLpR.cpp:46
Definition sltk_grid_driver.h:17
int adj_num
Definition sltk_grid_driver.h:22
std::vector< ModuleBase::Vector3< int > > box
Definition sltk_grid_driver.h:26
std::vector< int > ntype
Definition sltk_grid_driver.h:23
std::vector< int > natom
Definition sltk_grid_driver.h:24
std::vector< int > iw2m
Definition atom_spec.h:17
std::vector< int > iw2l
Definition atom_spec.h:19
std::vector< int > iw2n
Definition atom_spec.h:18
Definition sltk_grid_driver.h:40
void Find_atom(const UnitCell &ucell, const int ntype, const int nnumber, AdjacentAtomInfo *adjs=nullptr) const
Definition sltk_grid_driver.cpp:25
3 elements vector
Definition vector3.h:24
T x
Definition vector3.h:26
T norm(void) const
Get the norm of a Vector3.
Definition vector3.h:216
T y
Definition vector3.h:27
T z
Definition vector3.h:28
void zero_out(void)
Definition matrix.cpp:296
int nr
Definition matrix.h:22
int nc
Definition matrix.h:23
Definition parallel_orbitals.h:9
std::vector< int > get_indexes_col() const
Definition parallel_orbitals.cpp:154
std::vector< int > get_indexes_row() const
gather global indexes of orbitals in this processor get_indexes_row() : global indexes (~NLOCAL) of r...
Definition parallel_orbitals.cpp:140
Atom * atoms
Definition unitcell.h:45
const int & get_npol() const
Definition unitcell.h:104
const ModuleBase::Vector3< double > & get_tau(const int &iat) const
Definition unitcell.h:177
double & lat0
Definition unitcell.h:56
ModuleBase::IntArray & itia2iat
Definition unitcell.h:79
int & nat
Definition unitcell.h:74
const ModuleBase::Vector3< double > cal_dtau(const int &iat1, const int &iat2, const ModuleBase::Vector3< int > &R) const
Definition unitcell.h:183
bool iat2iait(const Tiat iat, Tiait *ia, Tiait *it) const
Definition unitcell.h:117
Definition base_matrix.h:20
T * get_pointer() const
get pointer of value from a submatrix
Definition base_matrix.h:86
Definition hcontainer.h:144
BaseMatrix< T > * find_matrix(int i, int j, int rx, int ry, int rz)
find BaseMatrix with atom index atom_i and atom_j and R index (rx, ry, rz) This interface can be used...
Definition hcontainer.cpp:286
Definition operator_force_stress_utils.cpp:4
void cal_force_stress_2center(const bool cal_force, const bool cal_stress, const hamilt::HContainer< double > *dmR, const UnitCell *ucell, const Grid_Driver *gridD, const std::vector< double > &orb_cutoff, const Parallel_Orbitals *paraV, IntegralFunc &integral_calculator, ModuleBase::matrix &force, ModuleBase::matrix &stress)
Template function for calculating force and stress from 2-center integrals.
Definition operator_force_stress_utils.hpp:38
void finalize_force_stress(bool cal_force, bool cal_stress, const UnitCell *ucell, const std::vector< double > &stress_tmp, ModuleBase::matrix &force, ModuleBase::matrix &stress, double force_factor, double stress_factor)
Finalize force and stress calculations with MPI reduction and post-processing.
Definition operator_force_stress_utils.cpp:6