Skip to content

Commit 0cdab49

Browse files
authored
Feature: LR-TDDFT absorption spectrum in velocity gauge (#5760)
* calculate absorption spectrum by velocity matrix * add parameter abs_gauge * refactor transition density matrix in lr_spectrum * refactor oscillator_strength and dipole in lr_spectrum * refactor and add some test functions * fix the bug at ks-lr * contract v(k) with D(k) * fix: recover Nk divided in cal_dm_trans * fix the spectra strength of singlet * update examples * fix after rebase
1 parent 28cb769 commit 0cdab49

File tree

15 files changed

+526
-205
lines changed

15 files changed

+526
-205
lines changed

examples/lr-tddft/lcao_H2O/INPUT

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ orbital_dir ../../../tests/PP_ORB
66
calculation scf
77
nbands 23
88
symmetry -1
9+
nspin 2
910

1011
#Parameters (2.Iteration)
1112
ecutwfc 60 ###Energy cutoff needs to be tested to ensure your calculation is reliable.[1]
@@ -30,6 +31,7 @@ xc_kernel lda
3031
lr_solver dav
3132
lr_thr 1e-2
3233
pw_diag_ndim 2
34+
# lr_unrestricted 1 ### use this to do TDUKS calculation for closeshell systems (openshell system will force TDUKS)
3335

3436
esolver_type ks-lr
3537
out_alllog 1
@@ -39,6 +41,7 @@ out_alllog 1
3941
nvirt 19
4042
abs_wavelen_range 40 180
4143
abs_broadening 0.01
44+
abs_gauge length
4245

4346
### [1] Energy cutoff determines the quality of numerical quadratures in your calculations.
4447
### So it is strongly recommended to test whether your result (such as converged SCF energies) is

examples/lr-tddft/lcao_Si2/INPUT

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ pseudo_dir ../../../tests/PP_ORB
55
orbital_dir ../../../tests/PP_ORB
66
calculation scf
77
nbands 23
8-
symmetry 0
8+
symmetry -1
9+
nspin 2
910

1011
#Parameters (2.Iteration)
1112
ecutwfc 60 ###Energy cutoff needs to be tested to ensure your calculation is reliable.[1]
@@ -37,6 +38,8 @@ out_alllog 1
3738

3839
nvirt 19
3940
abs_wavelen_range 100 175
41+
abs_broadening 0.01 # in Ry
42+
abs_gauge velocity ### velocity gauge is recommended for periodic systems
4043

4144

4245
### [1] Energy cutoff determines the quality of numerical quadratures in your calculations.

source/Makefile.Objects

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ OBJS_TENSOR=tensor.o\
731731
xc_kernel.o\
732732
pot_hxc_lrtd.o\
733733
lr_spectrum.o\
734+
lr_spectrum_velocity.o\
734735
hamilt_casida.o\
735736
esolver_lrtd_lcao.o\
736737

source/module_basis/module_nao/two_center_bundle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class TwoCenterBundle
1212
public:
1313
TwoCenterBundle() = default;
1414
~TwoCenterBundle() = default;
15+
TwoCenterBundle& operator=(TwoCenterBundle&&) = default;
1516

1617
// NOTE: some variables might be set only on RANK-0
1718
void build_orb(int ntype, const std::string* file_orb0);

source/module_io/read_input_item_tddft.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,12 @@ void ReadInput::item_lr_tddft()
360360
sync_doublevec(input.abs_wavelen_range, 2, 0.0);
361361
this->add_item(item);
362362
}
363+
{
364+
Input_Item item("abs_gauge");
365+
item.annotation = "whether to use length or velocity gauge to calculate the absorption spectrum in LR-TDDFT";
366+
read_sync_string(input.abs_gauge);
367+
this->add_item(item);
368+
}
363369
{
364370
Input_Item item("abs_broadening");
365371
item.annotation = "the broadening (eta) for LR-TDDFT absorption spectrum";

source/module_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ TEST_F(InputParaTest, ParaRead)
431431
EXPECT_EQ(param.inp.abs_wavelen_range.size(), 2);
432432
EXPECT_DOUBLE_EQ(param.inp.abs_wavelen_range[0], 0.0);
433433
EXPECT_DOUBLE_EQ(param.inp.abs_broadening, 0.01);
434+
EXPECT_EQ(param.inp.abs_gauge, "length");
434435
EXPECT_EQ(param.inp.rdmft, 0);
435436
EXPECT_DOUBLE_EQ(param.inp.rdmft_power_alpha, 0.656);
436437
}

source/module_lr/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ if(ENABLE_LCAO)
1616
operator_casida/operator_lr_exx.cpp
1717
potentials/pot_hxc_lrtd.cpp
1818
lr_spectrum.cpp
19+
lr_spectrum_velocity.cpp
1920
hamilt_casida.cpp
2021
esolver_lrtd_lcao.cpp
2122
potentials/xc_kernel.cpp)

source/module_lr/esolver_lrtd_lcao.cpp

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ inline int cal_nupdown_form_occ(const ModuleBase::matrix& wg)
6262
return nupdown;
6363
}
6464

65+
inline void setup_2center_table(TwoCenterBundle& two_center_bundle, LCAO_Orbitals& orb, UnitCell& ucell)
66+
{
67+
// set up 2-center table
68+
#ifdef USE_NEW_TWO_CENTER
69+
two_center_bundle.tabulate();
70+
#else
71+
two_center_bundle.tabulate(inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax);
72+
#endif
73+
if (PARAM.inp.vnl_in_h)
74+
{
75+
ucell.infoNL.setupNonlocal(ucell.ntype, ucell.atoms, GlobalV::ofs_running, orb);
76+
two_center_bundle.build_beta(ucell.ntype, ucell.infoNL.Beta);
77+
}
78+
}
79+
6580
template<typename T, typename TR>
6681
void LR::ESolver_LR<T, TR>::parameter_check()const
6782
{
@@ -149,8 +164,7 @@ LR::ESolver_LR<T, TR>::ESolver_LR(ModuleESolver::ESolver_KS_LCAO<T, TR>&& ks_sol
149164
this->gd = std::move(ks_sol.gd);
150165

151166
// xc kernel
152-
this->xc_kernel = inp.xc_kernel;
153-
std::transform(xc_kernel.begin(), xc_kernel.end(), xc_kernel.begin(), tolower);
167+
this->xc_kernel = LR_Util::tolower(inp.xc_kernel);
154168
//kv
155169
this->kv = std::move(ks_sol.kv);
156170

@@ -218,8 +232,7 @@ LR::ESolver_LR<T, TR>::ESolver_LR(ModuleESolver::ESolver_KS_LCAO<T, TR>&& ks_sol
218232
if (xc_kernel == "hf" || xc_kernel == "hse")
219233
{
220234
// if the same kernel is calculated in the esolver_ks, move it
221-
std::string dft_functional = input.dft_functional;
222-
std::transform(dft_functional.begin(), dft_functional.end(), dft_functional.begin(), tolower);
235+
std::string dft_functional = LR_Util::tolower(input.dft_functional);
223236
if (ks_sol.exx_lri_double && std::is_same<T, double>::value && xc_kernel == dft_functional) {
224237
this->move_exx_lri(ks_sol.exx_lri_double);
225238
} else if (ks_sol.exx_lri_complex && std::is_same<T, std::complex<double>>::value && xc_kernel == dft_functional) {
@@ -237,6 +250,10 @@ LR::ESolver_LR<T, TR>::ESolver_LR(ModuleESolver::ESolver_KS_LCAO<T, TR>&& ks_sol
237250
#endif
238251
this->pelec = new elecstate::ElecStateLCAO<T>();
239252
orb_cutoff_ = ks_sol.orb_.cutoffs();
253+
if (LR_Util::tolower(input.abs_gauge) == "velocity")
254+
{
255+
this->two_center_bundle_ = std::move(ks_sol.two_center_bundle_);
256+
}
240257
}
241258

242259
template <typename T, typename TR>
@@ -247,8 +264,7 @@ LR::ESolver_LR<T, TR>::ESolver_LR(const Input_para& inp, UnitCell& ucell) : inpu
247264
{
248265
ModuleBase::TITLE("ESolver_LR", "ESolver_LR(from scratch)");
249266
// xc kernel
250-
this->xc_kernel = inp.xc_kernel;
251-
std::transform(xc_kernel.begin(), xc_kernel.end(), xc_kernel.begin(), tolower);
267+
this->xc_kernel = LR_Util::tolower(inp.xc_kernel);
252268

253269
// necessary steps in ESolver_FP
254270
ESolver_FP::before_all_runners(ucell, inp);
@@ -272,6 +288,10 @@ LR::ESolver_LR<T, TR>::ESolver_LR(const Input_para& inp, UnitCell& ucell) : inpu
272288
LCAO_Orbitals orb;
273289
two_center_bundle_.to_LCAO_Orbitals(orb, inp.lcao_ecut, inp.lcao_dk, inp.lcao_dr, inp.lcao_rmax);
274290
orb_cutoff_ = orb.cutoffs();
291+
if (LR_Util::tolower(input.abs_gauge) == "velocity")
292+
{
293+
setup_2center_table(this->two_center_bundle_, orb, ucell);
294+
}
275295

276296
this->set_dimension();
277297
// setup 2d-block distribution for AO-matrix and KS wfc
@@ -320,7 +340,6 @@ LR::ESolver_LR<T, TR>::ESolver_LR(const Input_para& inp, UnitCell& ucell) : inpu
320340
this->init_pot(chg_gs);
321341

322342
// search adjacent atoms and init Gint
323-
std::cout << "ucell.infoNL.get_rcutmax_Beta(): " << ucell.infoNL.get_rcutmax_Beta() << std::endl;
324343
double search_radius = -1.0;
325344
search_radius = atom_arrange::set_sr_NL(GlobalV::ofs_running,
326345
PARAM.inp.out_level,
@@ -539,26 +558,21 @@ void LR::ESolver_LR<T, TR>::after_all_runners(UnitCell& ucell)
539558
auto spin_types = (nspin == 2 && !openshell) ? std::vector<std::string>({ "singlet", "triplet" }) : std::vector<std::string>({ "updown" });
540559
for (int is = 0;is < this->X.size();++is)
541560
{
542-
LR_Spectrum<T> spectrum(nspin,
543-
this->nbasis,
544-
this->nocc,
545-
this->nvirt,
546-
this->gint_,
547-
*this->pw_rho,
548-
*this->psi_ks,
549-
this->ucell,
550-
this->kv,
551-
this->gd,
552-
this->orb_cutoff_,
553-
this->paraX_,
554-
this->paraC_,
555-
this->paraMat_,
556-
&this->pelec->ekb.c[is * nstates],
557-
this->X[is].template data<T>(),
558-
nstates,
559-
openshell);
561+
LR_Spectrum<T> spectrum(nspin, this->nbasis, this->nocc, this->nvirt, this->gint_, *this->pw_rho, *this->psi_ks,
562+
this->ucell, this->kv, this->gd, this->orb_cutoff_, this->two_center_bundle_,
563+
this->paraX_, this->paraC_, this->paraMat_,
564+
&this->pelec->ekb.c[is * nstates], this->X[is].template data<T>(), nstates, openshell,
565+
LR_Util::tolower(input.abs_gauge));
560566
spectrum.transition_analysis(spin_types[is]);
561-
spectrum.optical_absorption(freq, input.abs_broadening, spin_types[is]);
567+
if (spin_types[is] != "triplet") // triplets has no transition dipole and no contribution to the spectrum
568+
{
569+
spectrum.optical_absorption_method1(freq, input.abs_broadening);
570+
// =============================================== for test ====================================================
571+
// spectrum.optical_absorption_method2(freq, input.abs_broadening, spin_types[is]);
572+
// spectrum.test_transition_dipoles_velocity_ks(eig_ks.c);
573+
// spectrum.write_transition_dipole(PARAM.globalv.global_out_dir + "dipole_velocity_ks.dat");
574+
// =============================================== for test ====================================================
575+
}
562576
}
563577
}
564578

0 commit comments

Comments
 (0)