Skip to content

Commit 2e13f9f

Browse files
authored
Feature: write Vxc(R) (#6061)
* fix the R range of data-HR * feature: write Vxc(R) * add parameter out_mat_xc2 and update tests * fix compile
1 parent cdc88cf commit 2e13f9f

File tree

16 files changed

+350
-50
lines changed

16 files changed

+350
-50
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
- [out\_mat\_t](#out_mat_t)
154154
- [out\_mat\_dh](#out_mat_dh)
155155
- [out\_mat\_xc](#out_mat_xc)
156+
- [out\_mat\_xc2](#out_mat_xc2)
156157
- [out\_eband\_terms](#out_eband_terms)
157158
- [out\_hr\_npz/out\_dm\_npz](#out_hr_npzout_dm_npz)
158159
- [dm\_to\_rho](#dm_to_rho)
@@ -1799,6 +1800,13 @@ These variables are used to control the output of properties.
17991800
The band (KS orbital) energy for each (k-point, spin, band) will be printed in the file `OUT.${suffix}/vxc_out.dat`. If EXX is calculated, the local and EXX part of band energy will also be printed in `OUT.${suffix}/vxc_local_out.dat`and `OUT.${suffix}/vxc_exx_out.dat`, respectively. All the `vxc*_out.dat` files contains 3 integers (nk, nspin, nband) followed by nk\*nspin\*nband lines of energy Hartree and eV.
18001801
- **Default**: False
18011802

1803+
### out_mat_xc2
1804+
1805+
- **Type**: Boolean
1806+
- **Availability**: Numerical atomic orbital (NAO) basis
1807+
- **Description**: Whether to print the exchange-correlation matrices in **numerical orbital representation** (unit: Ry): $\braket{\phi_i|V_\text{xc}^\text{(semi-)local}+V_\text{exx}+V_\text{DFTU}|\phi_j}(\mathbf{R})$ in CSR format (the same format as [out_mat_hs2](../elec_properties/hs_matrix.md#out_mat_hs2)) in the directory `OUT.${suffix}`. (Note that currently DeePKS term is not included. ) The files are named `Vxc_R_spin$s`.
1808+
- **Default**: False
1809+
18021810
### out_eband_terms
18031811

18041812
- **Type**: Boolean

source/module_esolver/esolver_ks_lcao.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
//be careful of hpp, there may be multiple definitions of functions, 20250302, mohan
3434
#include "module_io/write_eband_terms.hpp"
3535
#include "module_io/write_vxc.hpp"
36+
#include "module_io/write_vxc_r.hpp"
3637
#include "module_hamilt_lcao/hamilt_lcaodft/hs_matrix_k.hpp"
3738

3839
//--------------temporary----------------------------
@@ -488,27 +489,49 @@ void ESolver_KS_LCAO<TK, TR>::after_all_runners(UnitCell& ucell)
488489
if (PARAM.inp.out_mat_xc)
489490
{
490491
ModuleIO::write_Vxc<TK, TR>(PARAM.inp.nspin,
491-
PARAM.globalv.nlocal,
492-
GlobalV::DRANK,
493-
&this->pv,
494-
*this->psi,
495-
ucell,
496-
this->sf,
497-
this->solvent,
498-
*this->pw_rho,
499-
*this->pw_rhod,
500-
this->locpp.vloc,
501-
this->chr,
502-
this->GG,
503-
this->GK,
504-
this->kv,
505-
orb_.cutoffs(),
506-
this->pelec->wg,
507-
this->gd
492+
PARAM.globalv.nlocal,
493+
GlobalV::DRANK,
494+
&this->pv,
495+
*this->psi,
496+
ucell,
497+
this->sf,
498+
this->solvent,
499+
*this->pw_rho,
500+
*this->pw_rhod,
501+
this->locpp.vloc,
502+
this->chr,
503+
this->GG,
504+
this->GK,
505+
this->kv,
506+
orb_.cutoffs(),
507+
this->pelec->wg,
508+
this->gd
508509
#ifdef __EXX
509-
,
510-
this->exx_lri_double ? &this->exx_lri_double->Hexxs : nullptr,
511-
this->exx_lri_complex ? &this->exx_lri_complex->Hexxs : nullptr
510+
,
511+
this->exx_lri_double ? &this->exx_lri_double->Hexxs : nullptr,
512+
this->exx_lri_complex ? &this->exx_lri_complex->Hexxs : nullptr
513+
#endif
514+
);
515+
}
516+
if (PARAM.inp.out_mat_xc2)
517+
{
518+
ModuleIO::write_Vxc_R<TK, TR>(PARAM.inp.nspin,
519+
&this->pv,
520+
ucell,
521+
this->sf,
522+
this->solvent,
523+
*this->pw_rho,
524+
*this->pw_rhod,
525+
this->locpp.vloc,
526+
this->chr,
527+
this->GG,
528+
this->GK,
529+
this->kv,
530+
orb_.cutoffs(),
531+
this->gd
532+
#ifdef __EXX
533+
, this->exx_lri_double ? &this->exx_lri_double->Hexxs : nullptr,
534+
this->exx_lri_complex ? &this->exx_lri_complex->Hexxs : nullptr
512535
#endif
513536
);
514537
}

source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/op_exx_lcao.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44

55
namespace hamilt
66
{
7+
RI::Cell_Nearest<int, int, 3, double, 3> init_cell_nearest(const UnitCell& ucell, const std::array<int, 3>& Rs_period)
8+
{
9+
RI::Cell_Nearest<int, int, 3, double, 3> cell_nearest;
10+
std::map<int, std::array<double, 3>> atoms_pos;
11+
for (int iat = 0; iat < ucell.nat; ++iat) {
12+
atoms_pos[iat] = RI_Util::Vector3_to_array3(
13+
ucell.atoms[ucell.iat2it[iat]]
14+
.tau[ucell.iat2ia[iat]]);
15+
}
16+
const std::array<std::array<double, 3>, 3> latvec
17+
= { RI_Util::Vector3_to_array3(ucell.a1),
18+
RI_Util::Vector3_to_array3(ucell.a2),
19+
RI_Util::Vector3_to_array3(ucell.a3) };
20+
cell_nearest.init(atoms_pos, latvec, Rs_period);
21+
return cell_nearest;
22+
}
723

824
template<>
925
void OperatorEXX<OperatorLCAO<double, double>>::add_loaded_Hexx(const int ik)

source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/op_exx_lcao.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,22 @@ class OperatorEXX<OperatorLCAO<TK, TR>> : public OperatorLCAO<TK, TR>
7373
std::vector<std::vector<std::complex<double>>> Hexxc_k_load;
7474
};
7575

76+
using TAC = std::pair<int, std::array<int, 3>>;
77+
78+
RI::Cell_Nearest<int, int, 3, double, 3> init_cell_nearest(const UnitCell& ucell, const std::array<int, 3>& Rs_period);
79+
80+
// allocate according to the read-in HexxR, used in nscf
81+
template <typename Tdata, typename TR>
82+
void reallocate_hcontainer(const std::vector<std::map<int, std::map<TAC, RI::Tensor<Tdata>>>>& Hexxs,
83+
HContainer<TR>* hR,
84+
const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest = nullptr);
85+
86+
/// allocate according to BvK cells, used in scf
87+
template <typename TR>
88+
void reallocate_hcontainer(const int nat, HContainer<TR>* hR,
89+
const std::array<int, 3>& Rs_period,
90+
const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest = nullptr);
91+
7692
} // namespace hamilt
7793
#endif // __EXX
7894
#include "op_exx_lcao.hpp"

source/module_hamilt_lcao/hamilt_lcaodft/operator_lcao/op_exx_lcao.hpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
namespace hamilt
1313
{
1414
using TAC = std::pair<int, std::array<int, 3>>;
15+
1516
// allocate according to the read-in HexxR, used in nscf
1617
template <typename Tdata, typename TR>
17-
inline void reallocate_hcontainer(const std::vector<std::map<int, std::map<TAC, RI::Tensor<Tdata>>>>& Hexxs,
18-
HContainer<TR>* hR)
18+
void reallocate_hcontainer(const std::vector<std::map<int, std::map<TAC, RI::Tensor<Tdata>>>>& Hexxs,
19+
HContainer<TR>* hR,
20+
const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest)
1921
{
2022
auto* pv = hR->get_paraV();
2123
bool need_allocate = false;
@@ -27,7 +29,10 @@ namespace hamilt
2729
const int& iat1 = Htmp2.first.first;
2830
if (pv->get_row_size(iat0) > 0 && pv->get_col_size(iat1) > 0)
2931
{
30-
const Abfs::Vector3_Order<int>& R = RI_Util::array3_to_Vector3(Htmp2.first.second);
32+
const Abfs::Vector3_Order<int>& R = RI_Util::array3_to_Vector3(
33+
(cell_nearest ?
34+
cell_nearest->get_cell_nearest_discrete(iat0, iat1, Htmp2.first.second)
35+
: Htmp2.first.second));
3136
BaseMatrix<TR>* HlocR = hR->find_matrix(iat0, iat1, R.x, R.y, R.z);
3237
if (HlocR == nullptr)
3338
{ // add R to HContainer
@@ -40,11 +45,12 @@ namespace hamilt
4045
}
4146
if (need_allocate) { hR->allocate(nullptr, true); }
4247
}
48+
4349
/// allocate according to BvK cells, used in scf
4450
template <typename TR>
45-
inline void reallocate_hcontainer(const int nat, HContainer<TR>* hR,
51+
void reallocate_hcontainer(const int nat, HContainer<TR>* hR,
4652
const std::array<int, 3>& Rs_period,
47-
const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest = nullptr)
53+
const RI::Cell_Nearest<int, int, 3, double, 3>* const cell_nearest)
4854
{
4955
auto* pv = hR->get_paraV();
5056
auto Rs = RI_Util::get_Born_von_Karmen_cells(Rs_period);
@@ -154,18 +160,7 @@ OperatorEXX<OperatorLCAO<TK, TR>>::OperatorEXX(HS_Matrix_K<TK>* hsk_in,
154160
const std::array<int, 3> Rs_period = { this->kv.nmp[0], this->kv.nmp[1], this->kv.nmp[2] };
155161
if (this->use_cell_nearest)
156162
{
157-
// set cell_nearest
158-
std::map<int, std::array<double, 3>> atoms_pos;
159-
for (int iat = 0; iat < ucell.nat; ++iat) {
160-
atoms_pos[iat] = RI_Util::Vector3_to_array3(
161-
ucell.atoms[ucell.iat2it[iat]]
162-
.tau[ucell.iat2ia[iat]]);
163-
}
164-
const std::array<std::array<double, 3>, 3> latvec
165-
= { RI_Util::Vector3_to_array3(ucell.a1),
166-
RI_Util::Vector3_to_array3(ucell.a2),
167-
RI_Util::Vector3_to_array3(ucell.a3) };
168-
this->cell_nearest.init(atoms_pos, latvec, Rs_period);
163+
this->cell_nearest = init_cell_nearest(ucell, Rs_period);
169164
reallocate_hcontainer(ucell.nat, this->hR, Rs_period, &this->cell_nearest);
170165
}
171166
else { reallocate_hcontainer(ucell.nat, this->hR, Rs_period); }

source/module_hamilt_lcao/hamilt_lcaodft/spar_hsr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void sparse_format::cal_HSR(const UnitCell& ucell,
2323
) {
2424
ModuleBase::TITLE("sparse_format", "cal_HSR");
2525

26-
sparse_format::set_R_range(HS_Arrays.all_R_coor, grid);
26+
// sparse_format::set_R_range(HS_Arrays.all_R_coor, grid);
2727

2828
const int nspin = PARAM.inp.nspin;
2929

@@ -33,6 +33,8 @@ void sparse_format::cal_HSR(const UnitCell& ucell,
3333
= dynamic_cast<hamilt::HamiltLCAO<std::complex<double>, double>*>(
3434
p_ham);
3535

36+
HS_Arrays.all_R_coor = get_R_range(*(p_ham_lcao->getHR()));
37+
3638
if (TD_Velocity::tddft_velocity) {
3739
sparse_format::cal_HContainer_td(
3840
pv,
@@ -57,7 +59,9 @@ void sparse_format::cal_HSR(const UnitCell& ucell,
5759
hamilt::HamiltLCAO<std::complex<double>, std::complex<double>>*
5860
p_ham_lcao
5961
= dynamic_cast<hamilt::HamiltLCAO<std::complex<double>,
60-
std::complex<double>>*>(p_ham);
62+
std::complex<double>>*>(p_ham);
63+
64+
HS_Arrays.all_R_coor = get_R_range(*(p_ham_lcao->getHR()));
6165

6266
sparse_format::cal_HContainer_cd(pv,
6367
current_spin,

source/module_hamilt_lcao/hamilt_lcaodft/spar_hsr.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,23 @@
44
#include "module_hamilt_lcao/hamilt_lcaodft/hamilt_lcao.h"
55

66
namespace sparse_format {
7+
template<typename T>
8+
std::set<Abfs::Vector3_Order<int>> get_R_range(const hamilt::HContainer<T>& hR)
9+
{
10+
std::set<Abfs::Vector3_Order<int>> all_R_coor;
11+
for (int iap = 0;iap < hR.size_atom_pairs(); ++iap)
12+
{
13+
const hamilt::AtomPair<T>& atom_pair = hR.get_atom_pair(iap);
14+
for (int iR = 0; iR < atom_pair.get_R_size(); ++iR)
15+
{
16+
const auto& r_index = atom_pair.get_R_index(iR);
17+
Abfs::Vector3_Order<int> dR(r_index.x, r_index.y, r_index.z);
18+
all_R_coor.insert(dR);
19+
}
20+
}
21+
return all_R_coor;
22+
};
23+
724
using TAC = std::pair<int, std::array<int, 3>>;
825
void cal_HSR(const UnitCell& ucell,
926
const Parallel_Orbitals& pv,

source/module_io/read_input_item_output.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ void ReadInput::item_output()
298298
read_sync_bool(input.out_mat_xc);
299299
this->add_item(item);
300300
}
301+
{
302+
Input_Item item("out_mat_xc2");
303+
item.annotation = "output exchange-correlation matrix in NAO representation";
304+
read_sync_bool(input.out_mat_xc2);
305+
this->add_item(item);
306+
}
301307
{
302308
Input_Item item("out_eband_terms");
303309
item.annotation = "output the band energy terms separately";

source/module_io/test/read_input_ptest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ TEST_F(InputParaTest, ParaRead)
208208
EXPECT_EQ(param.inp.out_mat_hs[1], 8);
209209
EXPECT_EQ(param.inp.out_mat_hs2, 0);
210210
EXPECT_FALSE(param.inp.out_mat_xc);
211+
EXPECT_FALSE(param.inp.out_mat_xc2);
211212
EXPECT_FALSE(param.inp.out_eband_terms);
212213
EXPECT_EQ(param.inp.out_interval, 1);
213214
EXPECT_EQ(param.inp.out_app_flag, 0);

source/module_io/write_vxc.hpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ struct TGint<std::complex<double>>
3030
namespace ModuleIO
3131
{
3232

33-
inline void gint_vl(Gint_Gamma& gg, Gint_inout& io)
34-
{
35-
gg.cal_vlocal(&io, false);
36-
};
37-
38-
inline void gint_vl(Gint_k& gk, Gint_inout& io, ModuleBase::matrix& wg)
39-
{
40-
gk.cal_gint(&io);
41-
};
42-
4333
inline void set_para2d_MO(const Parallel_Orbitals& pv, const int nbands, Parallel_2D& p2d)
4434
{
4535
std::ofstream ofs;
@@ -134,6 +124,8 @@ std::vector<double> orbital_energy(const int ik, const int nbands, const std::ve
134124
return e;
135125
}
136126

127+
#ifndef SET_GINT_POINTER_H
128+
#define SET_GINT_POINTER_H
137129
// mohan update 2024-04-01
138130
template <typename T>
139131
void set_gint_pointer(Gint_Gamma& gint_gamma, Gint_k& gint_k, typename TGint<T>::type*& gint);
@@ -153,6 +145,7 @@ void set_gint_pointer<std::complex<double>>(Gint_Gamma& gint_gamma,
153145
{
154146
gint = &gint_k;
155147
}
148+
#endif
156149

157150
inline void write_orb_energy(const K_Vectors& kv,
158151
const int nspin0, const int nbands,
@@ -223,7 +216,7 @@ void write_Vxc(const int nspin,
223216
// 2. allocate AO-matrix
224217
// R (the number of hR: 1 for nspin=1, 4; 2 for nspin=2)
225218
int nspin0 = (nspin == 2) ? 2 : 1;
226-
std::vector<hamilt::HContainer<TR>> vxcs_R_ao(nspin0, hamilt::HContainer<TR>(pv));
219+
std::vector<hamilt::HContainer<TR>> vxcs_R_ao(nspin0, hamilt::HContainer<TR>(ucell, pv));
227220
for (int is = 0; is < nspin0; ++is) {
228221
vxcs_R_ao[is].set_zero();
229222
if (std::is_same<TK, double>::value) { vxcs_R_ao[is].fix_gamma(); }

0 commit comments

Comments
 (0)