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