Skip to content

Commit b774535

Browse files
authored
Fix: Add the correct RT-TDDFT electric field force acting on ions (#5918)
* Fix: Add the correct RT-TDDFT electric field force acting on ions * Fix a CI/CD test issue
1 parent dbf3bd6 commit b774535

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

source/module_elecstate/potentials/H_TDDFT_pw.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ double H_TDDFT_pw::amp;
1818
double H_TDDFT_pw::bmod;
1919
double H_TDDFT_pw::bvec[3];
2020

21+
// Used for calculating electric field force on ions
22+
vector<double> H_TDDFT_pw::global_vext_time = {0.0, 0.0, 0.0};
23+
2124
int H_TDDFT_pw::stype; // 0 : length gauge 1: velocity gauge
2225

2326
std::vector<int> H_TDDFT_pw::ttype;
@@ -121,11 +124,29 @@ void H_TDDFT_pw::cal_fixed_v(double* vl_pseudo)
121124
trigo_count = 0;
122125
heavi_count = 0;
123126

127+
global_vext_time = {0.0, 0.0, 0.0};
128+
129+
if (PARAM.inp.td_vext_dire.size() != 1)
130+
{
131+
ModuleBase::WARNING("H_TDDFT_pw::cal_fixed_v",
132+
"Multiple electric fields detected. This feature may have potential issues and is not "
133+
"recommended for use!");
134+
}
135+
if (PARAM.inp.td_vext_dire.size() > 2)
136+
{
137+
// To avoid breaking the integration test 601_NO_TDDFT_H2_len_hhg, a maximum of 2 electric fields are allowed
138+
ModuleBase::WARNING_QUIT("H_TDDFT_pw::cal_fixed_v",
139+
"For the sake of program stability, the feature of applying multiple electric fields "
140+
"simultaneously has been temporarily disabled. Thank you for your understanding!");
141+
}
142+
124143
for (auto direc: PARAM.inp.td_vext_dire)
125144
{
126145
std::vector<double> vext_space(this->rho_basis_->nrxx, 0.0);
127146
double vext_time = cal_v_time(ttype[count], true);
128147

148+
global_vext_time[direc - 1] += vext_time;
149+
129150
if (PARAM.inp.out_efield && GlobalV::MY_RANK == 0)
130151
{
131152
std::stringstream as;
@@ -479,7 +500,7 @@ void H_TDDFT_pw::prepare(const ModuleBase::Matrix3& G, int& dir)
479500
bmod = sqrt(pow(bvec[0], 2) + pow(bvec[1], 2) + pow(bvec[2], 2));
480501
}
481502

482-
void H_TDDFT_pw ::compute_force(const UnitCell& cell, ModuleBase::matrix& fe)
503+
void H_TDDFT_pw::compute_force(const UnitCell& cell, ModuleBase::matrix& fe)
483504
{
484505
int iat = 0;
485506
for (int it = 0; it < cell.ntype; ++it)
@@ -488,7 +509,9 @@ void H_TDDFT_pw ::compute_force(const UnitCell& cell, ModuleBase::matrix& fe)
488509
{
489510
for (int jj = 0; jj < 3; ++jj)
490511
{
491-
fe(iat, jj) = ModuleBase::e2 * amp * cell.atoms[it].ncpp.zv * bvec[jj] / bmod;
512+
// No need to multiply ModuleBase::e2, since the unit of force is Ry/Bohr
513+
fe(iat, jj)
514+
= (std::abs(bmod) > 1e-10 ? global_vext_time[jj] * cell.atoms[it].ncpp.zv * bvec[jj] / bmod : 0);
492515
}
493516
++iat;
494517
}

source/module_elecstate/potentials/H_TDDFT_pw.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class H_TDDFT_pw : public PotBase
124124
static bool is_initialized; // static flag variable, used to ensure initialization only once
125125

126126
static double amp;
127+
static vector<double> global_vext_time;
127128

128129
static double bmod;
129130
static double bvec[3];

source/module_hamilt_lcao/hamilt_lcaodft/FORCE_STRESS.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "module_base/timer.h"
99
#include "module_cell/module_neighbor/sltk_grid_driver.h"
1010
#include "module_elecstate/elecstate_lcao.h"
11+
#include "module_elecstate/potentials/H_TDDFT_pw.h" // Taoni add 2025-02-20
1112
#include "module_elecstate/potentials/efield.h" // liuyu add 2022-05-18
1213
#include "module_elecstate/potentials/gatefield.h" // liuyu add 2022-09-13
1314
#include "module_hamilt_general/module_surchem/surchem.h" //sunml add 2022-08-10
@@ -271,10 +272,10 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
271272

272273
//! atomic forces from E-field of rt-TDDFT
273274
ModuleBase::matrix fefield_tddft;
274-
if (PARAM.inp.esolver_type == "TDDFT" && isforce)
275+
if (PARAM.inp.esolver_type == "tddft" && isforce)
275276
{
276277
fefield_tddft.create(nat, 3);
277-
elecstate::Efield::compute_force(ucell, fefield_tddft);
278+
elecstate::H_TDDFT_pw::compute_force(ucell, fefield_tddft);
278279
}
279280

280281
//! atomic forces from gate field
@@ -447,7 +448,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
447448
fcs(iat, i) += fefield(iat, i);
448449
}
449450
// E-field force of tddft
450-
if (PARAM.inp.esolver_type == "TDDFT")
451+
if (PARAM.inp.esolver_type == "tddft")
451452
{
452453
fcs(iat, i) += fefield_tddft(iat, i);
453454
}
@@ -566,7 +567,7 @@ void Force_Stress_LCAO<T>::getForceStress(UnitCell& ucell,
566567
ModuleIO::print_force(GlobalV::ofs_running, ucell, "EFIELD FORCE", fefield, false);
567568
// this->print_force("EFIELD FORCE",fefield,1,ry);
568569
}
569-
if (PARAM.inp.esolver_type == "TDDFT")
570+
if (PARAM.inp.esolver_type == "tddft")
570571
{
571572
ModuleIO::print_force(GlobalV::ofs_running, ucell, "EFIELD_TDDFT FORCE", fefield_tddft, false);
572573
// this->print_force("EFIELD_TDDFT FORCE",fefield_tddft,1,ry);

0 commit comments

Comments
 (0)