Skip to content

Commit fb7a145

Browse files
dyzhengdyzheng
andauthored
Feature: init_chg hr for initializing charge density with hrs1_nao.csr (deepmodeling#6791)
* Fix: init_chg dm with mismatched sparsity * Feature: for initializing charge density with hrs1_nao.csr * Test: add a test case --------- Co-authored-by: dyzheng <zhengdy@bjaisi.com>
1 parent 72f55c4 commit fb7a145

File tree

16 files changed

+235
-50
lines changed

16 files changed

+235
-50
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,8 @@ These variables are used to control general system parameters.
640640
- atomic: the density is starting from the summation of the atomic density of single atoms.
641641
- file: the density will be read in from a binary file `charge-density.dat` first. If it does not exist, the charge density will be read in from cube files. Besides, when you do `nspin=1` calculation, you only need the density file chgs1.cube. However, if you do `nspin=2` calculation, you also need the density file chgs2.cube. The density file should be output with these names if you set out_chg = 1 in INPUT file.
642642
- wfc: the density will be calculated by wavefunctions and occupations. Wavefunctions are read in from binary files `wf*.dat` (see [out_wfc_pw](#out_wfc_pw)) while occupations are read in from file `eig.txt`.
643+
- dm: the density will be calculated by real space density matrix(DMR) of LCAO base. DMR is read in from file `dmrs1_nao.csr` in directory [read_file_dir](#read_file_dir).
644+
- hr: the real space Hamiltonian matrix(HR) will be read in from file `hrs1_nao.csr` in directory [read_file_dir](#read_file_dir), and DMR and charge density will be calculated from it.
643645
- auto: Abacus first attempts to read the density from a file; if not found, it defaults to using atomic density.
644646
- **Default**: atomic
645647

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,6 @@ void ESolver_KS_LCAO<TK, TR>::before_all_runners(UnitCell& ucell, const Input_pa
7575

7676
LCAO_domain::set_psi_occ_dm_chg<TK>(this->kv, this->psi, this->pv, this->pelec,
7777
this->dmat, this->chr, inp);
78-
79-
if(inp.init_chg == "dm")
80-
{
81-
//! 4.1) init density matrix from file
82-
std::string dmfile = PARAM.globalv.global_readin_dir + "/dmrs1_nao.csr";
83-
LCAO_domain::init_dm_from_file<TK>(dmfile, this->dmat, ucell, &(this->pv));
84-
}
8578

8679
LCAO_domain::set_pot<TK>(ucell, this->kv, this->sf, *this->pw_rho, *this->pw_rhod,
8780
this->pelec, this->orb_, this->pv, this->locpp, this->dftu,
@@ -167,46 +160,69 @@ void ESolver_KS_LCAO<TK, TR>::before_scf(UnitCell& ucell, const int istep)
167160
// 11) set xc type before the first cal of xc in pelec->init_scf, Peize Lin add 2016-12-03
168161
this->exx_nao.before_scf(ucell, this->kv, orb_, this->p_chgmix, istep, PARAM.inp);
169162

170-
// 12.1) if init_chg = "dm", then calculate rho from readin DMR before init_scf
171-
if(PARAM.inp.init_chg == "dm")
172-
{
173-
LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, this->pelec->charge, true);
174-
}
175-
// 12.2) init_scf, should be before_scf? mohan add 2025-03-10
176-
this->pelec->init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, ucell.symm);
177-
178-
// 13) initalize DM(R), which has the same size with Hamiltonian(R)
163+
// 12) initalize DM(R), which has the same size with Hamiltonian(R)
179164
auto* hamilt_lcao = dynamic_cast<hamilt::HamiltLCAO<TK, TR>*>(this->p_hamilt);
165+
180166
if(!hamilt_lcao)
181167
{
182168
ModuleBase::WARNING_QUIT("ESolver_KS_LCAO::before_scf","p_hamilt does not exist");
183169
}
184-
if(PARAM.inp.init_chg != "dm") this->dmat.dm->init_DMR(*hamilt_lcao->getHR());
170+
this->dmat.dm->init_DMR(*hamilt_lcao->getHR());
171+
172+
// 13.1) decide the strategy for initializing DMR and HR
173+
if(istep == 0)//if the first scf step, readin DMR from file,
174+
{
175+
//calculate or readin the density matrix DMR
176+
if(PARAM.inp.init_chg == "dm")
177+
{
178+
//! 13.1.1) init density matrix from file
179+
std::string dmfile = PARAM.globalv.global_readin_dir + "/dmrs1_nao.csr";
180+
LCAO_domain::init_dm_from_file<TK>(dmfile, this->dmat, ucell, &(this->pv));
181+
}
182+
if(PARAM.inp.init_chg == "hr")
183+
{
184+
//! 13.1.2) init HR from file
185+
std::string hrfile = PARAM.globalv.global_readin_dir + "/hrs1_nao.csr";
186+
LCAO_domain::init_hr_from_file<TR>(
187+
hrfile,
188+
dynamic_cast<hamilt::HamiltLCAO<TK, TR>*>(this->p_hamilt)->getHR(),
189+
ucell,
190+
&(this->pv)
191+
);
192+
this->p_hamilt->refresh(false);
193+
hsolver::HSolverLCAO<TK> hsolver_lcao_obj(&(this->pv), PARAM.inp.ks_solver);
194+
hsolver_lcao_obj.solve(this->p_hamilt, this->psi[0], this->pelec, *this->dmat.dm,
195+
this->chr, PARAM.inp.nspin, 0);
196+
}
197+
}
198+
else //if not, use the DMR calculated from last step
199+
{
200+
// 13.1.2) two cases are considered:
201+
// 1. DMK in DensityMatrix is not empty (istep > 0), then DMR is initialized by DMK
202+
// 2. DMK in DensityMatrix is empty (istep == 0), then DMR is initialized by zeros
203+
this->dmat.dm->cal_DMR();
204+
}
205+
// 13.2 if init_chg = "dm", then calculate rho from readin DMR before init_scf
206+
if(PARAM.inp.init_chg == "dm")
207+
{
208+
LCAO_domain::dm2rho(this->dmat.dm->get_DMR_vector(), PARAM.inp.nspin, this->pelec->charge, true);
209+
}
210+
// 13.2) init_scf, should be before_scf? mohan add 2025-03-10
211+
this->pelec->init_scf(ucell, this->Pgrid, this->sf.strucFac, this->locpp.numeric, ucell.symm);
185212

186213
#ifdef __MLALGO
187214
// 14) initialize DM2(R) of DeePKS, the DM2(R) is different from DM(R)
188215
this->deepks.ld.init_DMR(ucell, orb_, this->pv, this->gd);
189216
#endif
190217

191-
// 15) two cases are considered:
192-
// 1. DMK in DensityMatrix is not empty (istep > 0), then DMR is initialized by DMK
193-
// 2. DMK in DensityMatrix is empty (istep == 0), then DMR is initialized by zeros
194-
if (istep > 0)
195-
{
196-
this->dmat.dm->cal_DMR();
197-
}
198-
199218
// 16) the electron charge density should be symmetrized,
200219
Symmetry_rho srho;
201220
for (int is = 0; is < PARAM.inp.nspin; is++)
202221
{
203222
srho.begin(is, this->chr, this->pw_rho, ucell.symm);
204223
}
205224

206-
// 17) why we need to set this sentence? mohan add 2025-03-10
207-
this->p_hamilt->non_first_scf = istep;
208-
209-
// 18) update of RDMFT, added by jghan
225+
// 17) update of RDMFT, added by jghan
210226
if (PARAM.inp.rdmft == true)
211227
{
212228
rdmft_solver.update_ion(ucell, *(this->pw_rho), this->locpp.vloc, this->sf.strucFac);

source/source_hamilt/hamilt.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Hamilt
2121
virtual void updateHk(const int ik){return;}
2222

2323
/// refresh status of Hamiltonian, for example, refresh H(R) and S(R) in LCAO case
24-
virtual void refresh(void){return;}
24+
virtual void refresh(bool yes = true){return;}
2525

2626
/// core function: for solving eigenvalues of Hamiltonian with iterative method
2727
virtual void hPsi(
@@ -55,8 +55,6 @@ class Hamilt
5555

5656
std::string classname = "none";
5757

58-
int non_first_scf=0;
59-
6058
/// first node operator, add operations from each operators
6159
Operator<T, Device>* ops = nullptr;
6260

source/source_io/read_input_item_system.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void ReadInput::item_system()
552552
}
553553
};
554554
item.check_value = [](const Input_Item& item, const Parameter& para) {
555-
const std::vector<std::string> init_chgs = {"atomic", "file", "wfc", "auto", "dm"};
555+
const std::vector<std::string> init_chgs = {"atomic", "file", "wfc", "auto", "dm", "hr"};
556556
if (std::find(init_chgs.begin(), init_chgs.end(), para.input.init_chg) == init_chgs.end())
557557
{
558558
const std::string warningstr = nofound_str(init_chgs, "init_chg");

source/source_lcao/LCAO_set.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,34 @@ void LCAO_domain::init_dm_from_file(
9999
const UnitCell& ucell,
100100
const Parallel_Orbitals* pv)
101101
{
102-
ModuleBase::TITLE("LCAO_domain::init_dm_from_file", "init_dm_from_file");
103-
hamilt::HContainer<double>* dm_container = new hamilt::HContainer<double>(pv);
104-
dmat.dm->init_DMR(dm_container[0]);
102+
ModuleBase::TITLE("LCAO_domain", "init_dm_from_file");
103+
hamilt::HContainer<double>* dm_container = dmat.dm->get_DMR_vector()[0];
105104
hamilt::Read_HContainer<double> reader_dm(
106-
dmat.dm->get_DMR_vector()[0],
105+
dm_container,
107106
dmfile,
108107
PARAM.globalv.nlocal,
109108
&ucell
110109
);
111110
reader_dm.read();
112-
delete dm_container;
111+
return;
112+
}
113+
114+
template <typename TR>
115+
void LCAO_domain::init_hr_from_file(
116+
const std::string hrfile,
117+
hamilt::HContainer<TR>* hmat,
118+
const UnitCell& ucell,
119+
const Parallel_Orbitals* pv)
120+
{
121+
ModuleBase::TITLE("LCAO_domain", "init_hr_from_file");
122+
hmat->set_zero();
123+
hamilt::Read_HContainer<TR> reader_hr(
124+
hmat,
125+
hrfile,
126+
PARAM.globalv.nlocal,
127+
&ucell
128+
);
129+
reader_hr.read();
113130
return;
114131
}
115132

@@ -175,3 +192,14 @@ template void LCAO_domain::init_dm_from_file<std::complex<double>>(
175192
LCAO_domain::Setup_DM<std::complex<double>>& dmat,
176193
const UnitCell& ucell,
177194
const Parallel_Orbitals* pv);
195+
196+
template void LCAO_domain::init_hr_from_file<double>(
197+
const std::string hrfile,
198+
hamilt::HContainer<double>* hmat,
199+
const UnitCell& ucell,
200+
const Parallel_Orbitals* pv);
201+
template void LCAO_domain::init_hr_from_file<std::complex<double>>(
202+
const std::string hrfile,
203+
hamilt::HContainer<std::complex<double>>* hmat,
204+
const UnitCell& ucell,
205+
const Parallel_Orbitals* pv);

source/source_lcao/LCAO_set.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,25 @@ void set_pot(
5353
Setup_DeePKS<TK> &deepks,
5454
const Input_para &inp);
5555

56+
/**
57+
* @brief read in DMR from file, and save it into dmat
58+
*/
5659
template <typename TK>
5760
void init_dm_from_file(
5861
const std::string dmfile,
5962
LCAO_domain::Setup_DM<TK>& dmat,
6063
const UnitCell& ucell,
6164
const Parallel_Orbitals* pv);
65+
66+
/**
67+
* @brief read in HR from file, and save it into hmat
68+
*/
69+
template <typename TK>
70+
void init_hr_from_file(
71+
const std::string hrfile,
72+
hamilt::HContainer<TK>* hmat,
73+
const UnitCell& ucell,
74+
const Parallel_Orbitals* pv);
6275
} // end namespace
6376

6477
#endif

source/source_lcao/hamilt_lcao.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -493,20 +493,32 @@ void HamiltLCAO<TK, TR>::updateHk(const int ik)
493493
}
494494

495495
template <typename TK, typename TR>
496-
void HamiltLCAO<TK, TR>::refresh()
496+
void HamiltLCAO<TK, TR>::refresh(bool yes)
497497
{
498498
ModuleBase::TITLE("HamiltLCAO", "refresh");
499-
dynamic_cast<hamilt::OperatorLCAO<TK, TR>*>(this->ops)->set_hr_done(false);
500-
if (PARAM.inp.nspin == 2)
499+
if(yes)
501500
{
502-
this->refresh_times = 1;
503-
this->current_spin = 0;
504-
if (this->hR->get_nnr() != this->hRS2.size() / 2)
501+
dynamic_cast<hamilt::OperatorLCAO<TK, TR>*>(this->ops)->set_hr_done(false);
502+
if (PARAM.inp.nspin == 2)
505503
{
506-
// operator has changed, resize hRS2
507-
this->hRS2.resize(this->hR->get_nnr() * 2);
504+
this->refresh_times = 1;
505+
this->current_spin = 0;
506+
if (this->hR->get_nnr() != this->hRS2.size() / 2)
507+
{
508+
// operator has changed, resize hRS2
509+
this->hRS2.resize(this->hR->get_nnr() * 2);
510+
}
511+
this->hR->allocate(this->hRS2.data(), 0);
512+
}
513+
}
514+
else {
515+
dynamic_cast<hamilt::OperatorLCAO<TK, TR>*>(this->ops)->set_hr_done(true);
516+
this->refresh_times = 0;
517+
if (PARAM.inp.nspin == 2)
518+
{
519+
ModuleBase::WARNING_QUIT("HamiltLCAO::refresh",
520+
"When turning off the refresh flag, the nspin==2 case is not supported yet.");
508521
}
509-
this->hR->allocate(this->hRS2.data(), 0);
510522
}
511523
}
512524

source/source_lcao/hamilt_lcao.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class HamiltLCAO : public Hamilt<TK>
124124
#endif
125125

126126
/// refresh the status of HR
127-
void refresh() override;
127+
void refresh(bool yes) override;
128128

129129
// for target K point, update consequence of hPsi() and matrix()
130130
virtual void updateHk(const int ik) override;

source/source_lcao/module_operator_lcao/operator_lcao.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void OperatorLCAO<TK, TR>::init(const int ik_in) {
9898
// cal_type=lcao_overlap refer to overlap matrix operators, which are
9999
// only rely on stucture, and not changed during SCF
100100

101-
if (!this->hr_done) {
101+
{
102102
// update SR first
103103
// in cal_type=lcao_overlap, SR should be updated by each sub-chain
104104
// nodes
@@ -228,7 +228,7 @@ void OperatorLCAO<TK, TR>::init(const int ik_in) {
228228
!= nullptr) { // it is not the last node, loop next init() function
229229
// pass HR status to next node and than set HR status of this node to
230230
// done
231-
if (!this->hr_done) {
231+
{
232232
dynamic_cast<OperatorLCAO<TK, TR>*>(this->next_op)->hr_done
233233
= this->hr_done;
234234
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
INPUT_PARAMETERS
2+
#Parameters (1.General)
3+
suffix autotest
4+
calculation scf
5+
6+
nbands 6
7+
symmetry 0
8+
9+
#Parameters (2.Iteration)
10+
ecutwfc 20
11+
scf_thr 1e-6
12+
scf_nmax 100
13+
14+
15+
#Parameters (3.Basis)
16+
basis_type lcao
17+
18+
#Parameters (4.Smearing)
19+
smearing_method gauss
20+
smearing_sigma 0.002
21+
22+
#Parameters (5.Mixing)
23+
mixing_type broyden
24+
mixing_beta 0.7
25+
pseudo_dir ../../PP_ORB
26+
orbital_dir ../../PP_ORB
27+
28+
#out_mat_hs2 1
29+
init_chg hr
30+
read_file_dir ./

0 commit comments

Comments
 (0)