11 const bool cal_stress,
22 const int npol = this->ucell->get_npol();
23 std::vector<double> stress_tmp(6, 0);
32 std::vector<double> stress_local(6, 0);
34 #pragma omp for schedule(dynamic)
35 for (
int iat0 = 0; iat0 < this->ucell->nat; iat0++)
38 auto tau0 = ucell->get_tau(iat0);
41 ucell->iat2iait(iat0, &I0, &T0);
45 this->gridD->Find_atom(*ucell, tau0, T0, I0, &adjs);
47 std::vector<bool> is_adj(adjs.
adj_num + 1,
false);
48 for (
int ad = 0; ad < adjs.
adj_num + 1; ++ad)
50 const int T1 = adjs.
ntype[ad];
51 const int I1 = adjs.
natom[ad];
52 const int iat1 = ucell->itia2iat(T1, I1);
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())
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)
69 const int T1 = adjs.
ntype[ad];
70 const int I1 = adjs.
natom[ad];
71 const int iat1 = ucell->itia2iat(T1, I1);
73 const Atom* atom1 = &ucell->atoms[T1];
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)
83 const int iw1 = all_indexes[iw1l] / npol;
84 std::vector<std::vector<double>> nlm;
89 int L1 = atom1->
iw2l[iw1];
90 int N1 = atom1->
iw2n[iw1];
91 int m1 = atom1->
iw2m[iw1];
94 int M1 = (m1 % 2 == 0) ? -m1 / 2 : (m1 + 1) / 2;
97 intor_->snap(T1, L1, N1, M1, T0, dtau * this->ucell->lat0,
true , nlm);
99 const int length = nlm[0].size();
100 std::vector<double> nlm_target(length * 4);
102 for(
int index =0;index < length; index++)
104 for (
int n = 0; n < 4; n++)
106 nlm_target[index + n * length] = nlm[n][index];
109 nlm_iat0[ad].insert({all_indexes[iw1l], nlm_target});
114 for (
int ad1 = 0; ad1 < adjs.
adj_num + 1; ++ad1)
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;
123 for (
int ad2 = 0; ad2 < adjs.
adj_num + 1; ++ad2)
125 const int T2 = adjs.
ntype[ad2];
126 const int I2 = adjs.
natom[ad2];
127 const int iat2 = ucell->itia2iat(T2, I2);
131 R_index2[1] - R_index1[1],
132 R_index2[2] - R_index1[2]);
136 if(row_size == 0 || col_size == 0)
145 this->cal_force_IJR(iat1,
158 this->cal_stress_IJR(iat1,
167 stress_local.data());
177 force += force_local;
181 for(
int i = 0; i < 6; i++)
183 stress_tmp[i] += stress_local[i];
196 for (
int i = 0; i < force.nr * force.nc; i++)
209 const double weight = this->ucell->lat0 / this->ucell->omega;
210 for (
int i = 0; i < 6; i++)
212 stress.
c[i] = stress_tmp[i] * weight;
214 stress.
c[8] = stress.
c[5];
215 stress.
c[7] = stress.
c[4];
216 stress.
c[6] = stress.
c[2];
217 stress.
c[5] = stress.
c[4];
218 stress.
c[4] = stress.
c[3];
219 stress.
c[3] = stress.
c[1];
230 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
231 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
239 const int npol = this->ucell->get_npol();
246 std::vector<int> step_trace(npol * npol, 0);
249 step_trace[2] = col_indexes.size();
250 step_trace[3] = col_indexes.size() + 1;
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)
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)
261 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
263 assert(nlm1.size() == nlm2.size());
266 for (
int is = 0; is < 4; ++is)
268 for (
int no = 0;
no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[is];
no++)
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);
279 for(
int i = 0; i < 3; i++)
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();
290 dm_pointer += (npol - 1) * col_indexes.size();
299 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
300 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
309 const int npol = this->ucell->get_npol();
310 const int npol2 = npol * npol;
317 std::vector<int> step_trace(npol2, 0);
320 step_trace[2] = col_indexes.size();
321 step_trace[3] = col_indexes.size() + 1;
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)
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)
332 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
334 assert(nlm1.size() == nlm2.size());
337 for (
int is = 0; is < 4; ++is)
339 for (
int no = 0;
no < this->ucell->atoms[T0].ncpp.non_zero_count_soc[is];
no++)
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);
353 for(
int i = 0; i < 6; i++)
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();
362 dm_pointer += (npol - 1) * col_indexes.size();
371 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
372 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
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++)
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++)
391 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
393 assert(nlm1.size() == nlm2.size());
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++)
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);
406 for(
int i = 0; i < 3; i++)
408 force1[i] += dm_pointer[0] * nlm_tmp[i];
409 force2[i] -= dm_pointer[0] * nlm_tmp[i];
421 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
422 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
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++)
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++)
442 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
444 assert(nlm1.size() == nlm2.size());
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++)
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);
460 for(
int i = 0; i < 6; i++)
462 stress[i] += dm_pointer[0] * nlm_tmp[i];
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