Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ccb8a5d
add esolver_of_tddft
lyb9812 Sep 26, 2025
96dd8cc
esolver_of_tddft cmakelist
lyb9812 Sep 26, 2025
c87639c
move memeber function of esolver_of_tddft to module_ofdft
lyb9812 Sep 26, 2025
d311eb3
fix bug (confuse evolve_psi with evolve_phi)
lyb9812 Sep 26, 2025
262c4e5
change evolve_phi with evolve_ofdft; change to vector
lyb9812 Sep 27, 2025
020cd9d
Merge branch 'develop' into develop
lyb9812 Sep 27, 2025
c577829
Merge branch 'develop' of https://github.com/deepmodeling/abacus-deve…
lyb9812 Sep 27, 2025
70a0204
Merge branch 'develop' of https://github.com/lyb9812/abacus-develop i…
lyb9812 Sep 27, 2025
e65e75b
Merge branch 'develop' into develop
sunliang98 Sep 27, 2025
5acb224
Merge branch 'develop' of https://github.com/deepmodeling/abacus-deve…
lyb9812 Sep 27, 2025
d38224d
details
lyb9812 Sep 27, 2025
a252d05
Merge branch 'develop' of https://github.com/lyb9812/abacus-develop i…
lyb9812 Sep 27, 2025
cde47d3
code optimization
lyb9812 Sep 29, 2025
ea55c5c
Merge branch 'develop' of https://github.com/deepmodeling/abacus-deve…
lyb9812 Sep 29, 2025
a35a7ae
add situation of reading charge file for tdofdft
lyb9812 Sep 29, 2025
ef29159
add CD Potential
lyb9812 Oct 11, 2025
2eeb5e9
add INPUT parameters for tdofdft
lyb9812 Oct 11, 2025
37d3bf5
add integrate test for TDOFDFT
lyb9812 Oct 12, 2025
d8dead8
update doc file for tdofdft
lyb9812 Oct 12, 2025
5bad0d0
solve conflicts
lyb9812 Oct 12, 2025
51644c2
solve conflict
lyb9812 Oct 12, 2025
22b88fc
type transformation
lyb9812 Oct 12, 2025
a917e0b
type transformation
lyb9812 Oct 12, 2025
e595068
Merge branch 'develop' of https://github.com/deepmodeling/abacus-deve…
lyb9812 Oct 12, 2025
4c0a683
move integration test for TDOFDFT to 07_OFDFT
lyb9812 Oct 12, 2025
824e014
add judgement for nspin in TDOFDFT
lyb9812 Oct 12, 2025
040af90
add judgement for nspin in TDOFDFT
lyb9812 Oct 12, 2025
967d41f
Merge branch 'develop' of https://github.com/deepmodeling/abacus-deve…
lyb9812 Oct 12, 2025
e3fdd3e
TDOFDFT integration test
lyb9812 Oct 12, 2025
b278f26
change type of warning
lyb9812 Oct 13, 2025
1e56b71
fix bug of TDOFDFT
lyb9812 Jan 12, 2026
7815a24
solve conflicts
lyb9812 Jan 12, 2026
9238edb
solve conflicts
lyb9812 Jan 12, 2026
707811e
solve conflicts
lyb9812 Jan 12, 2026
ac336ae
update integration of tdofdft
lyb9812 Jan 12, 2026
7ef3bc2
add threshold for TDOFDFT integration test
lyb9812 Jan 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions source/source_esolver/esolver_of_tddft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
//-----stress------------------
#include "source_pw/module_ofdft/of_stress_pw.h"

#include <iostream>

namespace ModuleESolver
{

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

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

if ((istep<1) && PARAM.inp.init_chg != "file")
if ((istep==0) && PARAM.inp.init_chg != "file")
{
while (true)
{
Expand Down Expand Up @@ -91,7 +94,7 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep)
}
}
}
else if ((istep<1) && PARAM.inp.init_chg == "file")
else if ((istep==0) && PARAM.inp.init_chg == "file")
{
#ifdef _OPENMP
#pragma omp parallel for collapse(2)
Expand All @@ -107,7 +110,7 @@ void ESolver_OF_TDDFT::runner(UnitCell& ucell, const int istep)
}
else
{
this->evolve_ofdft->propagate_psi(this->pelec, this->chr, ucell, this->phi_td, this->pw_rho);
this->evolve_ofdft->propagate_psi_RK4(this->pelec, this->chr, ucell, this->phi_td, this->pw_rho);
#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
Expand Down
2 changes: 1 addition & 1 deletion source/source_esolver/esolver_of_tddft.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ESolver_OF_TDDFT : public ESolver_OF
virtual void runner(UnitCell& ucell, const int istep) override;

protected:
std::vector<std::complex<double>> phi_td; // pphi[i] = ppsi.get_pointer(i), which will be freed in ~Psi().
std::vector<std::complex<double>> phi_td; // time dependent wavefunction
Evolve_OFDFT* evolve_ofdft=nullptr;
};
} // namespace ModuleESolver
Expand Down
190 changes: 141 additions & 49 deletions source/source_pw/module_ofdft/evolve_ofdft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
#include "source_base/parallel_reduce.h"

void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
const Charge& chr,
Charge& chr,
UnitCell& ucell,
std::vector<std::complex<double>> psi_,
std::vector<std::complex<double>>& psi_,
ModulePW::PW_Basis* pw_rho,
std::vector<std::complex<double>> Hpsi)
std::vector<std::complex<double>>& Hpsi)
{
// update rho
#ifdef _OPENMP
Expand All @@ -23,6 +23,7 @@ void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
chr.rho[is][ir] = abs(psi_[is * pw_rho->nrxx + ir])*abs(psi_[is * pw_rho->nrxx + ir]);
}
}
this->renormalize_psi(chr, pw_rho, psi_);

pelec->pot->update_from_charge(&chr, &ucell); // Hartree + XC + external
this->cal_tf_potential(chr.rho, pw_rho, pelec->pot->get_eff_v()); // TF potential
Expand All @@ -45,6 +46,26 @@ void Evolve_OFDFT::cal_Hpsi(elecstate::ElecState* pelec,
this->cal_vw_potential_phi(psi_, pw_rho, Hpsi);
}

void Evolve_OFDFT::renormalize_psi(Charge& chr, ModulePW::PW_Basis* pw_rho, std::vector<std::complex<double>>& pphi_)
{
const double sr = chr.sum_rho();
const double normalize_factor = PARAM.inp.nelec / sr;

std::cout<<"sr="<<sr<<" nelec="<<PARAM.inp.nelec<<" normalize_factor="<<normalize_factor<<std::endl;
#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
for (int is = 0; is < PARAM.inp.nspin; is++)
{
for (int ir = 0; ir < pw_rho->nrxx; ir++)
{
pphi_[is * pw_rho->nrxx + ir] *= sqrt(normalize_factor);
chr.rho[is][ir] *= normalize_factor;
}
}
return;
}

void Evolve_OFDFT::cal_tf_potential(const double* const* prho, ModulePW::PW_Basis* pw_rho, ModuleBase::matrix& rpot)
{
if (PARAM.inp.nspin == 1)
Expand Down Expand Up @@ -72,9 +93,9 @@ void Evolve_OFDFT::cal_tf_potential(const double* const* prho, ModulePW::PW_Basi
}
}

void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>>& pphi,
ModulePW::PW_Basis* pw_rho,
std::vector<std::complex<double>> Hpsi)
std::vector<std::complex<double>>& Hpsi)
{
if (PARAM.inp.nspin <= 0) {
ModuleBase::WARNING_QUIT("Evolve_OFDFT","nspin must be positive");
Expand Down Expand Up @@ -107,7 +128,7 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
pw_rho->recip2real(recipPhi[is], rLapPhi[is]);
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
Hpsi[is * pw_rho->nrxx + ir]+=rLapPhi[is][ir];
Hpsi[is * pw_rho->nrxx + ir] += rLapPhi[is][ir];
}
}

Expand All @@ -123,7 +144,7 @@ void Evolve_OFDFT::cal_vw_potential_phi(std::vector<std::complex<double>> pphi,
delete[] rLapPhi;
}

void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>>& psi_,
ModulePW::PW_Basis* pw_rho,
ModuleBase::matrix& rpot,
double mCD_para)
Expand Down Expand Up @@ -151,20 +172,20 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
#endif
for (int is = 0; is < PARAM.inp.nspin; ++is)
{
std::complex<double> *recipCurrent_x=new std::complex<double>[pw_rho->npw];
std::complex<double> *recipCurrent_y=new std::complex<double>[pw_rho->npw];
std::complex<double> *recipCurrent_z=new std::complex<double>[pw_rho->npw];
std::complex<double> *recipCDPotential=new std::complex<double>[pw_rho->npw];
std::complex<double> *rCurrent_x=new std::complex<double>[pw_rho->nrxx];
std::complex<double> *rCurrent_y=new std::complex<double>[pw_rho->nrxx];
std::complex<double> *rCurrent_z=new std::complex<double>[pw_rho->nrxx];
std::complex<double> *kF_r=new std::complex<double>[pw_rho->nrxx];
std::complex<double> *rCDPotential=new std::complex<double>[pw_rho->nrxx];
std::vector<std::complex<double>> recipCurrent_x(pw_rho->npw);
std::vector<std::complex<double>> recipCurrent_y(pw_rho->npw);
std::vector<std::complex<double>> recipCurrent_z(pw_rho->npw);
std::vector<std::complex<double>> recipCDPotential(pw_rho->npw);
std::vector<std::complex<double>> rCurrent_x(pw_rho->nrxx);
std::vector<std::complex<double>> rCurrent_y(pw_rho->nrxx);
std::vector<std::complex<double>> rCurrent_z(pw_rho->nrxx);
std::vector<std::complex<double>> kF_r(pw_rho->nrxx);
std::vector<std::complex<double>> rCDPotential(pw_rho->nrxx);
recipPhi[is] = new std::complex<double>[pw_rho->npw];

for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
kF_r[ir]=std::pow(3*std::pow(ModuleBase::PI*std::abs(rPhi[is][ir]),2),1/3);
kF_r[ir]=std::pow(3*std::pow(ModuleBase::PI*std::abs(rPhi[is][ir]),2),1.0/3.0);
}

pw_rho->real2recip(rPhi[is], recipPhi[is]);
Expand All @@ -174,38 +195,40 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
recipCurrent_y[ik]=imag*pw_rho->gcar[ik].y*recipPhi[is][ik]* pw_rho->tpiba;
recipCurrent_z[ik]=imag*pw_rho->gcar[ik].z*recipPhi[is][ik]* pw_rho->tpiba;
}
pw_rho->recip2real(recipCurrent_x,rCurrent_x);
pw_rho->recip2real(recipCurrent_y,rCurrent_y);
pw_rho->recip2real(recipCurrent_z,rCurrent_z);
pw_rho->recip2real(recipCurrent_x.data(),rCurrent_x.data());
pw_rho->recip2real(recipCurrent_y.data(),rCurrent_y.data());
pw_rho->recip2real(recipCurrent_z.data(),rCurrent_z.data());
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
rCurrent_x[ir]=std::imag(rCurrent_x[ir]*std::conj(rPhi[is][ir]));
rCurrent_y[ir]=std::imag(rCurrent_y[ir]*std::conj(rPhi[is][ir]));
rCurrent_z[ir]=std::imag(rCurrent_z[ir]*std::conj(rPhi[is][ir]));
}
pw_rho->real2recip(rCurrent_x,recipCurrent_x);
pw_rho->real2recip(rCurrent_y,recipCurrent_y);
pw_rho->real2recip(rCurrent_z,recipCurrent_z);
pw_rho->real2recip(rCurrent_x.data(),recipCurrent_x.data());
pw_rho->real2recip(rCurrent_y.data(),recipCurrent_y.data());
pw_rho->real2recip(rCurrent_z.data(),recipCurrent_z.data());
for (int ik = 0; ik < pw_rho->npw; ++ik)
{
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;
recipCDPotential[ik]*=imag/pw_rho->gg[ik];
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;
if (pw_rho->gg[ik]==0)
{
recipCDPotential[ik]=0.0;
}
else
{
recipCDPotential[ik]*=imag/sqrt(pw_rho->gg[ik]);
}
}
pw_rho->recip2real(recipCDPotential,rCDPotential);
pw_rho->recip2real(recipCDPotential.data(),rCDPotential.data());

for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
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));
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));
if (isnan(rpot(0, ir)))
{
rpot(0, ir)=0.0;
}
}
delete[] recipCurrent_x;
delete[] recipCurrent_y;
delete[] recipCurrent_z;
delete[] rCurrent_x;
delete[] rCurrent_y;
delete[] rCurrent_z;
}

#ifdef _OPENMP
Expand All @@ -220,15 +243,16 @@ void Evolve_OFDFT::cal_CD_potential(std::vector<std::complex<double>> psi_,
delete[] rPhi;
}

void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
const Charge& chr, UnitCell& ucell,
std::vector<std::complex<double>> pphi_,
void Evolve_OFDFT::propagate_psi_RK4(elecstate::ElecState* pelec,
Charge& chr,
UnitCell& ucell,
std::vector<std::complex<double>>& pphi_,
ModulePW::PW_Basis* pw_rho)
{
ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagte_psi");
ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagate_psi_RK4");

std::complex<double> imag(0.0,1.0);
double dt=PARAM.inp.mdp.md_dt;
double dt=PARAM.inp.mdp.md_dt / ModuleBase::AU_to_FS;
const int nspin = PARAM.inp.nspin;
const int nrxx = pw_rho->nrxx;
const int total_size = nspin * nrxx;
Expand All @@ -247,7 +271,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
for (int is = 0; is < PARAM.inp.nspin; ++is){
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
K1[is * nrxx + ir]=-1.0*K1[is * nrxx + ir]*dt*imag;
K1[is * nrxx + ir]=-0.5*K1[is * nrxx + ir]*dt*imag; // 0.5 convert Ry to Hartree
psi1[is * nrxx + ir]=pphi_[is * nrxx + ir]+0.5*K1[is * nrxx + ir];
}
}
Expand All @@ -258,7 +282,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
for (int is = 0; is < PARAM.inp.nspin; ++is){
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
K2[is * nrxx + ir]=-1.0*K2[is * nrxx + ir]*dt*imag;
K2[is * nrxx + ir]=-0.5*K2[is * nrxx + ir]*dt*imag;
psi2[is * nrxx + ir]=pphi_[is * nrxx + ir]+0.5*K2[is * nrxx + ir];
}
}
Expand All @@ -269,7 +293,7 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
for (int is = 0; is < PARAM.inp.nspin; ++is){
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
K3[is * nrxx + ir]=-1.0*K3[is * nrxx + ir]*dt*imag;
K3[is * nrxx + ir]=-0.5*K3[is * nrxx + ir]*dt*imag;
psi3[is * nrxx + ir]=pphi_[is * nrxx + ir]+K3[is * nrxx + ir];
}
}
Expand All @@ -280,12 +304,80 @@ void Evolve_OFDFT::propagate_psi(elecstate::ElecState* pelec,
for (int is = 0; is < PARAM.inp.nspin; ++is){
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
K4[is * nrxx + ir]=-1.0*K4[is * nrxx + ir]*dt*imag;
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]);
K4[is * nrxx + ir]=-0.5*K4[is * nrxx + ir]*dt*imag;
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]);
}
}

#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
for (int is = 0; is < PARAM.inp.nspin; ++is)
{
for (int ir = 0; ir < pw_rho->nrxx; ++ir)
{
chr.rho[is][ir] = abs(pphi_[is * pw_rho->nrxx + ir])*abs(pphi_[is * pw_rho->nrxx + ir]);
}
}
this->renormalize_psi(chr, pw_rho, pphi_);

ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagate_psi_RK4");
}

void Evolve_OFDFT::propagate_psi_RK2(elecstate::ElecState* pelec,
Charge& chr,
UnitCell& ucell,
std::vector<std::complex<double>>& pphi_,
ModulePW::PW_Basis* pw_rho)
{
ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagate_psi_RK2");

const std::complex<double> imag(0.0, 1.0);
double dt=PARAM.inp.mdp.md_dt / ModuleBase::AU_to_FS;
const int nspin = PARAM.inp.nspin;
const int nrxx = pw_rho->nrxx;
const int total_size = nspin * nrxx;

std::vector<std::complex<double>> K1(total_size);
std::vector<std::complex<double>> K2(total_size);
std::vector<std::complex<double>> psi_mid(total_size);

cal_Hpsi(pelec, chr, ucell, pphi_, pw_rho, K1);

#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
for (int is = 0; is < nspin; ++is) {
for (int ir = 0; ir < nrxx; ++ir) {
const int idx = is * nrxx + ir;
K1[idx] = -0.5 * K1[idx] * dt * imag;
psi_mid[idx] = pphi_[idx] + 0.5 * K1[idx];
}
}

cal_Hpsi(pelec, chr, ucell, psi_mid, pw_rho, K2);

#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
for (int is = 0; is < nspin; ++is) {
for (int ir = 0; ir < nrxx; ++ir) {
const int idx = is * nrxx + ir;
K2[idx] = -0.5 * K2[idx] * dt * imag;
pphi_[idx] += K2[idx];
}
}

ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagte_psi");
#ifdef _OPENMP
#pragma omp parallel for collapse(2)
#endif
for (int is = 0; is < nspin; ++is) {
for (int ir = 0; ir < nrxx; ++ir) {
chr.rho[is][ir] = std::norm(pphi_[is * nrxx + ir]);
}
}

this->renormalize_psi(chr, pw_rho, pphi_);

ModuleBase::timer::tick("ESolver_OF_TDDFT", "propagate_psi_RK2");
}
Loading
Loading