88#include < cmath>
99
1010ModuleBase::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+ }
0 commit comments