Skip to content

Commit 4301a21

Browse files
committed
Feature: add xc output info
1 parent 7baaab1 commit 4301a21

File tree

6 files changed

+99
-59
lines changed

6 files changed

+99
-59
lines changed

source/source_esolver/esolver_ks.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ void ESolver_KS<T, Device>::before_all_runners(UnitCell& ucell, const Input_para
7070

7171
//! 4) setup Exc for the first element '0' (all elements have same exc)
7272
XC_Functional::set_xc_type(ucell.atoms[0].ncpp.xc_func);
73+
GlobalV::ofs_running<<XC_Functional::output_info()<<std::endl;
7374

7475
//! 5) setup the charge mixing parameters
7576
p_chgmix->set_mixing(inp.mixing_mode, inp.mixing_beta, inp.mixing_ndim,

source/source_hamilt/module_xc/xc_functional.cpp

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,29 @@ void XC_Functional::set_xc_first_loop(const UnitCell& ucell)
2929
the first scf iteration only calculate the functional without exact
3030
exchange. but in "nscf" calculation, there is no need of "two-level"
3131
method. */
32-
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "HSE"
33-
|| ucell.atoms[0].ncpp.xc_func == "PBE0"|| ucell.atoms[0].ncpp.xc_func == "LC_PBE"
34-
|| ucell.atoms[0].ncpp.xc_func == "LC_WPBE" || ucell.atoms[0].ncpp.xc_func == "LRC_WPBEH"
35-
|| ucell.atoms[0].ncpp.xc_func == "CAM_PBEH") {
32+
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE")
33+
{
3634
XC_Functional::set_xc_type("pbe");
3735
}
38-
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0") {
39-
XC_Functional::set_xc_type("scan");
36+
else if ( ucell.atoms[0].ncpp.xc_func == "LC_PBE" || ucell.atoms[0].ncpp.xc_func == "LC_WPBE"
37+
|| ucell.atoms[0].ncpp.xc_func == "LRC_WPBEH" || ucell.atoms[0].ncpp.xc_func == "CAM_PBEH" )
38+
{
39+
XC_Functional::set_xc_type("pbe");
40+
}
41+
// added by jghan, 2024-07-07
42+
else if ( ucell.atoms[0].ncpp.xc_func == "MULLER" || ucell.atoms[0].ncpp.xc_func == "POWER"
43+
|| ucell.atoms[0].ncpp.xc_func == "WP22" || ucell.atoms[0].ncpp.xc_func == "CWP22" )
44+
{
45+
XC_Functional::set_xc_type("pbe");
4046
}
41-
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP") {
47+
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP")
48+
{
4249
XC_Functional::set_xc_type("blyp");
4350
}
51+
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0")
52+
{
53+
XC_Functional::set_xc_type("scan");
54+
}
4455
}
4556

4657
// The setting values of functional id according to the index in LIBXC
@@ -316,3 +327,42 @@ void XC_Functional::set_xc_type(const std::string xc_func_in)
316327
#endif
317328

318329
}
330+
331+
std::string XC_Functional::output_info()
332+
{
333+
#ifdef USE_LIBXC
334+
if(use_libxc)
335+
{
336+
std::stringstream ss;
337+
ss<<" Libxc v"<<xc_version_string()<<std::endl;
338+
ss<<"\t"<<xc_reference()<<std::endl;
339+
340+
std::vector<xc_func_type> funcs = XC_Functional_Libxc::init_func(func_id, XC_UNPOLARIZED);
341+
for(const auto &func : funcs)
342+
{
343+
const xc_func_info_type *info = xc_func_get_info(&func);
344+
ss<<" XC: "<<xc_func_info_get_name(info)<<std::endl;
345+
for(int i=0; i<XC_MAX_REFERENCES; ++i)
346+
{
347+
const func_reference_type *ref = xc_func_info_get_references(func.info, i);
348+
if(ref)
349+
ss<<"\t"<<xc_func_reference_get_ref(ref)<<std::endl;
350+
}
351+
}
352+
XC_Functional_Libxc::finish_func(funcs);
353+
return ss.str();
354+
}
355+
else
356+
{
357+
std::string s = " XC:\t";
358+
for(const auto &id: func_id)
359+
s += std::string(xc_functional_get_name(id))+"\t";
360+
return s;
361+
}
362+
#else
363+
std::string s = " XC:\t";
364+
for(const auto &id: func_id)
365+
s += std::to_string(id)+"\t";
366+
return s;
367+
#endif
368+
}

source/source_hamilt/module_xc/xc_functional.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ class XC_Functional
8383
/// Usually in exx caculation, the first SCF loop should be converged with PBE
8484
static void set_xc_first_loop(const UnitCell& ucell);
8585

86+
static std::string output_info();
87+
8688
private:
8789

8890
static std::vector<int> func_id; // libxc id of functional

source/source_hamilt/module_xc/xc_functional_libxc.cpp

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ bool not_supported_xc_with_nonlocal_vdw(const std::string& xc_func_in)
4040

4141
if(xc_func.find("VV10") != std::string::npos) { return true; }
4242
/* known excluded: GGA_XC_VV10, HYB_GGA_XC_LC_VV10, MGGA_C_REVSCAN_VV10, MGGA_C_SCAN_VV10,
43-
MGGA_C_SCANL_VV10, MGGA_XC_VCML_RVV10 */
43+
MGGA_C_SCANL_VV10, MGGA_XC_VCML_RVV10 */
4444

4545
const std::vector<std::string> not_supported = {"C09X", "VCML", "HYB_MGGA_XC_WB97M_V", "MGGA_XC_B97M_V"};
4646
for(const std::string& str : not_supported)
@@ -54,8 +54,8 @@ bool not_supported_xc_with_nonlocal_vdw(const std::string& xc_func_in)
5454
{
5555
std::cout << " WARNING: range-seperated XC omega-B97 family with nonlocal correction term is used.\n"
5656
<< " if you are not planning to use these functionals like wB97X-D3BJ that:\n"
57-
<< " XC_GGA_XC_WB97X_V with specified D3BJ DFT-D3 parameters, this is not what\n"
58-
<< " you want." << std::endl;
57+
<< " XC_GGA_XC_WB97X_V with specified D3BJ DFT-D3 parameters, this is not what\n"
58+
<< " you want." << std::endl;
5959
}
6060
return false;
6161
}
@@ -92,7 +92,7 @@ int xc_func_type_classifier(const std::string& xc_func,
9292
std::pair<int,std::vector<int>>
9393
XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
9494
{
95-
// check if the functional involves Laplacian of rho
95+
// check if the functional involves Laplacian of rho
9696
if (not_supported_xc_with_laplacian(xc_func_in))
9797
{
9898
ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc",
@@ -120,14 +120,14 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
120120
}
121121

122122
// check if there is None (no, we dont check it)
123-
int func_type = xcfunc_type_.front(); // all functionals are of the same type
123+
int func_type = xcfunc_type_.front(); // all functionals are of the same type
124124
// if (func_type == 0)
125125
// {
126126
// ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc",
127127
// "Unrecognized functional type in '" + xc_func_in + "'.");
128128
// }
129129

130-
// determine the functional id
130+
// determine the functional id
131131
std::vector<int> func_id(xcfunc_words_.size(), -1);
132132
std::transform(xcfunc_words_.begin(), xcfunc_words_.end(), func_id.begin(),
133133
[](const std::string& func) { return xc_functional_get_number(func.c_str()); });
@@ -144,7 +144,7 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
144144
}
145145

146146
// return
147-
return std::make_pair(func_type, func_id);
147+
return std::make_pair(func_type, func_id);
148148
}
149149

150150
const std::vector<double> in_built_xc_func_ext_params(const int id)
@@ -176,45 +176,45 @@ const std::vector<double> in_built_xc_func_ext_params(const int id)
176176
return {0.04918, 0.132, 0.2533, 0.349,
177177
0.35/2.29, 2.0/2.29, GlobalC::exx_info.info_global.hse_omega};
178178
// Long-range corrected functionals:
179-
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
179+
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
180180
{
181-
// This is a range-separated hybrid functional with range-separation constant 0.330,
182-
// and 0.0% short-range and 100.0% long-range exact exchange,
183-
// using the error function kernel.
181+
// This is a range-separated hybrid functional with range-separation constant 0.330,
182+
// and 0.0% short-range and 100.0% long-range exact exchange,
183+
// using the error function kernel.
184184
return { GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.33
185185
}
186-
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
186+
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
187187
{
188-
// This is a range-separated hybrid functional with range-separation constant 0.400,
189-
// and 0.0% short-range and 100.0% long-range exact exchange,
190-
// using the error function kernel.
188+
// This is a range-separated hybrid functional with range-separation constant 0.400,
189+
// and 0.0% short-range and 100.0% long-range exact exchange,
190+
// using the error function kernel.
191191
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
192192
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
193193
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.4
194194
}
195-
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
195+
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
196196
{
197-
// This is a range-separated hybrid functional with range-separation constant 0.300,
198-
// and 0.0% short-range and 100.0% long-range exact exchange,
199-
// using the error function kernel.
197+
// This is a range-separated hybrid functional with range-separation constant 0.300,
198+
// and 0.0% short-range and 100.0% long-range exact exchange,
199+
// using the error function kernel.
200200
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
201201
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
202202
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.3
203203
}
204-
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
204+
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
205205
{
206-
// This is a range-separated hybrid functional with range-separation constant 0.200,
207-
// and 20.0% short-range and 100.0% long-range exact exchange,
208-
// using the error function kernel.
206+
// This is a range-separated hybrid functional with range-separation constant 0.200,
207+
// and 20.0% short-range and 100.0% long-range exact exchange,
208+
// using the error function kernel.
209209
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
210210
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -0.8
211211
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.2
212212
}
213-
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
213+
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
214214
{
215-
// This is a range-separated hybrid functional with range-separation constant 0.700,
216-
// and 100.0% short-range and 20.0% long-range exact exchange,
217-
// using the error function kernel.
215+
// This is a range-separated hybrid functional with range-separation constant 0.700,
216+
// and 100.0% short-range and 20.0% long-range exact exchange,
217+
// using the error function kernel.
218218
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 0.2
219219
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: 0.8
220220
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.7
@@ -287,10 +287,10 @@ XC_Functional_Libxc::init_func(const std::vector<int> &func_id,
287287

288288
void XC_Functional_Libxc::finish_func(std::vector<xc_func_type> &funcs)
289289
{
290-
for(xc_func_type func : funcs)
290+
for(xc_func_type func : funcs)
291291
{
292-
xc_func_end(&func);
293-
}
292+
xc_func_end(&func);
293+
}
294294
}
295295

296296
#endif

source/source_hamilt/module_xc/xc_functional_libxc.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ namespace XC_Functional_Libxc
5353
// xc_functional_libxc_vxc.cpp
5454
//-------------------
5555

56-
extern std::tuple<double,double,ModuleBase::matrix> v_xc_libxc(
57-
const std::vector<int> &func_id,
58-
const int &nrxx, // number of real-space grid
59-
const double &omega, // volume of cell
60-
const double tpiba,
61-
const Charge* const chr, // charge density
62-
const std::map<int, double>* scaling_factor = nullptr); // added by jghan, 2024-10-10
56+
extern std::tuple<double,double,ModuleBase::matrix> v_xc_libxc(
57+
const std::vector<int> &func_id,
58+
const int &nrxx, // number of real-space grid
59+
const double &omega, // volume of cell
60+
const double tpiba,
61+
const Charge* const chr, // charge density
62+
const std::map<int, double>* scaling_factor = nullptr); // added by jghan, 2024-10-10
6363

6464
// for mGGA functional
6565
extern std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> v_xc_meta(

source/source_lcao/module_ri/Exx_LRI_interface.hpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -135,20 +135,7 @@ void Exx_LRI_Interface<T, Tdata>::exx_beforescf(const int istep,
135135
}
136136
else
137137
{
138-
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE")
139-
{
140-
XC_Functional::set_xc_type("pbe");
141-
}
142-
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0")
143-
{
144-
XC_Functional::set_xc_type("scan");
145-
}
146-
// added by jghan, 2024-07-07
147-
else if ( ucell.atoms[0].ncpp.xc_func == "MULLER" || ucell.atoms[0].ncpp.xc_func == "POWER"
148-
|| ucell.atoms[0].ncpp.xc_func == "WP22" || ucell.atoms[0].ncpp.xc_func == "CWP22" )
149-
{
150-
XC_Functional::set_xc_type("pbe");
151-
}
138+
XC_Functional::set_xc_first_loop(ucell);
152139
}
153140

154141
this->cal_exx_ions(ucell,PARAM.inp.out_ri_cv);
@@ -313,7 +300,7 @@ void Exx_LRI_Interface<T, Tdata>::exx_iter_finish(const K_Vectors& kv,
313300
{
314301
chgmix.close_kerker_gg0();
315302
}
316-
// mohan update 2025-11-04
303+
// mohan update 2025-11-04
317304
this->dm_last_step = dm;
318305
conv_esolver = this->exx_after_converge(
319306
ucell,

0 commit comments

Comments
 (0)