11 const bool cal_stress,
23 this->cal_constraint_atom_list(constrain);
27 const int npol = this->ucell->get_npol();
28 std::vector<double> stress_tmp(6, 0);
37 std::vector<double> stress_local(6, 0);
39 #pragma omp for schedule(dynamic)
40 for (
int iat0 = 0; iat0 < this->ucell->nat; iat0++)
42 if(!this->constraint_atom_list[iat0])
48 auto tau0 = ucell->get_tau(iat0);
50 ucell->iat2iait(iat0, &I0, &T0);
54 this->gridD->Find_atom(*ucell, tau0, T0, I0, &adjs);
56 std::vector<bool> is_adj(adjs.
adj_num + 1,
false);
57 for (
int ad = 0; ad < adjs.
adj_num + 1; ++ad)
59 const int T1 = adjs.
ntype[ad];
60 const int I1 = adjs.
natom[ad];
61 const int iat1 = ucell->itia2iat(T1, I1);
67 if (this->ucell->cal_dtau(iat0, iat1, R_index1).norm() * this->ucell->lat0
74 const int max_l_plus_1 = this->ucell->atoms[T0].nwl + 1;
75 const int length = max_l_plus_1 * max_l_plus_1;
76 std::vector<std::unordered_map<int, std::vector<double>>> nlm_iat0(adjs.
adj_num + 1);
78 for (
int ad = 0; ad < adjs.
adj_num + 1; ++ad)
80 const int T1 = adjs.
ntype[ad];
81 const int I1 = adjs.
natom[ad];
82 const int iat1 = ucell->itia2iat(T1, I1);
84 const Atom* atom1 = &ucell->atoms[T1];
89 all_indexes.insert(all_indexes.end(), col_indexes.begin(), col_indexes.end());
90 std::sort(all_indexes.begin(), all_indexes.end());
91 all_indexes.erase(std::unique(all_indexes.begin(), all_indexes.end()), all_indexes.end());
92 for (
int iw1l = 0; iw1l < all_indexes.size(); iw1l += npol)
94 const int iw1 = all_indexes[iw1l] / npol;
95 std::vector<std::vector<double>> nlm;
100 int L1 = atom1->
iw2l[iw1];
101 int N1 = atom1->
iw2n[iw1];
102 int m1 = atom1->
iw2m[iw1];
105 int M1 = (m1 % 2 == 0) ? -m1 / 2 : (m1 + 1) / 2;
108 intor_->snap(T1, L1, N1, M1, T0, dtau * this->ucell->lat0, 1 , nlm);
110 std::vector<double> nlm_target(length * 4);
112 int target_L = 0, index=0;
113 for(
int iw =0;iw < this->ucell->atoms[T0].nw; iw++)
115 const int L0 = this->ucell->atoms[T0].iw2l[iw];
119 for(
int m = 0; m < 2*L0+1; m++)
121 for (
int n = 0; n < 4; n++)
123 nlm_target[index + n * length] = nlm[n][iw + m];
130 nlm_iat0[ad].insert({all_indexes[iw1l], nlm_target});
135 for (
int ad1 = 0; ad1 < adjs.
adj_num + 1; ++ad1)
137 const int T1 = adjs.
ntype[ad1];
138 const int I1 = adjs.
natom[ad1];
139 const int iat1 = ucell->itia2iat(T1, I1);
140 double* force_tmp1 = (cal_force) ? &force_local(iat1, 0) :
nullptr;
141 double* force_tmp2 = (cal_force) ? &force_local(iat0, 0) :
nullptr;
144 for (
int ad2 = 0; ad2 < adjs.
adj_num + 1; ++ad2)
146 const int T2 = adjs.
ntype[ad2];
147 const int I2 = adjs.
natom[ad2];
148 const int iat2 = ucell->itia2iat(T2, I2);
152 R_index2[1] - R_index1[1],
153 R_index2[2] - R_index1[2]);
157 if(row_size == 0 || col_size == 0)
166 this->cal_force_IJR(iat1,
180 this->cal_stress_IJR(iat1,
190 stress_local.data());
200 force += force_local;
204 for(
int i = 0; i < 6; i++)
206 stress_tmp[i] += stress_local[i];
218 for (
int i = 0; i < force.nr * force.nc; i++)
231 const double weight = this->ucell->lat0 / this->ucell->omega;
232 for (
int i = 0; i < 6; i++)
234 stress.
c[i] = stress_tmp[i] * weight;
236 stress.
c[8] = stress.
c[5];
237 stress.
c[7] = stress.
c[4];
238 stress.
c[6] = stress.
c[2];
239 stress.
c[5] = stress.
c[4];
240 stress.
c[4] = stress.
c[3];
241 stress.
c[3] = stress.
c[1];
251 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
252 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
262 const int npol = this->ucell->get_npol();
269 std::vector<int> step_trace(nspin, 0);
272 step_trace[2] = col_indexes.size();
273 step_trace[3] = col_indexes.size() + 1;
277 for (
int is = 1; is < nspin; is++)
279 const double lambda_tmp = nspin==2?lambda[2]:lambda[is-1];
280 const double* dm_pointer = dmR_pointer->
get_pointer();
281 for (
int iw1l = 0; iw1l < row_indexes.size(); iw1l += npol)
283 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
284 for (
int iw2l = 0; iw2l < col_indexes.size(); iw2l += npol)
286 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
288 assert(nlm1.size() == nlm2.size());
290 const int length = nlm1.size() / 4;
291 const int lmax = sqrt(length);
293 for(
int l = 0; l<lmax; l++)
295 for (
int m = 0; m < 2*l+1; m++)
298 tmp[0] = lambda_tmp * nlm1[index + length] * nlm2[index] * dm_pointer[step_trace[is]];
299 tmp[1] = lambda_tmp * nlm1[index + length * 2] * nlm2[index] * dm_pointer[step_trace[is]];
300 tmp[2] = lambda_tmp * nlm1[index + length * 3] * nlm2[index] * dm_pointer[step_trace[is]];
313 dm_pointer += (npol - 1) * col_indexes.size();
322 const std::unordered_map<
int, std::vector<double>>& nlm1_all,
323 const std::unordered_map<
int, std::vector<double>>& nlm2_all,
334 const int npol = this->ucell->get_npol();
341 std::vector<int> step_trace(nspin, 0);
344 step_trace[2] = col_indexes.size();
345 step_trace[3] = col_indexes.size() + 1;
348 for (
int is = 1; is < nspin; is++)
350 const double lambda_tmp = nspin==2?lambda[2]:lambda[is-1];
351 const double* dm_pointer = dmR_pointer->
get_pointer();
352 for (
int iw1l = 0; iw1l < row_indexes.size(); iw1l += npol)
354 const std::vector<double>& nlm1 = nlm1_all.find(row_indexes[iw1l])->second;
355 for (
int iw2l = 0; iw2l < col_indexes.size(); iw2l += npol)
357 const std::vector<double>& nlm2 = nlm2_all.find(col_indexes[iw2l])->second;
359 assert(nlm1.size() == nlm2.size());
361 const int length = nlm1.size() / 4;
362 const int lmax = sqrt(length);
363 double tmp = lambda_tmp * dm_pointer[step_trace[is]];
365 for(
int l = 0; l<lmax; l++)
367 for (
int m = 0; m < 2*l+1; m++)
371 += tmp * (nlm1[index + length] * dis1.
x * nlm2[index] + nlm1[index] * nlm2[index + length] * dis2.
x);
373 += tmp * (nlm1[index + length] * dis1.
y * nlm2[index] + nlm1[index] * nlm2[index + length] * dis2.
y);
375 += tmp * (nlm1[index + length] * dis1.
z * nlm2[index] + nlm1[index] * nlm2[index + length] * dis2.
z);
377 * (nlm1[index + length * 2] * dis1.
y * nlm2[index]
378 + nlm1[index] * nlm2[index + length * 2] * dis2.
y);
380 * (nlm1[index + length * 2] * dis1.
z * nlm2[index]
381 + nlm1[index] * nlm2[index + length * 2] * dis2.
z);
383 * (nlm1[index + length * 3] * dis1.
z * nlm2[index]
384 + nlm1[index] * nlm2[index + length * 3] * dis2.
z);
389 dm_pointer += (npol - 1) * col_indexes.size();
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