Skip to content

Commit 7145d5e

Browse files
committed
fix xc condition and remove DX symmetrization in cal_force
enable PBE0
1 parent 9a70cc9 commit 7145d5e

15 files changed

Lines changed: 123 additions & 25 deletions

source/module_lr/Grad/esolver_lr_grad.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,15 @@ std::vector<ModuleBase::matrix> LR::ESolver_LR<T, TR>::cal_force(const int ispin
147147
// The imag part will be cancelled in the force calculation, so we use double DM(R) to calculate force.
148148
// But complex transition DM(R) is still used in energy density matrix calculation.
149149
const auto& dm_trans_k = cal_dm_trans_pblas(this->X[ispin].template data<T>() + offset, this->paraX_[ispin], c, this->paraC_, this->nbasis, this->nocc[ispin], this->nvirt[ispin], this->paraMat_);
150-
const elecstate::DensityMatrix<T, double>& dm_trans_real = // D(X), double (FIXME: not enough for periodic system!)
150+
auto dm_trans_real = // D(X), double (FIXME: not enough for periodic system!)
151151
LR_Util::build_dm_from_dmk<T, double>(dm_trans_k,
152152
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_);
153-
const elecstate::DensityMatrix<T, T>& dm_trans = // D(X) complex
153+
LR_Util::transpose_DMR(dm_trans_real, this->ucell.nat); //D(X) is not symmetric, need to transpose for the left side of force calculation
154+
auto dm_trans = // D(X) complex
154155
LR_Util::build_dm_from_dmk<T, T>(dm_trans_k,
155156
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_);
157+
LR_Util::transpose_DMR(dm_trans, this->ucell.nat);
156158
// LR_Util::print_DMR(dm_trans, "dm_trans of istate " + std::to_string(istate));
157-
158159
// difference density matrix
159160
std::vector<ct::Tensor> dm_diff_k = cal_dm_diff_pblas(this->X[ispin].template data<T>() + offset, this->paraX_[ispin], c, this->paraC_, this->nbasis, this->nocc[ispin], this->nvirt[ispin], this->paraMat_);
160161
// std::cout << "dm_diff_k T(k) before symmetrization, istate " + std::to_string(istate) << std::endl;
@@ -173,7 +174,7 @@ std::vector<ModuleBase::matrix> LR::ESolver_LR<T, TR>::cal_force(const int ispin
173174
const std::vector<ct::Tensor>& relaxed_diff_dm_k = dm_diff_k + dm_relaxed_k;
174175
const elecstate::DensityMatrix<T, T>& relaxed_diff_dm =
175176
LR_Util::build_dm_from_dmk<T, T>(relaxed_diff_dm_k,
176-
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_, /*symmetrize=*/false);
177+
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_);
177178
// LR_Util::print_DMR(relaxed_diff_dm, "relaxed_diff_dm T+Z (Z symmetrized) of istate " + std::to_string(istate));
178179

179180
// elecstate::DensityMatrix<T, T> relaxed_diff_dm = // T+D(Z), (R) can be complex
@@ -219,7 +220,7 @@ std::vector<ModuleBase::matrix> LR::ESolver_LR<T, TR>::cal_force(const int ispin
219220
test_edm_H2<T>(edm_k[0].data<T>(), this->eig_ks.c, c, this->nbasis);
220221
}
221222
elecstate::DensityMatrix<T, double> edm_real = LR_Util::build_dm_from_dmk<T, double>(edm_k,
222-
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_);
223+
this->paraMat_, this->nk, this->kv.kvec_d, this->ucell, this->gd, this->orb_cutoff_, /*symmetrize=*/true);
223224
// print edm_real (R)
224225
if (PARAM.inp.test_force)
225226
{

source/module_lr/Grad/force/lr_force_test.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
#include "pulay_force_hcontainer.h"
44
#include "module_hamilt_lcao/hamilt_lcaodft/pulay_force_stress.h" // only for gint terms
55
#include "module_lr/utils/lr_util_hcontainer.h"
6+
#include "module_lr/utils/lr_util_print.h"
7+
#ifdef __EXX
8+
#include "module_lr/operator_casida/operator_lr_exx.h"
9+
#endif
610
namespace LR
711
{
812
template<typename TK>
@@ -34,8 +38,7 @@ namespace LR
3438
ModuleBase::matrix f_nonortho = cal_force_overlap_edm(edm_gs); // overlap
3539
this->gint_->reset_DMRGint(1);
3640
#ifdef __EXX
37-
const std::set<std::string> exx_kernel_list = { "hf", "hse" };
38-
if (exx_kernel_list.count(PARAM.inp.dft_functional))
41+
if (exx_kernel_list().find(PARAM.inp.dft_functional) != exx_kernel_list().end())
3942
{
4043
const auto& Ds_gs = LR_Util::get_exx_Ds_gs(dm_gs, ucell_, kv, pv_);
4144
const auto& Ds_gs_2 = LR_Util::get_exx_Ds_gs(dm_gs, ucell_, kv, pv_);

source/module_lr/Grad/multipliers/cal_multiplier_w_from_z.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,12 @@ namespace LR
158158
cal_dm_diff_relaxed(0, X, Z); // relaxed difference density matrix T+DZ
159159
// the 3 terms
160160
op_ht.act(/*nband=*/1, ld_oo, /*npol=*/1, X, W); //comment out this line to test H[T+Z]=0
161-
if (LR::exx_kernel_list().count(xc_kernel))
161+
// std::cout << "W (H[T+Z])) local terms: " << std::endl;
162+
// LR_Util::print_value(W, nk, p_occ_occ[0].get_col_size(), p_occ_occ[0].get_row_size());
163+
if (LR::exx_kernel_list().count(PARAM.inp.dft_functional)) // H[T+Z] term depends on ground-state kernel (dft_functional)
162164
op_ht_exx.act(/*nband=*/1, ld_oo, /*npol=*/1, X, W);
163-
165+
// std::cout << "W (H[T+Z])) local +exx terms: " << std::endl;
166+
// LR_Util::print_value(W, nk, p_occ_occ[0].get_col_size(), p_occ_occ[0].get_row_size());
164167
if (LR_Util::has_local_xc(xc_kernel))
165168
op_gxc.act(/*nband=*/1, ld_oo, /*npol=*/1, X, W);
166169

source/module_lr/esolver_lrtd_lcao.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ template<typename T, typename TR>
8484
void LR::ESolver_LR<T, TR>::parameter_check()const
8585
{
8686
const std::set<std::string> lr_solvers = { "dav", "lapack" , "spectrum", "dav_subspace", "cg" };
87-
const std::set<std::string> xc_kernels = { "rpa", "lda", "pwlda", "pbe", "hf" , "hse" };
87+
const std::set<std::string> xc_kernels = { "rpa", "lda", "pwlda", "pbe", "hf" , "hse", "pbe0" };
8888
if (lr_solvers.find(this->input.lr_solver) == lr_solvers.end())
8989
{
9090
throw std::invalid_argument("ESolver_LR: unknown type of lr_solver");
@@ -255,7 +255,7 @@ LR::ESolver_LR<T, TR>::ESolver_LR(ModuleESolver::ESolver_KS_LCAO<T, TR>&& ks_sol
255255
init_pot(*ks_sol.pelec->charge);
256256

257257
#ifdef __EXX
258-
if (xc_kernel == "hf" || xc_kernel == "hse")
258+
if (exx_kernel_list().find(xc_kernel) != exx_kernel_list().end())
259259
{
260260
// if the same kernel is calculated in the esolver_ks, move it
261261
std::string dft_functional = LR_Util::tolower(input.dft_functional);
@@ -266,10 +266,10 @@ LR::ESolver_LR<T, TR>::ESolver_LR(ModuleESolver::ESolver_KS_LCAO<T, TR>&& ks_sol
266266
} else // construct C, V from scratch
267267
{
268268
// set ccp_type according to the xc_kernel
269-
if (xc_kernel == "hf") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Hf; }
269+
if (xc_kernel == "hf" || xc_kernel == "pbe0") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Hf; }
270270
else if (xc_kernel == "hse") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Erfc; }
271271
this->exx_lri = std::make_shared<Exx_LRI<T>>(exx_info.info_ri);
272-
this->exx_lri->init(MPI_COMM_WORLD, ucell,this->kv, ks_sol.orb_);
272+
this->exx_lri->init(MPI_COMM_WORLD, ucell,this->kv, ks_sol.orb_);
273273
this->exx_lri->cal_exx_ions(ucell,input.out_ri_cv);
274274
}
275275
}
@@ -442,8 +442,8 @@ LR::ESolver_LR<T, TR>::ESolver_LR(const Input_para& inp, UnitCell& ucell) : inpu
442442
// 1. EXX xc_kernel
443443
// 2. cal_force with ground state with EXX functional
444444
#ifdef __EXX
445-
if (((xc_kernel == "hf" || xc_kernel == "hse") && this->input.lr_solver != "spectrum")
446-
|| (PARAM.inp.cal_force && (PARAM.inp.dft_functional == "hf" || PARAM.inp.dft_functional == "hse")))
445+
if (((exx_kernel_list().count(xc_kernel)) && this->input.lr_solver != "spectrum")
446+
|| (PARAM.inp.cal_force && (exx_kernel_list().count(PARAM.inp.dft_functional) )))
447447
{
448448
// set ccp_type according to the xc_kernel
449449
if (xc_kernel == "hf") { exx_info.info_global.ccp_type = Conv_Coulomb_Pot_K::Ccp_Type::Hf; }
@@ -516,6 +516,7 @@ void LR::ESolver_LR<T, TR>::runner(UnitCell& ucell, const int istep)
516516
if (input.lr_solver != "lapack") { pre_op.act(1, nloc_per_band, 1, precondition.data(), precondition.data()); }
517517
// auto spin_types = std::vector<std::string>({ "singlet", "triplet" });
518518
this->spin_types = { "singlet", "triplet" };
519+
// for (int is = 0;is < nspin - 1;++is)
519520
for (int is = 0;is < nspin;++is)
520521
{
521522
std::cout << "Calculating " << spin_types[is] << " excitations" << std::endl;
@@ -605,6 +606,7 @@ void LR::ESolver_LR<T, TR>::after_all_runners(UnitCell& ucell)
605606
double lambda_min = std::min(abs_wavelen_range[1], abs_wavelen_range[0]);
606607
for (int i = 0;i < freq.size();++i) { freq[i] = 91.126664 / (lambda_min + 0.01 * static_cast<double>(i + 1) * lambda_diff); }
607608
// auto spin_types = (nspin == 2 && !openshell) ? std::vector<std::string>({ "singlet", "triplet" }) : std::vector<std::string>({ "updown" });
609+
// for (int is = 0;is < this->X.size() - 1;++is)
608610
for (int is = 0;is < this->X.size();++is)
609611
{
610612
LR_Spectrum<T> spectrum(nspin, this->nbasis, this->nocc, this->nvirt, this->gint_, *this->pw_rho, *this->psi_ks,

source/module_lr/hamilt_casida.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ namespace LR
9999
this->ops->add(lr_hxc);
100100
}
101101
#ifdef __EXX
102-
if (xc_kernel == "hf" || xc_kernel == "hse")
102+
if (exx_kernel_list().find(xc_kernel) != exx_kernel_list().end())
103103
{ //add Exx operator
104104
if (ri_hartree_benchmark != "none" && spin_type == "singlet")
105105
{

source/module_lr/hamilt_ulr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ namespace LR
5656
this->ops[3]->add(newHxc(1, 1));
5757

5858
#ifdef __EXX
59-
if (xc_kernel == "hf" || xc_kernel == "hse")
59+
if (exx_kernel_list().find(xc_kernel) != exx_kernel_list().end())
6060
{
6161
std::vector<psi::Psi<T>> psi_ks_spin = { LR_Util::get_psi_spin(psi_ks_in, 0, nk), LR_Util::get_psi_spin(psi_ks_in, 1, nk) };
6262
for (int is : {0, 1})

source/module_lr/lr_density.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ namespace LR
8585
// 2. calculate DM(R)
8686
elecstate::DensityMatrix<T, T> dm_diff=
8787
LR_Util::build_dm_from_dmk<T, T>(dm_diff_k,
88-
this->pmat_, this->nk_, this->kv_.kvec_d, this->ucell_, this->gd_, this->orb_cutoff_, /*symmetrize=*/false);
88+
this->pmat_, this->nk_, this->kv_.kvec_d, this->ucell_, this->gd_, this->orb_cutoff_);
8989
// 3. calculate electron density from DM(R)
9090
this->dm_to_density(dm_diff, density);
9191
}

source/module_lr/lr_spectrum.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ elecstate::DensityMatrix<T, T> LR::LR_Spectrum<T>::cal_transition_density_matrix
3030
{
3131
LR_Util::initialize_DMR(DM_trans, this->pmat, this->ucell, this->gd_, this->orb_cutoff_);
3232
DM_trans.cal_DMR();
33+
LR_Util::swap_atompair_in_DMR(DM_trans, ucell.nat); // make D(R) consistent with the defination: D(R)[iat1][iat2] = \sum_k c1(k)c2^*(k)exp(-ik(R2-R1))
3334
}
3435
return DM_trans;
3536
}

source/module_lr/operator_casida/operator_lr_exx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "module_lr/Grad/dm_diff/dm_diff.h"
99
namespace LR
1010
{
11-
inline std::set<std::string> exx_kernel_list() { return { "hf", "hse" }; };
11+
inline std::set<std::string> exx_kernel_list() { return { "hf", "hse", "pbe0" }; };
1212
template<typename T = double>
1313
class OperatorLREXX : public hamilt::Operator<T, base_device::DEVICE_CPU>
1414
{

source/module_lr/operator_casida/operator_lr_hxc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace LR
2626
const int& lgd = gint->gridt->lgd;
2727

2828
this->DM_trans.cal_DMR(); //DM_trans.get_DMR_vector() is 2d-block parallized
29+
LR_Util::swap_atompair_in_DMR(this->DM_trans, ucell.nat); // make D(R) consistent with the defination: D(R)[iat1][iat2] = \sum_k c1(k)c2^*(k)exp(-ik(R2-R1))
2930
// LR_Util::print_DMR(DM_trans, ucell.nat, "DMR");
3031

3132
// ========================= begin grid calculation=========================

0 commit comments

Comments
 (0)