Skip to content

Commit 8b7bab4

Browse files
authored
Merge pull request #1193 from ddhhss/develop
Fix: Add calculation for compensating charge energy and force.
2 parents f649b38 + 7dfa978 commit 8b7bab4

File tree

17 files changed

+983
-650
lines changed

17 files changed

+983
-650
lines changed

source/module_surchem/H_correction_pw.cpp

Lines changed: 137 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <cmath>
99

1010
ModuleBase::matrix surchem::v_correction(const UnitCell &cell,
11-
ModulePW::PW_Basis* rho_basis,
11+
ModulePW::PW_Basis *rho_basis,
1212
const int &nspin,
1313
const double *const *const rho)
1414
{
@@ -51,7 +51,14 @@ ModuleBase::matrix surchem::v_correction(const UnitCell &cell,
5151
return v;
5252
}
5353

54-
void surchem::add_comp_chg(const UnitCell &cell, ModulePW::PW_Basis* rho_basis, double q, double l, double center, complex<double> *NG, int dim)
54+
void surchem::add_comp_chg(const UnitCell &cell,
55+
ModulePW::PW_Basis *rho_basis,
56+
double q,
57+
double l,
58+
double center,
59+
complex<double> *NG,
60+
int dim,
61+
bool flag)
5562
{
5663
// x dim
5764
double tmp_q = 0.0;
@@ -62,18 +69,24 @@ void surchem::add_comp_chg(const UnitCell &cell, ModulePW::PW_Basis* rho_basis,
6269
ModuleBase::GlobalFunc::ZEROS(NG, rho_basis->npw);
6370
for (int ig = 0; ig < rho_basis->npw; ig++)
6471
{
65-
if(ig==rho_basis->ig_gge0)
72+
if (ig == rho_basis->ig_gge0)
73+
{
74+
if(flag)
75+
{
76+
NG[ig] = complex<double>(tmp_q * l / L, 0.0);
77+
}
6678
continue;
79+
}
6780
double GX = rho_basis->gcar[ig][0];
6881
double GY = rho_basis->gcar[ig][1];
6982
double GZ = rho_basis->gcar[ig][2];
7083
GX = GX * 2 * ModuleBase::PI;
7184
if (GY == 0 && GZ == 0 && GX != 0)
7285
{
73-
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GX * center) * complex<double>(2.0 * tmp_q * sin(GX * l / 2.0) / (L * GX), 0.0);
86+
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GX * center)
87+
* complex<double>(2.0 * tmp_q * sin(GX * l / 2.0) / (L * GX), 0.0);
7488
}
7589
}
76-
// NG[0] = complex<double>(tmp_q * l / L, 0.0);
7790
}
7891
// y dim
7992
else if (dim == 1)
@@ -83,71 +96,126 @@ void surchem::add_comp_chg(const UnitCell &cell, ModulePW::PW_Basis* rho_basis,
8396
ModuleBase::GlobalFunc::ZEROS(NG, rho_basis->npw);
8497
for (int ig = 0; ig < rho_basis->npw; ig++)
8598
{
86-
if(ig==rho_basis->ig_gge0)
99+
if (ig == rho_basis->ig_gge0)
100+
{
101+
if(flag)
102+
{
103+
NG[ig] = complex<double>(tmp_q * l / L, 0.0);
104+
}
87105
continue;
106+
}
88107
double GX = rho_basis->gcar[ig][0];
89108
double GY = rho_basis->gcar[ig][1];
90109
double GZ = rho_basis->gcar[ig][2];
91110
GY = GY * 2 * ModuleBase::PI;
92111
if (GX == 0 && GZ == 0 && GY != 0)
93112
{
94-
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GY * center) * complex<double>(2.0 * tmp_q * sin(GY * l / 2.0) / (L * GY), 0.0);
113+
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GY * center)
114+
* complex<double>(2.0 * tmp_q * sin(GY * l / 2.0) / (L * GY), 0.0);
95115
}
96116
}
97-
// NG[0] = complex<double>(tmp_q * l / L, 0.0);
98117
}
99118
// z dim
100119
else if (dim == 2)
101120
{
102121
double L = cell.a3[2];
103-
// cout << "area" << cross(cell.a1, cell.a2).norm() << endl;
104122
tmp_q = q / (cross(cell.a1, cell.a2).norm() * l);
105123
ModuleBase::GlobalFunc::ZEROS(NG, rho_basis->npw);
106124
for (int ig = 0; ig < rho_basis->npw; ig++)
107125
{
108-
if(ig==rho_basis->ig_gge0)
126+
if (ig == rho_basis->ig_gge0)
127+
{
128+
if(flag)
129+
{
130+
NG[ig] = complex<double>(tmp_q * l / L, 0.0);
131+
}
109132
continue;
133+
}
110134
double GX = rho_basis->gcar[ig][0];
111135
double GY = rho_basis->gcar[ig][1];
112136
double GZ = rho_basis->gcar[ig][2];
113137
GZ = GZ * 2 * ModuleBase::PI;
114138
if (GX == 0 && GY == 0 && GZ != 0)
115139
{
116-
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GZ * center) * complex<double>(2.0 * tmp_q * sin(GZ * l / 2.0) / (L * GZ), 0.0);
140+
NG[ig] = exp(ModuleBase::NEG_IMAG_UNIT * GZ * center)
141+
* complex<double>(2.0 * tmp_q * sin(GZ * l / 2.0) / (L * GZ), 0.0);
117142
}
118143
}
119-
// NG[0] = complex<double>(tmp_q * l / L, 0.0);
120144
}
121145
}
122146

123-
ModuleBase::matrix surchem::v_compensating(const UnitCell &cell, ModulePW::PW_Basis *rho_basis)
147+
ModuleBase::matrix surchem::v_compensating(const UnitCell &cell,
148+
ModulePW::PW_Basis *rho_basis,
149+
const int &nspin,
150+
const double *const *const rho)
124151
{
125152
ModuleBase::TITLE("surchem", "v_compensating");
126153
ModuleBase::timer::tick("surchem", "v_compensating");
127154

155+
// calculating v_comp also need TOTN_real
156+
double *Porter = new double[rho_basis->nrxx];
157+
for (int i = 0; i < rho_basis->nrxx; i++)
158+
Porter[i] = 0.0;
159+
const int nspin0 = (nspin == 2) ? 2 : 1;
160+
for (int is = 0; is < nspin0; is++)
161+
for (int ir = 0; ir < rho_basis->nrxx; ir++)
162+
Porter[ir] += rho[is][ir];
163+
164+
complex<double> *Porter_g = new complex<double>[rho_basis->npw];
165+
ModuleBase::GlobalFunc::ZEROS(Porter_g, rho_basis->npw);
166+
167+
rho_basis->real2recip(Porter, Porter_g);
168+
169+
this->Porter_g_anchor = Porter_g[rho_basis->ig_gge0];
170+
171+
complex<double> *N = new complex<double>[rho_basis->npw];
172+
complex<double> *TOTN = new complex<double>[rho_basis->npw];
173+
174+
cal_totn(cell, rho_basis, Porter_g, N, TOTN);
175+
176+
// save TOTN in real space
177+
rho_basis->recip2real(TOTN, this->TOTN_real);
178+
128179
complex<double> *comp_reci = new complex<double>[rho_basis->npw];
129180
complex<double> *phi_comp_G = new complex<double>[rho_basis->npw];
130-
double *phi_comp_R = new double[rho_basis->nrxx];
181+
// double *phi_comp_R = new double[rho_basis->nrxx];
131182

132183
ModuleBase::GlobalFunc::ZEROS(comp_reci, rho_basis->npw);
133184
ModuleBase::GlobalFunc::ZEROS(phi_comp_G, rho_basis->npw);
134185
ModuleBase::GlobalFunc::ZEROS(phi_comp_R, rho_basis->nrxx);
135-
// get comp chg in reci space
136-
add_comp_chg(cell, rho_basis, comp_q, comp_l, comp_center, comp_reci, comp_dim);
137-
double ecomp = 0.0;
186+
// get compensating charge in reci space
187+
add_comp_chg(cell, rho_basis, comp_q, comp_l, comp_center, comp_reci, comp_dim, true);
188+
// save compensating charge in real space
189+
rho_basis->recip2real(comp_reci, this->comp_real);
190+
191+
// test sum of comp_real -> 0
192+
// for (int i = 0; i < rho_basis->nz;i++)
193+
// {
194+
// cout << comp_real[i] << endl;
195+
// }
196+
// double sum = 0;
197+
// for (int i = 0; i < rho_basis->nxyz; i++)
198+
// {
199+
// sum += TOTN_real[i];
200+
// }
201+
// sum = sum * cell.omega / rho_basis->nxyz;
202+
// cout << "sum:" << sum << endl;
203+
// int pp;
204+
// cin >> pp;
205+
138206
for (int ig = 0; ig < rho_basis->npw; ig++)
139207
{
140-
if (rho_basis->gg[ig] >= 1.0e-12) // LiuXh 20180410
208+
if (ig == rho_basis->ig_gge0)
209+
{
210+
// cout << ig << endl;
211+
continue;
212+
}
213+
else
141214
{
142215
const double fac = ModuleBase::e2 * ModuleBase::FOUR_PI / (cell.tpiba2 * rho_basis->gg[ig]);
143-
ecomp += (conj(comp_reci[ig]) * comp_reci[ig]).real() * fac;
144216
phi_comp_G[ig] = fac * comp_reci[ig];
145217
}
146218
}
147-
Parallel_Reduce::reduce_double_pool(ecomp);
148-
ecomp *= 0.5 * cell.omega;
149-
// std::cout << " ecomp=" << ecomp << std::endl;
150-
comp_chg_energy = ecomp;
151219

152220
rho_basis->recip2real(phi_comp_G, phi_comp_R);
153221

@@ -166,95 +234,64 @@ ModuleBase::matrix surchem::v_compensating(const UnitCell &cell, ModulePW::PW_Ba
166234

167235
delete[] comp_reci;
168236
delete[] phi_comp_G;
169-
delete[] phi_comp_R;
237+
// delete[] phi_comp_R;
238+
delete[] Porter;
239+
delete[] Porter_g;
240+
delete[] N;
241+
delete[] TOTN;
170242

171243
ModuleBase::timer::tick("surchem", "v_compensating");
172244
return v_comp;
173245
}
174246

175-
void test_print(double* tmp, ModulePW::PW_Basis *rho_basis)
247+
void surchem::cal_comp_force(ModuleBase::matrix &force_comp, ModulePW::PW_Basis *rho_basis)
176248
{
177-
for (int i = 0; i < rho_basis->nz; i++)
178-
{
179-
cout << tmp[i] << endl;
180-
}
181-
}
182-
183-
void surchem::test_V_to_N(ModuleBase::matrix &v,
184-
const UnitCell &cell,
185-
ModulePW::PW_Basis *rho_basis,
186-
const double *const *const rho)
187-
{
188-
double *phi_comp_R = new double[rho_basis->nrxx];
189-
complex<double> *phi_comp_G = new complex<double>[rho_basis->npw];
190-
complex<double> *comp_reci = new complex<double>[rho_basis->npw];
191-
double *N_real = new double[rho_basis->nrxx];
192-
193-
ModuleBase::GlobalFunc::ZEROS(phi_comp_R, rho_basis->nrxx);
194-
ModuleBase::GlobalFunc::ZEROS(phi_comp_G, rho_basis->npw);
195-
ModuleBase::GlobalFunc::ZEROS(comp_reci, rho_basis->npw);
196-
ModuleBase::GlobalFunc::ZEROS(N_real, rho_basis->nrxx);
197-
198-
for (int ir = 0; ir < rho_basis->nz; ir++)
199-
{
200-
cout << v(0, ir) << endl;
201-
}
202-
203-
for (int ir = 0; ir < rho_basis->nrxx; ir++)
204-
{
205-
phi_comp_R[ir] = v(0, ir);
206-
}
207-
249+
int iat = 0;
250+
std::complex<double> *N = new std::complex<double>[rho_basis->npw];
251+
std::complex<double> *phi_comp_G = new complex<double>[rho_basis->npw];
252+
std::complex<double> *vloc_at = new std::complex<double>[rho_basis->npw];
208253
rho_basis->real2recip(phi_comp_R, phi_comp_G);
209-
for (int ig = 0; ig < rho_basis->npw; ig++)
254+
255+
for (int it = 0; it < GlobalC::ucell.ntype; it++)
210256
{
211-
if (rho_basis->gg[ig] >= 1.0e-12) // LiuXh 20180410
257+
for (int ia = 0; ia < GlobalC::ucell.atoms[it].na; ia++)
212258
{
213-
const double fac = ModuleBase::e2 * ModuleBase::FOUR_PI / (cell.tpiba2 * rho_basis->gg[ig]);
214-
comp_reci[ig] = phi_comp_G[ig] / fac;
215-
}
216-
}
217-
rho_basis->recip2real(comp_reci, N_real);
218-
219-
complex<double> *vloc_g = new complex<double>[rho_basis->npw];
220-
complex<double> *ng = new complex<double>[rho_basis->npw];
221-
ModuleBase::GlobalFunc::ZEROS(vloc_g, rho_basis->npw);
222-
ModuleBase::GlobalFunc::ZEROS(ng, rho_basis->npw);
223259

224-
double* Porter = new double[rho_basis->nrxx];
225-
for (int ir = 0; ir < rho_basis->nrxx; ir++)
226-
Porter[ir] = rho[0][ir];
260+
// cout << GlobalC::ucell.atoms[it].zv << endl;
261+
for (int ig = 0; ig < rho_basis->npw; ig++)
262+
{
263+
complex<double> phase = exp( ModuleBase::NEG_IMAG_UNIT *ModuleBase::TWO_PI * ( rho_basis->gcar[ig] * GlobalC::ucell.atoms[it].tau[ia]));
264+
//vloc for each atom
265+
vloc_at[ig] = GlobalC::ppcell.vloc(it, rho_basis->ig2igg[ig]) * phase;
266+
if(rho_basis->ig_gge0 == ig)
267+
{
268+
N[ig] = GlobalC::ucell.atoms[it].zv / GlobalC::ucell.omega;
269+
}
270+
else
271+
{
272+
const double fac
273+
= ModuleBase::e2 * ModuleBase::FOUR_PI / (GlobalC::ucell.tpiba2 * rho_basis->gg[ig]);
274+
275+
N[ig] = -vloc_at[ig] / fac;
276+
}
277+
278+
//force for each atom
279+
force_comp(iat, 0) += rho_basis->gcar[ig][0] * imag(conj(phi_comp_G[ig]) * N[ig]);
280+
force_comp(iat, 1) += rho_basis->gcar[ig][1] * imag(conj(phi_comp_G[ig]) * N[ig]);
281+
force_comp(iat, 2) += rho_basis->gcar[ig][2] * imag(conj(phi_comp_G[ig]) * N[ig]);
282+
}
283+
284+
force_comp(iat, 0) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega);
285+
force_comp(iat, 1) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega);
286+
force_comp(iat, 2) *= (GlobalC::ucell.tpiba * GlobalC::ucell.omega);
227287

228-
rho_basis->real2recip(GlobalC::pot.vltot,vloc_g);// now n is vloc in Recispace
229-
for (int ig = 0; ig < rho_basis->npw; ig++) {
230-
if (rho_basis->gg[ig] >= 1.0e-12) // LiuXh 20180410
231-
{
232-
const double fac = ModuleBase::e2 * ModuleBase::FOUR_PI /
233-
(cell.tpiba2 * rho_basis->gg[ig]);
288+
// cout << "Force1(Ry / Bohr)" << iat << ":"
289+
// << " " << force_comp(iat, 0) << " " << force_comp(iat, 1) << " " << force_comp(iat, 2) << endl;
234290

235-
ng[ig] = -vloc_g[ig] / fac;
291+
++iat;
236292
}
237293
}
238-
double *nr = new double[rho_basis->nrxx];
239-
rho_basis->recip2real(ng, nr);
240-
241-
double *diff = new double[rho_basis->nrxx];
242-
double *diff2 = new double[rho_basis->nrxx];
243-
for (int i = 0; i < rho_basis->nrxx; i++)
244-
{
245-
diff[i] = N_real[i] - nr[i];
246-
diff2[i] = N_real[i] - Porter[i];
247-
}
248-
249-
for (int i = 0; i < rho_basis->nrxx;i++)
250-
{
251-
diff[i] -= Porter[i];
252-
}
253-
254-
delete[] phi_comp_R;
294+
delete[] vloc_at;
295+
delete[] N;
255296
delete[] phi_comp_G;
256-
delete[] comp_reci;
257-
delete[] diff;
258-
delete[] vloc_g;
259-
delete[] Porter;
260-
}
297+
}

source/module_surchem/cal_totn.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
void surchem::cal_totn(const UnitCell &cell, ModulePW::PW_Basis* rho_basis,
44
const complex<double> *Porter_g, complex<double> *N,
55
complex<double> *TOTN) {
6-
// vloc to N8
6+
// vloc to N
77
complex<double> *vloc_g = new complex<double>[rho_basis->npw];
88
ModuleBase::GlobalFunc::ZEROS(vloc_g, rho_basis->npw);
99

@@ -25,7 +25,6 @@ void surchem::cal_totn(const UnitCell &cell, ModulePW::PW_Basis* rho_basis,
2525
TOTN[ig] = N[ig] - Porter_g[ig];
2626
}
2727

28-
// delete[] comp_real;
2928
delete[] vloc_g;
3029
return;
3130
}

source/module_surchem/cal_vel.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ ModuleBase::matrix surchem::cal_vel(const UnitCell &cell,
9393

9494
double *phi_tilda_R = new double[rho_basis->nrxx];
9595
double *phi_tilda_R0 = new double[rho_basis->nrxx];
96-
// double *delta_phi_R = new double[pwb.nrxx];
9796

9897
rho_basis->recip2real(Sol_phi, phi_tilda_R);
9998
rho_basis->recip2real(Sol_phi0, phi_tilda_R0);
@@ -144,11 +143,8 @@ ModuleBase::matrix surchem::cal_vel(const UnitCell &cell,
144143
delete[] epsilon;
145144
delete[] epsilon0;
146145
delete[] tmp_Vel;
147-
// delete[] Vel2;
148-
// delete[] TOTN_real;
149146
delete[] phi_tilda_R;
150147
delete[] phi_tilda_R0;
151-
// delete[] delta_phi_R;
152148

153149
ModuleBase::timer::tick("surchem", "cal_vel");
154150
return Vel;

0 commit comments

Comments
 (0)