ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
pulay_force_stress_center2_template.hpp
Go to the documentation of this file.
1#pragma once
3#include "source_base/timer.h"
5namespace PulayForceStress
6{
7 // common kernel
8 template <typename TK, typename TR, typename Tfunc>
9 inline void cal_pulay_fs(
13 const UnitCell& ucell,
14 const Parallel_Orbitals& pv,
15 const double** dHSx,
16 const double** dHSxy,
17 const double* dtau,
18 const bool& isforce,
19 const bool& isstress,
20 Record_adj* ra,
21 const double& factor_force,
22 const double& factor_stress,
23 Tfunc& stress_func)
24 {
25 ModuleBase::TITLE("Force_LCAO", "cal_pulay_fs_center2");
26 ModuleBase::timer::tick("Force_LCAO", "cal_pulay_fs_center2");
27
28 const int nspin_DMR = (PARAM.inp.nspin == 2) ? 2 : 1;
29 int total_irr = 0;
30#ifdef _OPENMP
31#pragma omp parallel
32 {
33 int num_threads = omp_get_num_threads();
34 ModuleBase::matrix local_s(3, 3);
35 int local_total_irr = 0;
36#else
37 ModuleBase::matrix& local_s = s;
38 int& local_total_irr = total_irr;
39#endif
40
41#ifdef _OPENMP
42#pragma omp for schedule(dynamic)
43#endif
44 for (int iat = 0; iat < ucell.nat; iat++)
45 {
46 const int T1 = ucell.iat2it[iat];
47 Atom* atom1 = &ucell.atoms[T1];
48 const int I1 = ucell.iat2ia[iat];
49 // get iat1
50 int iat1 = ucell.itia2iat(T1, I1);
51 double* f_iat;
52 if (isforce) { f_iat = &f(iat, 0); }
53#ifdef _OPENMP
54 // using local stack to avoid false sharing in multi-threaded case
55 double f_tmp[3] = { 0.0, 0.0, 0.0 };
56 if (num_threads > 1) { f_iat = f_tmp; }
57#endif
58 int irr = pv.nlocstart[iat];
59 const int start1 = ucell.itiaiw2iwt(T1, I1, 0);
60 for (int cb = 0; cb < ra->na_each[iat]; ++cb)
61 {
62 const int T2 = ra->info[iat][cb][3];
63 const int I2 = ra->info[iat][cb][4];
64 const int start2 = ucell.itiaiw2iwt(T2, I2, 0);
65 Atom* atom2 = &ucell.atoms[T2];
66 // get iat2
67 int iat2 = ucell.itia2iat(T2, I2);
68 double Rx = ra->info[iat][cb][0];
69 double Ry = ra->info[iat][cb][1];
70 double Rz = ra->info[iat][cb][2];
71 // get BaseMatrix
72 if (pv.get_row_size(iat1) <= 0 || pv.get_col_size(iat2) <= 0) { continue; }
73 std::vector<hamilt::BaseMatrix<double>*> tmp_matrix;
74 for (int is = 0; is < nspin_DMR; ++is)
75 {
76 tmp_matrix.push_back(dm.get_DMR_pointer(is + 1)->find_matrix(iat1, iat2, Rx, Ry, Rz));
77 }
78 for (int mu = 0; mu < pv.get_row_size(iat1); ++mu)
79 {
80 for (int nu = 0; nu < pv.get_col_size(iat2); ++nu)
81 {
82 // the DMR should not be summed over spin, do the summation here
83 double dm2d1 = 0.0;
84 for (int is = 0; is < nspin_DMR; ++is) { dm2d1 += tmp_matrix[is]->get_value(mu, nu); }
85 double dm2d2 = 2.0 * dm2d1;
86 if (isforce)
87 {
88 const double dm2d2_f = dm2d2 * factor_force;
89 for (int i = 0; i < 3; ++i) { f_iat[i] += dm2d2_f * dHSx[i][irr]; }
90 }
91 if (isstress)
92 {
93 const double dm2d1_s = dm2d1 * factor_stress;
94 stress_func(local_s, dm2d1_s, dHSx, dHSxy, dtau, irr);
95 }
96 ++local_total_irr;
97 ++irr;
98 }
99 }
100 }
101#ifdef _OPENMP
102 if (isforce && num_threads > 1) { for (int i = 0; i < 3; ++i) { f(iat, i) += f_iat[i]; } }
103#endif
104 } // end iat
105#ifdef _OPENMP
106#pragma omp critical(cal_foverlap_k_reduce)
107 {
108 total_irr += local_total_irr;
109 if (isstress)
110 {
111 for (int i = 0; i < 3; ++i) { for (int j = i; j < 3; ++j) { s(i, j) += local_s(i, j); } }
112 }
113 }
114 }
115#endif
116
117 if (total_irr != pv.nnr)
118 {
119 ModuleBase::GlobalFunc::OUT(GlobalV::ofs_running, "wrong irr", total_irr);
121 ModuleBase::WARNING_QUIT("Force_LCAO::cal_pulay_fs_center2", "irr!=pv.nnr");
122 }
123
124 if (isstress) { StressTools::stress_fill(ucell.lat0, ucell.omega, s); }
125
126 ModuleBase::timer::tick("Force_LCAO", "cal_pulay_fs_center2");
127 }
128}
Definition atom_spec.h:7
Definition matrix.h:19
static void tick(const std::string &class_name_in, const std::string &name_in)
Use twice at a time: the first time, set start_flag to false; the second time, calculate the time dur...
Definition timer.cpp:57
Definition parallel_orbitals.h:9
int get_col_size() const
dimension getters for 2D-block-cyclic division of Hamiltonian matrix get_col_size() : total number of...
Definition parallel_orbitals.h:76
int get_row_size() const
Definition parallel_orbitals.h:77
int * nlocstart
Definition parallel_orbitals.h:34
int nnr
Definition parallel_orbitals.h:32
const Input_para & inp
Definition parameter.h:26
Definition record_adj.h:11
int *** info
Definition record_adj.h:61
int * na_each
Definition record_adj.h:41
Definition unitcell.h:16
int *& iat2it
Definition unitcell.h:47
Tiait itiaiw2iwt(const Tiait &it, const Tiait &ia, const Tiait &iw) const
Definition unitcell.h:68
Atom * atoms
Definition unitcell.h:18
double & lat0
Definition unitcell.h:28
ModuleBase::IntArray & itia2iat
Definition unitcell.h:51
int & nat
Definition unitcell.h:46
double & omega
Definition unitcell.h:32
int *& iat2ia
Definition unitcell.h:48
Definition density_matrix.h:36
hamilt::HContainer< TR > * get_DMR_pointer(const int ispin) const
get pointer of DMR
Definition density_matrix_io.cpp:186
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:261
std::ofstream ofs_running
Definition global_variable.cpp:38
void OUT(std::ofstream &ofs, const std::string &name)
Definition global_function.cpp:51
void WARNING_QUIT(const std::string &, const std::string &)
Combine the functions of WARNING and QUIT.
Definition test_delley.cpp:14
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
Definition pulay_force_stress.h:22
void cal_pulay_fs(ModuleBase::matrix &f, ModuleBase::matrix &s, const elecstate::DensityMatrix< TK, TR > &dm, const UnitCell &ucell, const Parallel_Orbitals &pv, const double *(&dHSx)[3], const double *(&dHSxy)[6], const bool &isforce, const bool &isstress, Record_adj *ra=nullptr, const double &factor_force=1.0, const double &factor_stress=1.0)
for 2-center-integration terms, provided force and stress derivatives
void stress_fill(const double &lat0_, const double &omega_, ModuleBase::matrix &stress_matrix)
Definition stress_tools.cpp:4
Parameter PARAM
Definition parameter.cpp:3
int nspin
LDA ; LSDA ; non-linear spin.
Definition input_parameter.h:84