ABACUS develop
Atomic-orbital Based Ab-initio Computation at UStc
Loading...
Searching...
No Matches
nonlocal_force_stress.hpp
Go to the documentation of this file.
1#pragma once
2#include "nonlocal.h"
5#include "source_base/timer.h"
6
7namespace hamilt
8{
9
10template <typename TK, typename TR>
11void Nonlocal<OperatorLCAO<TK, TR>>::cal_force_stress(const bool cal_force,
12 const bool cal_stress,
13 const HContainer<TR>* dmR,
14 ModuleBase::matrix& force,
15 ModuleBase::matrix& stress)
16{
17 ModuleBase::TITLE("Nonlocal", "cal_force_stress");
18
19 // begin the calculation of force and stress
20 ModuleBase::timer::start("Nonlocal", "cal_force_stress");
21
22 const Parallel_Orbitals* paraV = dmR->get_paraV();
23 const int npol = this->ucell->get_npol();
24 std::vector<double> stress_tmp(6, 0);
25 if (cal_force)
26 {
27 force.zero_out();
28 }
29 // 1. calculate <psi|beta> for each pair of atoms
30 // loop over all on-site atoms
31 #pragma omp parallel
32 {
33 std::vector<double> stress_local(6, 0);
34 ModuleBase::matrix force_local(force.nr, force.nc);
35 #pragma omp for schedule(dynamic)
36 for (int iat0 = 0; iat0 < this->ucell->nat; iat0++)
37 {
38 // skip the atoms without plus-U
39 auto tau0 = ucell->get_tau(iat0);
40 int I0 = 0;
41 int T0 = 0;
42 ucell->iat2iait(iat0, &I0, &T0);
43
44 // first step: find the adjacent atoms and filter the real adjacent atoms
46 this->gridD->Find_atom(*ucell, tau0, T0, I0, &adjs);
47
48 std::vector<bool> is_adj(adjs.adj_num + 1, false);
49 for (int ad = 0; ad < adjs.adj_num + 1; ++ad)
50 {
51 const int T1 = adjs.ntype[ad];
52 const int I1 = adjs.natom[ad];
53 const int iat1 = ucell->itia2iat(T1, I1);
54 const ModuleBase::Vector3<int>& R_index1 = adjs.box[ad];
55 // choose the real adjacent atoms
56 // Note: the distance of atoms should less than the cutoff radius,
57 // When equal, the theoretical value of matrix element is zero,
58 // but the calculated value is not zero due to the numerical error, which would lead to result changes.
59 if (this->ucell->cal_dtau(iat0, iat1, R_index1).norm() * this->ucell->lat0
60 < orb_cutoff_[T1] + this->ucell->infoNL.Beta[T0].get_rcut_max())
61 {
62 is_adj[ad] = true;
63 }
64 }
65 filter_adjs(is_adj, adjs);
66
67 std::vector<std::unordered_map<int, std::vector<double>>> nlm_iat0(adjs.adj_num + 1);
68 for (int ad = 0; ad < adjs.adj_num + 1; ++ad)
69 {
70 const int T1 = adjs.ntype[ad];
71 const int I1 = adjs.natom[ad];
72 const int iat1 = ucell->itia2iat(T1, I1);
73 const ModuleBase::Vector3<double>& tau1 = adjs.adjacent_tau[ad];
74 const Atom* atom1 = &ucell->atoms[T1];
75
76 auto all_indexes = paraV->get_indexes_row(iat1);
77 auto col_indexes = paraV->get_indexes_col(iat1);
78 // insert col_indexes into all_indexes to get universal set with no repeat elements
79 all_indexes.insert(all_indexes.end(), col_indexes.begin(), col_indexes.end());
80 std::sort(all_indexes.begin(), all_indexes.end());
81 all_indexes.erase(std::unique(all_indexes.begin(), all_indexes.end()), all_indexes.end());
82 for (int iw1l = 0; iw1l < all_indexes.size(); iw1l += npol)
83 {
84 const int iw1 = all_indexes[iw1l] / npol;
85 std::vector<std::vector<double>> nlm;
86 // nlm is a vector of vectors, but size of outer vector is only 1 here
87 // If we are calculating force, we need also to store the gradient
88 // and size of outer vector is then 4
89 // inner loop : all projectors (L0,M0)
90 auto qn1 = OperatorForceStress::get_orbital_qn(*atom1, iw1);
91
92 ModuleBase::Vector3<double> dtau = tau0 - tau1;
93 intor_->snap(T1, qn1.L, qn1.N, qn1.M, T0, dtau * this->ucell->lat0, true /*cal_deri*/, nlm);
94 // select the elements of nlm with target_L
95 const int length = nlm[0].size();
96 std::vector<double> nlm_target(length * 4);
97 // rearrange the nlm_target to store the gradient
98 for(int index =0;index < length; index++)
99 {
100 for (int n = 0; n < 4; n++) // value, deri_x, deri_y, deri_z
101 {
102 nlm_target[index + n * length] = nlm[n][index];
103 }
104 }
105 nlm_iat0[ad].insert({all_indexes[iw1l], nlm_target});
106 }
107 }
108
109 // second iteration to calculate force and stress
110 for (int ad1 = 0; ad1 < adjs.adj_num + 1; ++ad1)
111 {
112 const int T1 = adjs.ntype[ad1];
113 const int I1 = adjs.natom[ad1];
114 const int iat1 = ucell->itia2iat(T1, I1);
115 double* force_tmp1 = (cal_force) ? &force_local(iat1, 0) : nullptr;
116 double* force_tmp2 = (cal_force) ? &force_local(iat0, 0) : nullptr;
117 ModuleBase::Vector3<int>& R_index1 = adjs.box[ad1];
118 ModuleBase::Vector3<double> dis1 = adjs.adjacent_tau[ad1] - tau0;
119 for (int ad2 = 0; ad2 < adjs.adj_num + 1; ++ad2)
120 {
121 const int T2 = adjs.ntype[ad2];
122 const int I2 = adjs.natom[ad2];
123 const int iat2 = ucell->itia2iat(T2, I2);
124 ModuleBase::Vector3<int>& R_index2 = adjs.box[ad2];
125 ModuleBase::Vector3<double> dis2 = adjs.adjacent_tau[ad2] - tau0;
126 ModuleBase::Vector3<int> R_vector(R_index2[0] - R_index1[0],
127 R_index2[1] - R_index1[1],
128 R_index2[2] - R_index1[2]);
129 const hamilt::BaseMatrix<TR>* tmp = dmR->find_matrix(iat1, iat2, R_vector[0], R_vector[1], R_vector[2]);
130 int row_size = paraV->get_row_size();
131 int col_size = paraV->get_col_size();
132 if(row_size == 0 || col_size == 0)
133 {
134 continue;
135 }
136 // if not found , skip this pair of atoms
137 if (tmp != nullptr)
138 {
139 // calculate force
140 if (cal_force) {
141 this->cal_force_IJR(iat1,
142 iat2,
143 T0,
144 paraV,
145 nlm_iat0[ad1],
146 nlm_iat0[ad2],
147 tmp,
148 force_tmp1,
149 force_tmp2);
150 }
151
152 // calculate stress
153 if (cal_stress) {
154 this->cal_stress_IJR(iat1,
155 iat2,
156 T0,
157 paraV,
158 nlm_iat0[ad1],
159 nlm_iat0[ad2],
160 tmp,
161 dis1,
162 dis2,
163 stress_local.data());
164 }
165 }
166 }
167 }
168 }
169 #pragma omp critical
170 {
171 if(cal_force)
172 {
173 force += force_local;
174 }
175 if(cal_stress)
176 {
177 for(int i = 0; i < 6; i++)
178 {
179 stress_tmp[i] += stress_local[i];
180 }
181 }
182
183 }
184 }
185
186 if (cal_force)
187 {
188#ifdef __MPI
189 // sum up the occupation matrix
190 Parallel_Reduce::reduce_all(force.c, force.nr * force.nc);
191#endif
192 for (int i = 0; i < force.nr * force.nc; i++)
193 {
194 force.c[i] *= 2.0;
195 }
196 }
197
198 // stress renormalization
199 if (cal_stress)
200 {
201#ifdef __MPI
202 // sum up the occupation matrix
203 Parallel_Reduce::reduce_all(stress_tmp.data(), 6);
204#endif
205 const double weight = this->ucell->lat0 / this->ucell->omega;
206 for (int i = 0; i < 6; i++)
207 {
208 stress.c[i] = stress_tmp[i] * weight;
209 }
210 stress.c[8] = stress.c[5]; // stress(2,2)
211 stress.c[7] = stress.c[4]; // stress(2,1)
212 stress.c[6] = stress.c[2]; // stress(2,0)
213 stress.c[5] = stress.c[4]; // stress(1,2)
214 stress.c[4] = stress.c[3]; // stress(1,1)
215 stress.c[3] = stress.c[1]; // stress(1,0)
216 }
217
218 ModuleBase::timer::end("Nonlocal", "cal_force_stress");
219}
220
221template <>
222void Nonlocal<OperatorLCAO<std::complex<double>, std::complex<double>>>::cal_force_IJR(const int& iat1,
223 const int& iat2,
224 const int& T0,
225 const Parallel_Orbitals* paraV,
226 const std::unordered_map<int, std::vector<double>>& nlm1_all,
227 const std::unordered_map<int, std::vector<double>>& nlm2_all,
228 const hamilt::BaseMatrix<std::complex<double>>* dmR_pointer,
229 double* force1,
230 double* force2)
231{
232 // npol is the number of polarizations,
233 // 1 for non-magnetic (one Hamiltonian matrix only has spin-up or spin-down),
234 // 2 for magnetic (one Hamiltonian matrix has both spin-up and spin-down)
235 const int npol = this->ucell->get_npol();
236 // ---------------------------------------------
237 // calculate the Nonlocal matrix for each pair of orbitals
238 // ---------------------------------------------
239 auto row_indexes = paraV->get_indexes_row(iat1);
240 auto col_indexes = paraV->get_indexes_col(iat2);
241 // step_trace = 0 for NSPIN=2; ={0, 1, local_col, local_col+1} for NSPIN=4
242 std::vector<int> step_trace;
243 OperatorForceStress::setup_step_trace(npol, col_indexes.size(), step_trace);
244 // calculate the local matrix
245 const std::complex<double>* tmp_d = nullptr;
246 const std::complex<double>* dm_pointer = dmR_pointer->get_pointer();
247 for (int iw1l = 0; iw1l < row_indexes.size(); iw1l += npol)
248 {
249 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
250 const int length = nlm1.size() / 4;
251 for (int iw2l = 0; iw2l < col_indexes.size(); iw2l += npol)
252 {
253 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
254#ifdef __DEBUG
255 assert(nlm1.size() == nlm2.size());
256#endif
257 std::vector<std::complex<double>> nlm_tmp(12, ModuleBase::ZERO);
258 for (int is = 0; is < 4; ++is)
259 {
260 for (int no = 0; no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[is]; no++)
261 {
262 const int p1 = this->ucell->atoms[T0].ncpp.index1_soc[is][no];
263 const int p2 = this->ucell->atoms[T0].ncpp.index2_soc[is][no];
264 this->ucell->atoms[T0].ncpp.get_d(is, p1, p2, tmp_d);
265 nlm_tmp[is*3] += nlm1[p1 + length] * nlm2[p2] * (*tmp_d);
266 nlm_tmp[is*3+1] += nlm1[p1 + length * 2] * nlm2[p2] * (*tmp_d);
267 nlm_tmp[is*3+2] += nlm1[p1 + length * 3] * nlm2[p2] * (*tmp_d);
268 }
269 }
270 // calculate the force, transfer nlm_tmp to pauli matrix
271 for(int i = 0; i < 3; i++)
272 {
273 double tmp = (dm_pointer[step_trace[0]] * nlm_tmp[i]
274 + dm_pointer[step_trace[1]] * nlm_tmp[i+3]
275 + dm_pointer[step_trace[2]] * nlm_tmp[i+6]
276 + dm_pointer[step_trace[3]] * nlm_tmp[i+9]).real();
277 force1[i] += tmp;
278 force2[i] -= tmp;
279 }
280 dm_pointer += npol;
281 }
282 dm_pointer += (npol - 1) * col_indexes.size();
283 }
284}
285
286template <>
287void Nonlocal<OperatorLCAO<std::complex<double>, std::complex<double>>>::cal_stress_IJR(const int& iat1,
288 const int& iat2,
289 const int& T0,
290 const Parallel_Orbitals* paraV,
291 const std::unordered_map<int, std::vector<double>>& nlm1_all,
292 const std::unordered_map<int, std::vector<double>>& nlm2_all,
293 const hamilt::BaseMatrix<std::complex<double>>* dmR_pointer,
294 const ModuleBase::Vector3<double>& dis1,
295 const ModuleBase::Vector3<double>& dis2,
296 double* stress)
297{
298 // npol is the number of polarizations,
299 // 1 for non-magnetic (one Hamiltonian matrix only has spin-up or spin-down),
300 // 2 for magnetic (one Hamiltonian matrix has both spin-up and spin-down)
301 const int npol = this->ucell->get_npol();
302 const int npol2 = npol * npol;
303 // ---------------------------------------------
304 // calculate the Nonlocal matrix for each pair of orbitals
305 // ---------------------------------------------
306 auto row_indexes = paraV->get_indexes_row(iat1);
307 auto col_indexes = paraV->get_indexes_col(iat2);
308 // step_trace = 0 for NSPIN=2; ={0, 1, local_col, local_col+1} for NSPIN=4
309 std::vector<int> step_trace;
310 OperatorForceStress::setup_step_trace(npol, col_indexes.size(), step_trace);
311 // calculate the local matrix
312 const std::complex<double>* tmp_d = nullptr;
313 const std::complex<double>* dm_pointer = dmR_pointer->get_pointer();
314 for (int iw1l = 0; iw1l < row_indexes.size(); iw1l += npol)
315 {
316 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
317 const int length = nlm1.size() / npol2;
318 for (int iw2l = 0; iw2l < col_indexes.size(); iw2l += npol)
319 {
320 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
321#ifdef __DEBUG
322 assert(nlm1.size() == nlm2.size());
323#endif
324 std::vector<std::complex<double>> nlm_tmp(npol2 * 6, ModuleBase::ZERO);
325 for (int is = 0; is < 4; ++is)
326 {
327 for (int no = 0; no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[is]; no++)
328 {
329 const int p1 = this->ucell->atoms[T0].ncpp.index1_soc[is][no];
330 const int p2 = this->ucell->atoms[T0].ncpp.index2_soc[is][no];
331 this->ucell->atoms[T0].ncpp.get_d(is, p1, p2, tmp_d);
332 nlm_tmp[is*6] += (nlm1[p1 + length] * dis1.x * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.x) * (*tmp_d);
333 nlm_tmp[is*6+1] += (nlm1[p1 + length] * dis1.y * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.y) * (*tmp_d);
334 nlm_tmp[is*6+2] += (nlm1[p1 + length] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.z) * (*tmp_d);
335 nlm_tmp[is*6+3] += (nlm1[p1 + length * 2] * dis1.y * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 2] * dis2.y) * (*tmp_d);
336 nlm_tmp[is*6+4] += (nlm1[p1 + length * 2] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 2] * dis2.z) * (*tmp_d);
337 nlm_tmp[is*6+5] += (nlm1[p1 + length * 3] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 3] * dis2.z) * (*tmp_d);
338 }
339 }
340 // calculate the force, transfer nlm_tmp to pauli matrix
341 for(int i = 0; i < 6; i++)
342 {
343 stress[i] += (dm_pointer[step_trace[0]] * nlm_tmp[i]
344 + dm_pointer[step_trace[1]] * nlm_tmp[i+6]
345 + dm_pointer[step_trace[2]] * nlm_tmp[i+12]
346 + dm_pointer[step_trace[3]] * nlm_tmp[i+18]).real();
347 }
348 dm_pointer += npol;
349 }
350 dm_pointer += (npol - 1) * col_indexes.size();
351 }
352}
353
354template <typename TK, typename TR>
355void Nonlocal<OperatorLCAO<TK, TR>>::cal_force_IJR(const int& iat1,
356 const int& iat2,
357 const int& T0,
358 const Parallel_Orbitals* paraV,
359 const std::unordered_map<int, std::vector<double>>& nlm1_all,
360 const std::unordered_map<int, std::vector<double>>& nlm2_all,
361 const hamilt::BaseMatrix<TR>* dmR_pointer,
362 double* force1,
363 double* force2)
364{
365 // ---------------------------------------------
366 // calculate the Nonlocal matrix for each pair of orbitals
367 // ---------------------------------------------
368 auto row_indexes = paraV->get_indexes_row(iat1);
369 auto col_indexes = paraV->get_indexes_col(iat2);
370 // calculate the local matrix
371 const double* tmp_d = nullptr;
372 const double* dm_pointer = dmR_pointer->get_pointer();
373 for (int iw1l = 0; iw1l < row_indexes.size(); iw1l++)
374 {
375 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
376 const int length = nlm1.size() / 4;
377 for (int iw2l = 0; iw2l < col_indexes.size(); iw2l++)
378 {
379 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
380#ifdef __DEBUG
381 assert(nlm1.size() == nlm2.size());
382#endif
383 std::vector<double> nlm_tmp(3, 0.0);
384 for (int no = 0; no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[0]; no++)
385 {
386 const int p1 = this->ucell->atoms[T0].ncpp.index1_soc[0][no];
387 const int p2 = this->ucell->atoms[T0].ncpp.index2_soc[0][no];
388 this->ucell->atoms[T0].ncpp.get_d(0, p1, p2, tmp_d);
389 nlm_tmp[0] += nlm1[p1 + length] * nlm2[p2] * (*tmp_d);
390 nlm_tmp[1] += nlm1[p1 + length * 2] * nlm2[p2] * (*tmp_d);
391 nlm_tmp[2] += nlm1[p1 + length * 3] * nlm2[p2] * (*tmp_d);
392 }
393 // calculate the force, transfer nlm_tmp to pauli matrix
394 for(int i = 0; i < 3; i++)
395 {
396 force1[i] += dm_pointer[0] * nlm_tmp[i];
397 force2[i] -= dm_pointer[0] * nlm_tmp[i];
398 }
399 dm_pointer++;
400 }
401 }
402}
403
404template <typename TK, typename TR>
405void Nonlocal<OperatorLCAO<TK, TR>>::cal_stress_IJR(const int& iat1,
406 const int& iat2,
407 const int& T0,
408 const Parallel_Orbitals* paraV,
409 const std::unordered_map<int, std::vector<double>>& nlm1_all,
410 const std::unordered_map<int, std::vector<double>>& nlm2_all,
411 const hamilt::BaseMatrix<TR>* dmR_pointer,
412 const ModuleBase::Vector3<double>& dis1,
413 const ModuleBase::Vector3<double>& dis2,
414 double* stress)
415{
416 // ---------------------------------------------
417 // calculate the Nonlocal matrix for each pair of orbitals
418 // ---------------------------------------------
419 auto row_indexes = paraV->get_indexes_row(iat1);
420 auto col_indexes = paraV->get_indexes_col(iat2);
421 // calculate the local matrix
422 const double* tmp_d = nullptr;
423 const double* dm_pointer = dmR_pointer->get_pointer();
424 for (int iw1l = 0; iw1l < row_indexes.size(); iw1l++)
425 {
426 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
427 const int length = nlm1.size() / 4;
428 for (int iw2l = 0; iw2l < col_indexes.size(); iw2l++)
429 {
430 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
431#ifdef __DEBUG
432 assert(nlm1.size() == nlm2.size());
433#endif
434 std::vector<double> nlm_tmp(6, 0.0);
435 for (int no = 0; no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[0]; no++)
436 {
437 const int p1 = this->ucell->atoms[T0].ncpp.index1_soc[0][no];
438 const int p2 = this->ucell->atoms[T0].ncpp.index2_soc[0][no];
439 this->ucell->atoms[T0].ncpp.get_d(0, p1, p2, tmp_d);
440 nlm_tmp[0] += (nlm1[p1 + length] * dis1.x * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.x) * (*tmp_d);
441 nlm_tmp[1] += (nlm1[p1 + length] * dis1.y * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.y) * (*tmp_d);
442 nlm_tmp[2] += (nlm1[p1 + length] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length] * dis2.z) * (*tmp_d);
443 nlm_tmp[3] += (nlm1[p1 + length * 2] * dis1.y * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 2] * dis2.y) * (*tmp_d);
444 nlm_tmp[4] += (nlm1[p1 + length * 2] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 2] * dis2.z) * (*tmp_d);
445 nlm_tmp[5] += (nlm1[p1 + length * 3] * dis1.z * nlm2[p2] + nlm1[p1] * nlm2[p2 + length * 3] * dis2.z) * (*tmp_d);
446 }
447 // calculate the force, transfer nlm_tmp to pauli matrix
448 for(int i = 0; i < 6; i++)
449 {
450 stress[i] += dm_pointer[0] * nlm_tmp[i];
451 }
452 dm_pointer++;
453 }
454 }
455}
456
457} // namespace hamilt
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< double > > adjacent_tau
Definition sltk_grid_driver.h:25
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
Definition atom_spec.h:6
3 elements vector
Definition vector3.h:24
T x
Definition vector3.h:26
T y
Definition vector3.h:27
T z
Definition vector3.h:28
Definition matrix.h:18
void zero_out(void)
Definition matrix.cpp:296
int nr
Definition matrix.h:22
double * c
Definition matrix.h:24
int nc
Definition matrix.h:23
static void start(void)
Start total time calculation.
Definition timer.cpp:44
static void end(const std::string &class_name_in, const std::string &name_in)
Definition timer.cpp:109
Definition parallel_orbitals.h:9
std::vector< int > get_indexes_col() const
Definition parallel_orbitals.cpp:154
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
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
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
const Parallel_Orbitals * get_paraV() const
get parallel orbital pointer to check parallel information
Definition hcontainer.h:192
Definition nonlocal.h:26
const std::complex< double > ZERO(0.0, 0.0)
void TITLE(const std::string &class_name, const std::string &function_name, const bool disable)
Definition tool_title.cpp:18
void setup_step_trace(int npol, int col_size, std::vector< int > &step_trace)
Setup step_trace array for handling npol (spin polarization)
Definition operator_force_stress_utils.h:20
OrbitalQuantumNumbers get_orbital_qn(const Atom &atom, int iw)
Extract orbital quantum numbers from atom and orbital index.
Definition operator_force_stress_utils.h:49
void reduce_all(T &object)
reduce in all process
Definition depend_mock.cpp:14
Definition hamilt.h:13
void filter_adjs(const std::vector< bool > &is_adj, AdjacentAtomInfo &adjs)
Definition sltk_grid_driver.cpp:67