Skip to content

Commit 2fb30fd

Browse files
committed
Feature: add xc output info
1 parent 7baaab1 commit 2fb30fd

File tree

6 files changed

+103
-59
lines changed

6 files changed

+103
-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: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "source_pw/module_pwdft/global.h"
33
#include "source_io/module_parameter/parameter.h"
44
#include "source_base/global_function.h"
5+
#include "source_base/tool_title.h"
56

67
#ifdef USE_LIBXC
78
#include "xc_functional_libxc.h"
@@ -25,28 +26,41 @@ void XC_Functional::set_hybrid_alpha(const double alpha_in)
2526

2627
void XC_Functional::set_xc_first_loop(const UnitCell& ucell)
2728
{
29+
ModuleBase::TITLE("XC_Functional", "set_xc_first_loop");
2830
/** In the special "two-level" calculation case,
2931
the first scf iteration only calculate the functional without exact
3032
exchange. but in "nscf" calculation, there is no need of "two-level"
3133
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") {
34+
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE")
35+
{
3636
XC_Functional::set_xc_type("pbe");
3737
}
38-
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0") {
39-
XC_Functional::set_xc_type("scan");
38+
else if ( ucell.atoms[0].ncpp.xc_func == "LC_PBE" || ucell.atoms[0].ncpp.xc_func == "LC_WPBE"
39+
|| ucell.atoms[0].ncpp.xc_func == "LRC_WPBEH" || ucell.atoms[0].ncpp.xc_func == "CAM_PBEH" )
40+
{
41+
XC_Functional::set_xc_type("pbe");
42+
}
43+
// added by jghan, 2024-07-07
44+
else if ( ucell.atoms[0].ncpp.xc_func == "MULLER" || ucell.atoms[0].ncpp.xc_func == "POWER"
45+
|| ucell.atoms[0].ncpp.xc_func == "WP22" || ucell.atoms[0].ncpp.xc_func == "CWP22" )
46+
{
47+
XC_Functional::set_xc_type("pbe");
4048
}
41-
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP") {
49+
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP")
50+
{
4251
XC_Functional::set_xc_type("blyp");
4352
}
53+
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0")
54+
{
55+
XC_Functional::set_xc_type("scan");
56+
}
4457
}
4558

4659
// The setting values of functional id according to the index in LIBXC
4760
// for detail, refer to https://www.tddft.org/programs/libxc/functionals/
4861
void XC_Functional::set_xc_type(const std::string xc_func_in)
4962
{
63+
ModuleBase::TITLE("XC_Functional", "set_xc_type");
5064
//Note : due to the separation of gcx_spin and gcc_spin,
5165
//when you are adding new GGA functionals,
5266
//please put exchange first, followed by correlation,
@@ -316,3 +330,42 @@ void XC_Functional::set_xc_type(const std::string xc_func_in)
316330
#endif
317331

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

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: 31 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,8 @@ 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+
ModuleBase::TITLE("XC_Functional", "set_xc_type_libxc");
96+
// check if the functional involves Laplacian of rho
9697
if (not_supported_xc_with_laplacian(xc_func_in))
9798
{
9899
ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc",
@@ -120,14 +121,14 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
120121
}
121122

122123
// check if there is None (no, we dont check it)
123-
int func_type = xcfunc_type_.front(); // all functionals are of the same type
124+
int func_type = xcfunc_type_.front(); // all functionals are of the same type
124125
// if (func_type == 0)
125126
// {
126127
// ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc",
127128
// "Unrecognized functional type in '" + xc_func_in + "'.");
128129
// }
129130

130-
// determine the functional id
131+
// determine the functional id
131132
std::vector<int> func_id(xcfunc_words_.size(), -1);
132133
std::transform(xcfunc_words_.begin(), xcfunc_words_.end(), func_id.begin(),
133134
[](const std::string& func) { return xc_functional_get_number(func.c_str()); });
@@ -144,7 +145,7 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
144145
}
145146

146147
// return
147-
return std::make_pair(func_type, func_id);
148+
return std::make_pair(func_type, func_id);
148149
}
149150

150151
const std::vector<double> in_built_xc_func_ext_params(const int id)
@@ -176,45 +177,45 @@ const std::vector<double> in_built_xc_func_ext_params(const int id)
176177
return {0.04918, 0.132, 0.2533, 0.349,
177178
0.35/2.29, 2.0/2.29, GlobalC::exx_info.info_global.hse_omega};
178179
// Long-range corrected functionals:
179-
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
180+
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
180181
{
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.
182+
// This is a range-separated hybrid functional with range-separation constant 0.330,
183+
// and 0.0% short-range and 100.0% long-range exact exchange,
184+
// using the error function kernel.
184185
return { GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.33
185186
}
186-
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
187+
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
187188
{
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.
189+
// This is a range-separated hybrid functional with range-separation constant 0.400,
190+
// and 0.0% short-range and 100.0% long-range exact exchange,
191+
// using the error function kernel.
191192
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
192193
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
193194
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.4
194195
}
195-
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
196+
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
196197
{
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.
198+
// This is a range-separated hybrid functional with range-separation constant 0.300,
199+
// and 0.0% short-range and 100.0% long-range exact exchange,
200+
// using the error function kernel.
200201
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
201202
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
202203
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.3
203204
}
204-
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
205+
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
205206
{
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.
207+
// This is a range-separated hybrid functional with range-separation constant 0.200,
208+
// and 20.0% short-range and 100.0% long-range exact exchange,
209+
// using the error function kernel.
209210
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
210211
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -0.8
211212
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.2
212213
}
213-
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
214+
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
214215
{
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.
216+
// This is a range-separated hybrid functional with range-separation constant 0.700,
217+
// and 100.0% short-range and 20.0% long-range exact exchange,
218+
// using the error function kernel.
218219
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 0.2
219220
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: 0.8
220221
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.7
@@ -287,10 +288,10 @@ XC_Functional_Libxc::init_func(const std::vector<int> &func_id,
287288

288289
void XC_Functional_Libxc::finish_func(std::vector<xc_func_type> &funcs)
289290
{
290-
for(xc_func_type func : funcs)
291+
for(xc_func_type func : funcs)
291292
{
292-
xc_func_end(&func);
293-
}
293+
xc_func_end(&func);
294+
}
294295
}
295296

296297
#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)