66#include " source_base/parallel_reduce.h"
77
88void Evolve_OFDFT::cal_Hpsi (elecstate::ElecState* pelec,
9- const Charge& chr,
9+ Charge& chr,
1010 UnitCell& ucell,
11- std::vector<std::complex <double >> psi_,
11+ std::vector<std::complex <double >>& psi_,
1212 ModulePW::PW_Basis* pw_rho,
13- std::vector<std::complex <double >> Hpsi)
13+ std::vector<std::complex <double >>& Hpsi)
1414{
1515 // update rho
1616#ifdef _OPENMP
@@ -23,6 +23,7 @@ void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
2323 chr.rho [is][ir] = abs (psi_[is * pw_rho->nrxx + ir])*abs (psi_[is * pw_rho->nrxx + ir]);
2424 }
2525 }
26+ this ->renormalize_psi (chr, pw_rho, psi_);
2627
2728 pelec->pot ->update_from_charge (&chr, &ucell); // Hartree + XC + external
2829 this ->cal_tf_potential (chr.rho , pw_rho, pelec->pot ->get_eff_v ()); // TF potential
@@ -45,6 +46,26 @@ void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
4546 this ->cal_vw_potential_phi (psi_, pw_rho, Hpsi);
4647}
4748
49+ void Evolve_OFDFT::renormalize_psi (Charge& chr, ModulePW::PW_Basis* pw_rho, std::vector<std::complex <double >>& pphi_)
50+ {
51+ const double sr = chr.sum_rho ();
52+ const double normalize_factor = PARAM.inp .nelec / sr;
53+
54+ std::cout<<" sr=" <<sr<<" nelec=" <<PARAM.inp .nelec <<" normalize_factor=" <<normalize_factor<<std::endl;
55+ #ifdef _OPENMP
56+ #pragma omp parallel for collapse(2)
57+ #endif
58+ for (int is = 0 ; is < PARAM.inp .nspin ; is++)
59+ {
60+ for (int ir = 0 ; ir < pw_rho->nrxx ; ir++)
61+ {
62+ pphi_[is * pw_rho->nrxx + ir] *= sqrt (normalize_factor);
63+ chr.rho [is][ir] *= normalize_factor;
64+ }
65+ }
66+ return ;
67+ }
68+
4869void Evolve_OFDFT::cal_tf_potential (const double * const * prho, ModulePW::PW_Basis* pw_rho, ModuleBase::matrix& rpot)
4970{
5071 if (PARAM.inp .nspin == 1 )
@@ -72,9 +93,9 @@ void Evolve_OFDFT::cal_tf_potential(const double* const* prho, ModulePW::PW_Basi
7293 }
7394}
7495
75- void Evolve_OFDFT::cal_vw_potential_phi (std::vector<std::complex <double >> pphi,
96+ void Evolve_OFDFT::cal_vw_potential_phi (std::vector<std::complex <double >>& pphi,
7697 ModulePW::PW_Basis* pw_rho,
77- std::vector<std::complex <double >> Hpsi)
98+ std::vector<std::complex <double >>& Hpsi)
7899{
79100 if (PARAM.inp .nspin <= 0 ) {
80101 ModuleBase::WARNING_QUIT (" Evolve_OFDFT" ," nspin must be positive" );
@@ -107,7 +128,7 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
107128 pw_rho->recip2real (recipPhi[is], rLapPhi[is]);
108129 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
109130 {
110- Hpsi[is * pw_rho->nrxx + ir]+= rLapPhi[is][ir];
131+ Hpsi[is * pw_rho->nrxx + ir] += rLapPhi[is][ir];
111132 }
112133 }
113134
@@ -123,7 +144,7 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
123144 delete[] rLapPhi;
124145}
125146
126- void Evolve_OFDFT::cal_CD_potential (std::vector<std::complex <double >> psi_,
147+ void Evolve_OFDFT::cal_CD_potential (std::vector<std::complex <double >>& psi_,
127148 ModulePW::PW_Basis* pw_rho,
128149 ModuleBase::matrix& rpot,
129150 double mCD_para )
@@ -151,20 +172,20 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
151172#endif
152173 for (int is = 0 ; is < PARAM.inp .nspin ; ++is)
153174 {
154- std::complex < double > *recipCurrent_x= new std::complex <double >[ pw_rho->npw ] ;
155- std::complex < double > *recipCurrent_y= new std::complex <double >[ pw_rho->npw ] ;
156- std::complex < double > *recipCurrent_z= new std::complex <double >[ pw_rho->npw ] ;
157- std::complex < double > *recipCDPotential= new std::complex <double >[ pw_rho->npw ] ;
158- std::complex < double > *rCurrent_x= new std::complex <double >[ pw_rho->nrxx ] ;
159- std::complex < double > *rCurrent_y= new std::complex <double >[ pw_rho->nrxx ] ;
160- std::complex < double > *rCurrent_z= new std::complex <double >[ pw_rho->nrxx ] ;
161- std::complex < double > * kF_r = new std::complex <double >[ pw_rho->nrxx ] ;
162- std::complex < double > *rCDPotential= new std::complex <double >[ pw_rho->nrxx ] ;
175+ std::vector< std::complex <double >> recipCurrent_x ( pw_rho->npw ) ;
176+ std::vector< std::complex <double >> recipCurrent_y ( pw_rho->npw ) ;
177+ std::vector< std::complex <double >> recipCurrent_z ( pw_rho->npw ) ;
178+ std::vector< std::complex <double >> recipCDPotential ( pw_rho->npw ) ;
179+ std::vector< std::complex <double >> rCurrent_x ( pw_rho->nrxx ) ;
180+ std::vector< std::complex <double >> rCurrent_y ( pw_rho->nrxx ) ;
181+ std::vector< std::complex <double >> rCurrent_z ( pw_rho->nrxx ) ;
182+ std::vector< std::complex <double >> kF_r ( pw_rho->nrxx ) ;
183+ std::vector< std::complex <double >> rCDPotential ( pw_rho->nrxx ) ;
163184 recipPhi[is] = new std::complex <double >[pw_rho->npw ];
164185
165186 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
166187 {
167- kF_r [ir]=std::pow (3 *std::pow (ModuleBase::PI*std::abs (rPhi[is][ir]),2 ),1 / 3 );
188+ kF_r [ir]=std::pow (3 *std::pow (ModuleBase::PI*std::abs (rPhi[is][ir]),2 ),1.0 / 3.0 );
168189 }
169190
170191 pw_rho->real2recip (rPhi[is], recipPhi[is]);
@@ -174,38 +195,40 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
174195 recipCurrent_y[ik]=imag*pw_rho->gcar [ik].y *recipPhi[is][ik]* pw_rho->tpiba ;
175196 recipCurrent_z[ik]=imag*pw_rho->gcar [ik].z *recipPhi[is][ik]* pw_rho->tpiba ;
176197 }
177- pw_rho->recip2real (recipCurrent_x,rCurrent_x);
178- pw_rho->recip2real (recipCurrent_y,rCurrent_y);
179- pw_rho->recip2real (recipCurrent_z,rCurrent_z);
198+ pw_rho->recip2real (recipCurrent_x. data () ,rCurrent_x. data () );
199+ pw_rho->recip2real (recipCurrent_y. data () ,rCurrent_y. data () );
200+ pw_rho->recip2real (recipCurrent_z. data () ,rCurrent_z. data () );
180201 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
181202 {
182203 rCurrent_x[ir]=std::imag (rCurrent_x[ir]*std::conj (rPhi[is][ir]));
183204 rCurrent_y[ir]=std::imag (rCurrent_y[ir]*std::conj (rPhi[is][ir]));
184205 rCurrent_z[ir]=std::imag (rCurrent_z[ir]*std::conj (rPhi[is][ir]));
185206 }
186- pw_rho->real2recip (rCurrent_x,recipCurrent_x);
187- pw_rho->real2recip (rCurrent_y,recipCurrent_y);
188- pw_rho->real2recip (rCurrent_z,recipCurrent_z);
207+ pw_rho->real2recip (rCurrent_x. data () ,recipCurrent_x. data () );
208+ pw_rho->real2recip (rCurrent_y. data () ,recipCurrent_y. data () );
209+ pw_rho->real2recip (rCurrent_z. data () ,recipCurrent_z. data () );
189210 for (int ik = 0 ; ik < pw_rho->npw ; ++ik)
190211 {
191- recipCDPotential[ik]=recipCurrent_x[ik]*pw_rho->gcar [ik].x
192- +recipCurrent_y[ik]*pw_rho->gcar [ik].y
193- +recipCurrent_z[ik]*pw_rho->gcar [ik].z ;
194- recipCDPotential[ik]*=imag/pw_rho->gg [ik];
212+ recipCDPotential[ik]=recipCurrent_x[ik]*pw_rho->gcar [ik].x +recipCurrent_y[ik]*pw_rho->gcar [ik].y +recipCurrent_z[ik]*pw_rho->gcar [ik].z ;
213+ if (pw_rho->gg [ik]==0 )
214+ {
215+ recipCDPotential[ik]=0.0 ;
216+ }
217+ else
218+ {
219+ recipCDPotential[ik]*=imag/sqrt (pw_rho->gg [ik]);
220+ }
195221 }
196- pw_rho->recip2real (recipCDPotential,rCDPotential);
222+ pw_rho->recip2real (recipCDPotential. data () ,rCDPotential. data () );
197223
198224 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
199225 {
200- rpot (0 , ir) -= mCD_para *2.0 *std::real (rCDPotential[ir])*std::pow (ModuleBase::PI,3 )
201- / (2.0 *std::pow (std::real (kF_r [ir]),2 ));
226+ rpot (0 , ir) -= mCD_para *2.0 *std::real (rCDPotential[ir])*std::pow (ModuleBase::PI,3 ) / (2.0 *std::pow (std::real (kF_r [ir]),2 ));
227+ if (isnan (rpot (0 , ir)))
228+ {
229+ rpot (0 , ir)=0.0 ;
230+ }
202231 }
203- delete[] recipCurrent_x;
204- delete[] recipCurrent_y;
205- delete[] recipCurrent_z;
206- delete[] rCurrent_x;
207- delete[] rCurrent_y;
208- delete[] rCurrent_z;
209232 }
210233
211234#ifdef _OPENMP
@@ -220,15 +243,16 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
220243 delete[] rPhi;
221244}
222245
223- void Evolve_OFDFT::propagate_psi (elecstate::ElecState* pelec,
224- const Charge& chr, UnitCell& ucell,
225- std::vector<std::complex <double >> pphi_,
246+ void Evolve_OFDFT::propagate_psi_RK4 (elecstate::ElecState* pelec,
247+ Charge& chr,
248+ UnitCell& ucell,
249+ std::vector<std::complex <double >>& pphi_,
226250 ModulePW::PW_Basis* pw_rho)
227251{
228- ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagte_psi " );
252+ ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagate_psi_RK4 " );
229253
230254 std::complex <double > imag (0.0 ,1.0 );
231- double dt=PARAM.inp .mdp .md_dt ;
255+ double dt=PARAM.inp .mdp .md_dt / ModuleBase::AU_to_FS ;
232256 const int nspin = PARAM.inp .nspin ;
233257 const int nrxx = pw_rho->nrxx ;
234258 const int total_size = nspin * nrxx;
@@ -247,7 +271,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
247271 for (int is = 0 ; is < PARAM.inp .nspin ; ++is){
248272 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
249273 {
250- K1[is * nrxx + ir]=-1.0 *K1[is * nrxx + ir]*dt*imag;
274+ K1[is * nrxx + ir]=-0.5 *K1[is * nrxx + ir]*dt*imag; // 0.5 convert Ry to Hartree
251275 psi1[is * nrxx + ir]=pphi_[is * nrxx + ir]+0.5 *K1[is * nrxx + ir];
252276 }
253277 }
@@ -258,7 +282,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
258282 for (int is = 0 ; is < PARAM.inp .nspin ; ++is){
259283 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
260284 {
261- K2[is * nrxx + ir]=-1.0 *K2[is * nrxx + ir]*dt*imag;
285+ K2[is * nrxx + ir]=-0.5 *K2[is * nrxx + ir]*dt*imag;
262286 psi2[is * nrxx + ir]=pphi_[is * nrxx + ir]+0.5 *K2[is * nrxx + ir];
263287 }
264288 }
@@ -269,7 +293,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
269293 for (int is = 0 ; is < PARAM.inp .nspin ; ++is){
270294 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
271295 {
272- K3[is * nrxx + ir]=-1.0 *K3[is * nrxx + ir]*dt*imag;
296+ K3[is * nrxx + ir]=-0.5 *K3[is * nrxx + ir]*dt*imag;
273297 psi3[is * nrxx + ir]=pphi_[is * nrxx + ir]+K3[is * nrxx + ir];
274298 }
275299 }
@@ -280,12 +304,80 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
280304 for (int is = 0 ; is < PARAM.inp .nspin ; ++is){
281305 for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
282306 {
283- K4[is * nrxx + ir]=-1.0 *K4[is * nrxx + ir]*dt*imag;
284- pphi_[is * nrxx + ir]+=1.0 /6.0 *(K1[is * nrxx + ir]
285- +2.0 *K2[is * nrxx + ir]+2.0 *K3[is * nrxx + ir]
286- +K4[is * nrxx + ir]);
307+ K4[is * nrxx + ir]=-0.5 *K4[is * nrxx + ir]*dt*imag;
308+ pphi_[is * nrxx + ir]+=1.0 /6.0 *(K1[is * nrxx + ir]+2.0 *K2[is * nrxx + ir]+2.0 *K3[is * nrxx + ir]+K4[is * nrxx + ir]);
309+ }
310+ }
311+
312+ #ifdef _OPENMP
313+ #pragma omp parallel for collapse(2)
314+ #endif
315+ for (int is = 0 ; is < PARAM.inp .nspin ; ++is)
316+ {
317+ for (int ir = 0 ; ir < pw_rho->nrxx ; ++ir)
318+ {
319+ chr.rho [is][ir] = abs (pphi_[is * pw_rho->nrxx + ir])*abs (pphi_[is * pw_rho->nrxx + ir]);
320+ }
321+ }
322+ this ->renormalize_psi (chr, pw_rho, pphi_);
323+
324+ ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagate_psi_RK4" );
325+ }
326+
327+ void Evolve_OFDFT::propagate_psi_RK2 (elecstate::ElecState* pelec,
328+ Charge& chr,
329+ UnitCell& ucell,
330+ std::vector<std::complex <double >>& pphi_,
331+ ModulePW::PW_Basis* pw_rho)
332+ {
333+ ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagate_psi_RK2" );
334+
335+ const std::complex <double > imag (0.0 , 1.0 );
336+ double dt=PARAM.inp .mdp .md_dt / ModuleBase::AU_to_FS;
337+ const int nspin = PARAM.inp .nspin ;
338+ const int nrxx = pw_rho->nrxx ;
339+ const int total_size = nspin * nrxx;
340+
341+ std::vector<std::complex <double >> K1 (total_size);
342+ std::vector<std::complex <double >> K2 (total_size);
343+ std::vector<std::complex <double >> psi_mid (total_size);
344+
345+ cal_Hpsi (pelec, chr, ucell, pphi_, pw_rho, K1);
346+
347+ #ifdef _OPENMP
348+ #pragma omp parallel for collapse(2)
349+ #endif
350+ for (int is = 0 ; is < nspin; ++is) {
351+ for (int ir = 0 ; ir < nrxx; ++ir) {
352+ const int idx = is * nrxx + ir;
353+ K1[idx] = -0.5 * K1[idx] * dt * imag;
354+ psi_mid[idx] = pphi_[idx] + 0.5 * K1[idx];
355+ }
356+ }
357+
358+ cal_Hpsi (pelec, chr, ucell, psi_mid, pw_rho, K2);
359+
360+ #ifdef _OPENMP
361+ #pragma omp parallel for collapse(2)
362+ #endif
363+ for (int is = 0 ; is < nspin; ++is) {
364+ for (int ir = 0 ; ir < nrxx; ++ir) {
365+ const int idx = is * nrxx + ir;
366+ K2[idx] = -0.5 * K2[idx] * dt * imag;
367+ pphi_[idx] += K2[idx];
287368 }
288369 }
289370
290- ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagte_psi" );
371+ #ifdef _OPENMP
372+ #pragma omp parallel for collapse(2)
373+ #endif
374+ for (int is = 0 ; is < nspin; ++is) {
375+ for (int ir = 0 ; ir < nrxx; ++ir) {
376+ chr.rho [is][ir] = std::norm (pphi_[is * nrxx + ir]);
377+ }
378+ }
379+
380+ this ->renormalize_psi (chr, pw_rho, pphi_);
381+
382+ ModuleBase::timer::tick (" ESolver_OF_TDDFT" , " propagate_psi_RK2" );
291383}
0 commit comments