Skip to content

Commit cd76ed0

Browse files
committed
read fxc or charge for fxc from file
1 parent 6cdb848 commit cd76ed0

File tree

10 files changed

+94
-43
lines changed

10 files changed

+94
-43
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,6 +3921,15 @@ These parameters are used to solve the excited states using. e.g. LR-TDDFT.
39213921
Currently supported: `RPA`, `LDA`, `PBE`, `HSE`, `HF`.
39223922
- **Default**: LDA
39233923

3924+
### init_fxc
3925+
3926+
- **Type**: String
3927+
- **Description**: The method to initalize the xc kernel.
3928+
- "gs": Calculate fxc from the ground-state charge density.
3929+
- "file_fxc": Read the xc kernel $f_\text{xc}$ on grid from the provided files. The following worlds should be the paths of ".cube" files, where the first 3 (spin-aa, spin-ab and spin-bb) will be read in. The parameter [xc_kernel](#xc_kernel) will be invalid. Now only LDA-type kernel is supproted as the potential will be calculated by directly multiplying the transition density.
3930+
- "file_chg": Calculate fxc from the charge density read from the provided files. The following words should be the paths of ".cube" files, where the first [nspin]($nspin) files will be read in.
3931+
- **Default**: "gs"
3932+
39243933
### lr_solver
39253934

39263935
- **Type**: String

source/module_io/read_input_item_tddft.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,20 @@ void ReadInput::item_lr_tddft()
309309
read_sync_string(input.xc_kernel);
310310
this->add_item(item);
311311
}
312+
{
313+
Input_Item item("init_fxc");
314+
item.annotation = "The method to initalize the xc kernel";
315+
item.read_value = [](const Input_Item& item, Parameter& para) {
316+
size_t count = item.get_size();
317+
auto& ifxc = para.input.init_fxc;
318+
for (int i = 0; i < count; i++) { ifxc.push_back(item.str_values[i]); }
319+
};
320+
item.reset_value = [](const Input_Item& item, Parameter& para) {
321+
if (para.input.init_fxc.empty()) { para.input.init_fxc.push_back("gs"); }
322+
};
323+
sync_stringvec(input.init_fxc, para.input.init_fxc.size(), "gs");
324+
this->add_item(item);
325+
}
312326
{
313327
Input_Item item("lr_solver");
314328
item.annotation = "the eigensolver for LR-TDDFT";

source/module_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ TEST_F(InputParaTest, ParaRead)
417417
EXPECT_EQ(param.inp.nocc, param.inp.nbands);
418418
EXPECT_EQ(param.inp.nvirt, 1);
419419
EXPECT_EQ(param.inp.xc_kernel, "LDA");
420+
EXPECT_EQ(param.inp.init_fxc[0], "gs");
420421
EXPECT_EQ(param.inp.lr_solver, "dav");
421422
EXPECT_DOUBLE_EQ(param.inp.lr_thr, 1e-2);
422423
EXPECT_FALSE(param.inp.lr_unrestricted);

source/module_lr/esolver_lrtd_lcao.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,11 @@ void LR::ESolver_LR<T, TR>::init_pot(const Charge& chg_gs)
603603
{
604604
using ST = PotHxcLR::SpinType;
605605
case 1:
606-
this->pot[0] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, ST::S1);
606+
this->pot[0] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, GlobalC::Pgrid, ST::S1, input.init_fxc);
607607
break;
608608
case 2:
609-
this->pot[0] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, openshell ? ST::S2_updown : ST::S2_singlet);
610-
this->pot[1] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, openshell ? ST::S2_updown : ST::S2_triplet);
609+
this->pot[0] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, GlobalC::Pgrid, openshell ? ST::S2_updown : ST::S2_singlet, input.init_fxc);
610+
this->pot[1] = std::make_shared<PotHxcLR>(xc_kernel, this->pw_rho, &ucell, &chg_gs, GlobalC::Pgrid, openshell ? ST::S2_updown : ST::S2_triplet, input.init_fxc);
611611
break;
612612
default:
613613
throw std::invalid_argument("ESolver_LR: nspin must be 1 or 2");

source/module_lr/potentials/kernel.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
#pragma once
22
#include "module_basis/module_pw/pw_basis.h"
3-
#include "module_elecstate/module_charge/charge.h"
4-
#include "module_cell/unitcell.h"
5-
// #include <ATen/tensor.h>
63

74
namespace LR
85
{
96
class KernelXC
107
{
118
public:
12-
KernelXC() {};
9+
KernelXC(const ModulePW::PW_Basis& rho_basis) : rho_basis_(rho_basis) {};
1310
~KernelXC() {};
1411

1512
// xc kernel for LR-TDDFT
1613
#ifdef USE_LIBXC
17-
void f_xc_libxc(const int& nspin, const double& omega, const double& tpiba, const Charge* chg_gs);
14+
void f_xc_libxc(const int& nspin, const double& omega, const double& tpiba, const double* const* const rho_gs, const double* const rho_core = nullptr);
1815
#endif
1916

17+
void set_kernel(const std::string& name, const std::vector<double>& vec) { this->kernel_set_[name] = vec; }
18+
void set_kernel(const std::string& name, const std::vector<double>&& vec) { this->kernel_set_[name] = std::move(vec); }
2019
const std::vector<double>& get_kernel(const std::string& name) { return kernel_set_[name]; }
2120
const std::vector<ModuleBase::Vector3<double>>& get_grad_kernel(const std::string& name) { return grad_kernel_set_[name]; }
2221

2322
protected:
2423

25-
const ModulePW::PW_Basis* rho_basis_ = nullptr;
24+
const ModulePW::PW_Basis& rho_basis_;
2625
std::map<std::string, std::vector<double>> kernel_set_; // [kernel_type][nrxx][nspin]
2726
std::map<std::string, std::vector<ModuleBase::Vector3<double>>> grad_kernel_set_;// [kernel_type][nrxx][nspin], intermediate terms for GGA
2827
};

source/module_lr/potentials/kernel_xc.cpp

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,31 @@
77
#include <xc.h>
88
#include "module_hamilt_general/module_xc/xc_functional_libxc.h"
99

10-
void LR::KernelXC::f_xc_libxc(const int& nspin, const double& omega, const double& tpiba, const Charge* chg_gs)
10+
void LR::KernelXC::f_xc_libxc(const int& nspin, const double& omega, const double& tpiba, const double* const* const rho_gs, const double* const rho_core)
1111
{
1212
ModuleBase::TITLE("XC_Functional", "f_xc_libxc");
1313
ModuleBase::timer::tick("XC_Functional", "f_xc_libxc");
1414
// https://www.tddft.org/programs/libxc/manual/libxc-5.1.x/
1515

16+
assert(nspin == 1 || nspin == 2);
17+
1618
std::vector<xc_func_type> funcs = XC_Functional_Libxc::init_func(
1719
XC_Functional::get_func_id(),
1820
(1 == nspin) ? XC_UNPOLARIZED : XC_POLARIZED);
19-
int nrxx = chg_gs->nrxx;
21+
const int& nrxx = rho_basis_.nrxx;
2022

2123
// converting rho (extract it as a subfuntion in the future)
2224
// -----------------------------------------------------------------------------------
2325
std::vector<double> rho(nspin * nrxx); // r major / spin contigous
24-
std::vector<double> amag;
25-
if (1 == nspin || 2 == nspin)
26-
{
26+
2727
#ifdef _OPENMP
2828
#pragma omp parallel for collapse(2) schedule(static, 1024)
2929
#endif
30-
for (int is = 0; is < nspin; ++is)
31-
for (int ir = 0; ir < nrxx; ++ir)
32-
rho[ir * nspin + is] = chg_gs->rho[is][ir] + 1.0 / nspin * chg_gs->rho_core[ir];
33-
}
34-
else
30+
for (int is = 0; is < nspin; ++is) { for (int ir = 0; ir < nrxx; ++ir) { rho[ir * nspin + is] = rho_gs[is][ir]; } }
31+
if (rho_core)
3532
{
36-
amag.resize(nrxx);
37-
#ifdef _OPENMP
38-
#pragma omp parallel for
39-
#endif
40-
for (int ir = 0; ir < nrxx; ++ir)
41-
{
42-
const double arhox = std::abs(chg_gs->rho[0][ir] + chg_gs->rho_core[ir]);
43-
amag[ir] = std::sqrt(std::pow(chg_gs->rho[1][ir], 2) + std::pow(chg_gs->rho[2][ir], 2) + std::pow(chg_gs->rho[3][ir], 2));
44-
const double amag_clip = (amag[ir] < arhox) ? amag[ir] : arhox;
45-
rho[ir * nspin + 0] = (arhox + amag_clip) / 2.0;
46-
rho[ir * nspin + 1] = (arhox - amag_clip) / 2.0;
47-
}
33+
const double fac = 1.0 / nspin;
34+
for (int is = 0; is < nspin; ++is) { for (int ir = 0; ir < nrxx; ++ir) { rho[ir * nspin + is] += fac * rho_core[ir]; } }
4835
}
4936

5037
// -----------------------------------------------------------------------------------
@@ -81,7 +68,7 @@ void LR::KernelXC::f_xc_libxc(const int& nspin, const double& omega, const doubl
8168
#endif
8269
for (int ir = 0; ir < nrxx; ++ir) rhor[ir] = rho[ir * nspin + is];
8370
gdr[is].resize(nrxx);
84-
LR_Util::grad(rhor.data(), gdr[is].data(), *(chg_gs->rhopw), tpiba);
71+
LR_Util::grad(rhor.data(), gdr[is].data(), rho_basis_, tpiba);
8572
}
8673
// 2. |\nabla\rho|^2
8774
sigma.resize(nrxx * ((1 == nspin) ? 1 : 3));

source/module_lr/potentials/pot_hxc_lrtd.cpp

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,69 @@
66
#include "module_hamilt_general/module_xc/xc_functional.h"
77
#include <set>
88
#include "module_lr/utils/lr_util.h"
9-
9+
#include "module_io/cube_io.h"
10+
#include "module_hamilt_pw/hamilt_pwdft/global.h" // tmp, for pgrid
1011
#define FXC_PARA_TYPE const double* const rho, ModuleBase::matrix& v_eff, const std::vector<int>& ispin_op = { 0,0 }
1112
namespace LR
1213
{
1314
// constructor for exchange-correlation kernel
1415
PotHxcLR::PotHxcLR(const std::string& xc_kernel_in, const ModulePW::PW_Basis* rho_basis_in, const UnitCell* ucell_in,
15-
const Charge* chg_gs/*ground state*/, const SpinType& st_in)
16-
:xc_kernel(xc_kernel_in), tpiba_(ucell_in->tpiba), spin_type_(st_in)
16+
const Charge* chg_gs/*ground state*/, const Parallel_Grid& pgrid,
17+
const SpinType& st_in, const std::vector<std::string>& init_fxc)
18+
:xc_kernel(xc_kernel_in), tpiba_(ucell_in->tpiba), spin_type_(st_in),
19+
xc_kernel_components_(*rho_basis_in)
1720
{
1821
this->rho_basis_ = rho_basis_in;
1922
this->nrxx = chg_gs->nrxx;
2023
this->nspin = (PARAM.inp.nspin == 1 || (PARAM.inp.nspin == 4 && !PARAM.globalv.domag && !PARAM.globalv.domag_z)) ? 1 : 2;
2124

2225
this->pot_hartree = LR_Util::make_unique<elecstate::PotHartree>(this->rho_basis_);
26+
2327
std::set<std::string> local_xc = { "lda", "pbe", "hse" };
2428
if (local_xc.find(this->xc_kernel) != local_xc.end())
2529
{
2630
XC_Functional::set_xc_type(this->xc_kernel); // for hse, (1-alpha) and omega are set here
2731
this->xc_type_ = XCType(XC_Functional::get_func_type());
28-
#ifdef USE_LIBXC
2932
this->set_integral_func(this->spin_type_, this->xc_type_);
30-
this->xc_kernel_components_.f_xc_libxc(nspin, ucell_in->omega, ucell_in->tpiba, chg_gs);
33+
34+
if (init_fxc[0] == "file_fxc")
35+
{
36+
assert(this->xc_kernel == "lda");
37+
const int spinsize = (1 == nspin) ? 1 : 3;
38+
std::vector<double> v2rho2(spinsize * nrxx);
39+
// read fxc adn add to xc_kernel_components
40+
assert(init_fxc.size() >= spinsize + 1);
41+
for (int is = 0;is < spinsize;++is)
42+
{
43+
double ef = 0.0;
44+
int prenspin = 1;
45+
std::vector<double> v2rho2_tmp(nrxx);
46+
ModuleIO::read_vdata_palgrid(GlobalC::Pgrid, GlobalV::MY_RANK, GlobalV::ofs_running, init_fxc[is + 1],
47+
v2rho2_tmp.data(), ucell_in->nat);
48+
for (int ir = 0;ir < nrxx;++ir) { v2rho2[ir * spinsize + is] = v2rho2_tmp[ir]; }
49+
}
50+
this->xc_kernel_components_.set_kernel("v2rho2", std::move(v2rho2));
51+
return;
52+
}
53+
54+
#ifdef USE_LIBXC
55+
if (init_fxc[0] == "file_chg")
56+
{
57+
assert(init_fxc.size() >= 2);
58+
double** rho_for_fxc;
59+
LR_Util::new_p2(rho_for_fxc, nspin, nrxx);
60+
double ef = 0.0;
61+
int prenspin = 1;
62+
for (int is = 0;is < nspin;++is)
63+
{
64+
const std::string file = init_fxc[init_fxc.size() > nspin ? 1 + is : 1];
65+
ModuleIO::read_vdata_palgrid(pgrid, GlobalV::MY_RANK, GlobalV::ofs_running, file,
66+
rho_for_fxc[is], ucell_in->nat);
67+
}
68+
this->xc_kernel_components_.f_xc_libxc(nspin, ucell_in->omega, ucell_in->tpiba, rho_for_fxc, chg_gs->rho_core);
69+
LR_Util::delete_p2(rho_for_fxc, nspin);
70+
}
71+
else { this->xc_kernel_components_.f_xc_libxc(nspin, ucell_in->omega, ucell_in->tpiba, chg_gs->rho, chg_gs->rho_core); }
3172
#else
3273
ModuleBase::WARNING_QUIT("KernelXC", "to calculate xc-kernel in LR-TDDFT, compile with LIBXC");
3374
#endif
@@ -63,7 +104,6 @@ namespace LR
63104
ModuleBase::timer::tick("PotHxcLR", "cal_v_eff");
64105
}
65106

66-
#ifdef USE_LIBXC
67107
void PotHxcLR::set_integral_func(const SpinType& s, const XCType& xc)
68108
{
69109
auto& funcs = this->kernel_to_potential_;
@@ -168,5 +208,4 @@ namespace LR
168208
+ " unfinished in " + std::string(__FILE__) + " line " + std::to_string(__LINE__));
169209
}
170210
}
171-
#endif
172211
} // namespace LR

source/module_lr/potentials/pot_hxc_lrtd.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "kernel.h"
55
#include <unordered_map>
66
#include <memory>
7+
8+
class Parallel_Grid;
79
namespace LR
810
{
911
class PotHxcLR : public elecstate::PotBase
@@ -15,8 +17,9 @@ namespace LR
1517
enum SpinType { S1 = 0, S2_singlet = 1, S2_triplet = 2, S2_updown = 3 };
1618
enum XCType { None = 0, LDA = 1, GGA = 2, HYB_GGA = 4 };
1719
/// constructor for exchange-correlation kernel
18-
PotHxcLR(const std::string& xc_kernel_in, const ModulePW::PW_Basis* rho_basis_in, const UnitCell* ucell_in, const Charge* chg_gs/*ground state*/,
19-
const SpinType& st_in = SpinType::S1);
20+
PotHxcLR(const std::string& xc_kernel_in, const ModulePW::PW_Basis* rho_basis_in,
21+
const UnitCell* ucell_in, const Charge* chg_gs/*ground state*/, const Parallel_Grid& pgrid,
22+
const SpinType& st_in = SpinType::S1, const std::vector<std::string>& init_fxc = { "gs" });
2023
~PotHxcLR() {}
2124
void cal_v_eff(const Charge* chg/*excited state*/, const UnitCell* ucell, ModuleBase::matrix& v_eff) override {};
2225
void cal_v_eff(double** rho, const UnitCell* ucell, ModuleBase::matrix& v_eff, const std::vector<int>& ispin_op = { 0,0 });

source/module_lr/utils/lr_util.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ namespace LR_Util
270270
vl.data(), &ldvl, vr.data(), &ldvr, work2.data(), &lwork, rwork.data(), &info);
271271
if (info) { std::cout << "ERROR: Lapack solver zgeev, info=" << info << std::endl; }
272272
}
273-
#ifdef USE_LIBXC
274273
void grad(const double* rhor,
275274
ModuleBase::Vector3<double>* gdr,
276275
const ModulePW::PW_Basis& rho_basis,
@@ -299,5 +298,4 @@ namespace LR_Util
299298
}
300299
}
301300
}
302-
#endif
303301
}

source/module_parameter/input_parameter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ struct Input_para
296296

297297
// ============== #Parameters (10.lr-tddft) ===========================
298298
int lr_nstates = 1; ///< the number of 2-particle states to be solved
299+
std::vector<std::string> init_fxc = {}; ///< The method to initalize the xc kernel
299300
int nocc = -1; ///< the number of occupied orbitals to form the 2-particle basis
300301
int nvirt = 1; ///< the number of virtual orbitals to form the 2-particle basis (nocc + nvirt <= nbands)
301302
std::string xc_kernel = "LDA"; ///< exchange correlation (XC) kernel for LR-TDDFT

0 commit comments

Comments
 (0)