Skip to content

Commit 1348a16

Browse files
lyb9812sunliang98
andauthored
Fix: Al ESP result discrepancy & add wavefunction normalization (#6853)
* add esolver_of_tddft * esolver_of_tddft cmakelist * move memeber function of esolver_of_tddft to module_ofdft * fix bug (confuse evolve_psi with evolve_phi) * change evolve_phi with evolve_ofdft; change to vector * details * code optimization * add situation of reading charge file for tdofdft * add CD Potential * add INPUT parameters for tdofdft * add integrate test for TDOFDFT * update doc file for tdofdft * solve conflict * type transformation * type transformation * move integration test for TDOFDFT to 07_OFDFT * add judgement for nspin in TDOFDFT * add judgement for nspin in TDOFDFT * TDOFDFT integration test * change type of warning * fix bug of TDOFDFT * solve conflicts * solve conflicts * update integration of tdofdft * add threshold for TDOFDFT integration test --------- Co-authored-by: Liang Sun <[email protected]>
1 parent f7deafc commit 1348a16

File tree

10 files changed

+195
-79
lines changed

10 files changed

+195
-79
lines changed

source/source_esolver/esolver_of_tddft.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
//-----stress------------------
1717
#include "source_pw/module_ofdft/of_stress_pw.h"
1818

19+
#include <iostream>
20+
1921
namespace ModuleESolver
2022
{
2123

@@ -45,12 +47,13 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep)
4547
this->iter_time = std::chrono::system_clock::now();
4648
#endif
4749

48-
if (istep==0)
50+
if (this->phi_td.empty())
4951
{
50-
this->phi_td.resize(PARAM.inp.nspin*this->pw_rho->nrxx);
52+
const int size = PARAM.inp.nspin * this->pw_rho->nrxx;
53+
this->phi_td.resize(size, std::complex<double>(0.0, 0.0));
5154
}
5255

53-
if ((istep<1) && PARAM.inp.init_chg != "file")
56+
if ((istep==0) && PARAM.inp.init_chg != "file")
5457
{
5558
while (true)
5659
{
@@ -91,7 +94,7 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep)
9194
}
9295
}
9396
}
94-
else if ((istep<1) && PARAM.inp.init_chg == "file")
97+
else if ((istep==0) && PARAM.inp.init_chg == "file")
9598
{
9699
#ifdef _OPENMP
97100
#pragma omp parallel for collapse(2)
@@ -107,7 +110,7 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep)
107110
}
108111
else
109112
{
110-
this->evolve_ofdft->propagate_psi(this->pelec, this->chr, ucell, this->phi_td, this->pw_rho);
113+
this->evolve_ofdft->propagate_psi_RK4(this->pelec, this->chr, ucell, this->phi_td, this->pw_rho);
111114
#ifdef _OPENMP
112115
#pragma omp parallel for collapse(2)
113116
#endif

source/source_esolver/esolver_of_tddft.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class ESolver_OF_TDDFT : public ESolver_OF
1515
virtual void runner(UnitCell& ucell, const int istep) override;
1616

1717
protected:
18-
std::vector<std::complex<double>> phi_td; // pphi[i] = ppsi.get_pointer(i), which will be freed in ~Psi().
18+
std::vector<std::complex<double>> phi_td; // time dependent wavefunction
1919
Evolve_OFDFT* evolve_ofdft=nullptr;
2020
};
2121
} // namespace ModuleESolver

source/source_pw/module_ofdft/evolve_ofdft.cpp

Lines changed: 141 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
#include "source_base/parallel_reduce.h"
77

88
void 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+
4869
void 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

Comments
 (0)