Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions source/source_esolver/esolver_ks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ void ESolver_KS<T, Device>::before_all_runners(UnitCell& ucell, const Input_para

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

//! 5) setup the charge mixing parameters
p_chgmix->set_mixing(inp.mixing_mode, inp.mixing_beta, inp.mixing_ndim,
Expand Down
9 changes: 6 additions & 3 deletions source/source_hamilt/module_xc/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ AddTest(
TARGET XCTest_PBE
LIBS parameter MPI::MPI_CXX Libxc::xc # required by global.h; for details, `remove_definitions(-D__MPI)`.
SOURCES test_xc.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp
../xc_functional_libxc_wrapper_gcxc.cpp ../xc_functional_libxc.cpp
../xc_functional_libxc_wrapper_gcxc.cpp ../xc_functional_libxc.cpp ../../../source_base/tool_title.cpp
)

AddTest(
TARGET XCTest_HSE
LIBS parameter MPI::MPI_CXX Libxc::xc # required by global.h; for details, `remove_definitions(-D__MPI)`.
SOURCES test_xc1.cpp ../xc_functional.cpp ../xc_functional_libxc.cpp
SOURCES test_xc1.cpp ../xc_functional.cpp ../xc_functional_libxc.cpp ../../../source_base/tool_title.cpp
)


AddTest(
TARGET XCTest_PZ_SPN
LIBS parameter MPI::MPI_CXX Libxc::xc # required by global.h; for details, `remove_definitions(-D__MPI)`.
SOURCES test_xc2.cpp ../xc_functional.cpp ../xc_functional_wrapper_xc.cpp ../xc_functional_wrapper_gcxc.cpp ../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp ../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp
../xc_functional_libxc_wrapper_gcxc.cpp ../xc_functional_libxc_wrapper_xc.cpp ../xc_functional_libxc.cpp
../xc_functional_libxc_wrapper_gcxc.cpp ../xc_functional_libxc_wrapper_xc.cpp ../xc_functional_libxc.cpp ../../../source_base/tool_title.cpp
)

if (USE_CUDA)
Expand All @@ -41,6 +41,7 @@ AddTest(
../../../source_base/libm/branred.cpp
../../../source_base/libm/sincos.cpp
../../../source_base/module_external/blas_connector_base.cpp ../../../source_base/module_external/blas_connector_vector.cpp ../../../source_base/module_external/blas_connector_matrix.cpp
../../../source_base/tool_title.cpp
../../../source_base/module_fft/fft_bundle.cpp
../../../source_base/module_fft/fft_cpu.cpp
${FFT_SRC}
Expand All @@ -57,6 +58,7 @@ AddTest(
../xc_functional_libxc_wrapper_tauxc.cpp
../xc_funct_corr_gga.cpp ../xc_funct_corr_lda.cpp
../xc_funct_exch_gga.cpp ../xc_funct_exch_lda.cpp ../xc_funct_hcth.cpp
../../../source_base/tool_title.cpp
)

AddTest(
Expand All @@ -77,6 +79,7 @@ AddTest(
../../../source_base/matrix.cpp
../../../source_base/memory.cpp
../../../source_base/timer.cpp
../../../source_base/tool_title.cpp
../../../source_base/libm/branred.cpp
../../../source_base/libm/sincos.cpp
../../../source_base/module_fft/fft_bundle.cpp
Expand Down
67 changes: 60 additions & 7 deletions source/source_hamilt/module_xc/xc_functional.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "source_pw/module_pwdft/global.h"
#include "source_io/module_parameter/parameter.h"
#include "source_base/global_function.h"
#include "source_base/tool_title.h"

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

void XC_Functional::set_xc_first_loop(const UnitCell& ucell)
{
ModuleBase::TITLE("XC_Functional", "set_xc_first_loop");
/** In the special "two-level" calculation case,
the first scf iteration only calculate the functional without exact
exchange. but in "nscf" calculation, there is no need of "two-level"
method. */
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "HSE"
|| ucell.atoms[0].ncpp.xc_func == "PBE0"|| ucell.atoms[0].ncpp.xc_func == "LC_PBE"
|| ucell.atoms[0].ncpp.xc_func == "LC_WPBE" || ucell.atoms[0].ncpp.xc_func == "LRC_WPBEH"
|| ucell.atoms[0].ncpp.xc_func == "CAM_PBEH") {
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE")
{
XC_Functional::set_xc_type("pbe");
}
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0") {
XC_Functional::set_xc_type("scan");
else if ( ucell.atoms[0].ncpp.xc_func == "LC_PBE" || ucell.atoms[0].ncpp.xc_func == "LC_WPBE"
|| ucell.atoms[0].ncpp.xc_func == "LRC_WPBEH" || ucell.atoms[0].ncpp.xc_func == "CAM_PBEH" )
{
XC_Functional::set_xc_type("pbe");
}
// added by jghan, 2024-07-07
else if ( ucell.atoms[0].ncpp.xc_func == "MULLER" || ucell.atoms[0].ncpp.xc_func == "POWER"
|| ucell.atoms[0].ncpp.xc_func == "WP22" || ucell.atoms[0].ncpp.xc_func == "CWP22" )
{
XC_Functional::set_xc_type("pbe");
}
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP") {
else if (ucell.atoms[0].ncpp.xc_func == "B3LYP")
{
XC_Functional::set_xc_type("blyp");
}
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0")
{
XC_Functional::set_xc_type("scan");
}
}

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

}

std::string XC_Functional::output_info()
{
#ifdef USE_LIBXC
if(use_libxc)
{
std::stringstream ss;
ss<<" Libxc v"<<xc_version_string()<<std::endl;
ss<<"\t"<<xc_reference()<<std::endl;

std::vector<xc_func_type> funcs = XC_Functional_Libxc::init_func(func_id, XC_UNPOLARIZED);
for(const auto &func : funcs)
{
const xc_func_info_type *info = xc_func_get_info(&func);
ss<<" XC: "<<xc_func_info_get_name(info)<<std::endl;
for(int i=0; i<XC_MAX_REFERENCES; ++i)
{
const func_reference_type *ref = xc_func_info_get_references(func.info, i);
if(ref)
ss<<"\t"<<xc_func_reference_get_ref(ref)<<std::endl;
}
}
XC_Functional_Libxc::finish_func(funcs);
return ss.str();
}
else
{
std::string s = " XC:\t";
for(const auto &id: func_id)
s += std::string(xc_functional_get_name(id))+"\t";
return s;
}
#else
std::string s = " XC:\t";
for(const auto &id: func_id)
s += std::to_string(id)+"\t";
return s;
#endif
}
2 changes: 2 additions & 0 deletions source/source_hamilt/module_xc/xc_functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class XC_Functional
/// Usually in exx caculation, the first SCF loop should be converged with PBE
static void set_xc_first_loop(const UnitCell& ucell);

static std::string output_info();

private:

static std::vector<int> func_id; // libxc id of functional
Expand Down
61 changes: 31 additions & 30 deletions source/source_hamilt/module_xc/xc_functional_libxc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ bool not_supported_xc_with_nonlocal_vdw(const std::string& xc_func_in)

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

const std::vector<std::string> not_supported = {"C09X", "VCML", "HYB_MGGA_XC_WB97M_V", "MGGA_XC_B97M_V"};
for(const std::string& str : not_supported)
Expand All @@ -54,8 +54,8 @@ bool not_supported_xc_with_nonlocal_vdw(const std::string& xc_func_in)
{
std::cout << " WARNING: range-seperated XC omega-B97 family with nonlocal correction term is used.\n"
<< " if you are not planning to use these functionals like wB97X-D3BJ that:\n"
<< " XC_GGA_XC_WB97X_V with specified D3BJ DFT-D3 parameters, this is not what\n"
<< " you want." << std::endl;
<< " XC_GGA_XC_WB97X_V with specified D3BJ DFT-D3 parameters, this is not what\n"
<< " you want." << std::endl;
}
return false;
}
Expand Down Expand Up @@ -92,7 +92,8 @@ int xc_func_type_classifier(const std::string& xc_func,
std::pair<int,std::vector<int>>
XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
{
// check if the functional involves Laplacian of rho
ModuleBase::TITLE("XC_Functional", "set_xc_type_libxc");
// check if the functional involves Laplacian of rho
if (not_supported_xc_with_laplacian(xc_func_in))
{
ModuleBase::WARNING_QUIT("XC_Functional::set_xc_type_libxc",
Expand Down Expand Up @@ -120,14 +121,14 @@ XC_Functional_Libxc::set_xc_type_libxc(const std::string& xc_func_in)
}

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

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

// return
return std::make_pair(func_type, func_id);
return std::make_pair(func_type, func_id);
}

const std::vector<double> in_built_xc_func_ext_params(const int id)
Expand Down Expand Up @@ -176,45 +177,45 @@ const std::vector<double> in_built_xc_func_ext_params(const int id)
return {0.04918, 0.132, 0.2533, 0.349,
0.35/2.29, 2.0/2.29, GlobalC::exx_info.info_global.hse_omega};
// Long-range corrected functionals:
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
case XC_HYB_GGA_XC_LC_PBEOP: // LC version of PBE
{
// This is a range-separated hybrid functional with range-separation constant 0.330,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
// This is a range-separated hybrid functional with range-separation constant 0.330,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
return { GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.33
}
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
case XC_HYB_GGA_XC_LC_WPBE: // Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria
{
// This is a range-separated hybrid functional with range-separation constant 0.400,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
// This is a range-separated hybrid functional with range-separation constant 0.400,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.4
}
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
case XC_HYB_GGA_XC_LRC_WPBE: // Long-range corrected PBE (LRC-wPBE) by by Rohrdanz, Martins and Herbert
{
// This is a range-separated hybrid functional with range-separation constant 0.300,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
// This is a range-separated hybrid functional with range-separation constant 0.300,
// and 0.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -1.0
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.3
}
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
case XC_HYB_GGA_XC_LRC_WPBEH: // Long-range corrected short-range hybrid PBE (LRC-wPBEh) by Rohrdanz, Martins and Herbert
{
// This is a range-separated hybrid functional with range-separation constant 0.200,
// and 20.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
// This is a range-separated hybrid functional with range-separation constant 0.200,
// and 20.0% short-range and 100.0% long-range exact exchange,
// using the error function kernel.
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 1.0
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: -0.8
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.2
}
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
case XC_HYB_GGA_XC_CAM_PBEH: // CAM hybrid screened exchange PBE version
{
// This is a range-separated hybrid functional with range-separation constant 0.700,
// and 100.0% short-range and 20.0% long-range exact exchange,
// using the error function kernel.
// This is a range-separated hybrid functional with range-separation constant 0.700,
// and 100.0% short-range and 20.0% long-range exact exchange,
// using the error function kernel.
return { std::stod(PARAM.inp.exx_fock_alpha[0]), //Fraction of Hartree-Fock exchange: 0.2
std::stod(PARAM.inp.exx_erfc_alpha[0]), //Fraction of short-range exact exchange: 0.8
GlobalC::exx_info.info_global.hse_omega }; //Range separation constant: 0.7
Expand Down Expand Up @@ -287,10 +288,10 @@ XC_Functional_Libxc::init_func(const std::vector<int> &func_id,

void XC_Functional_Libxc::finish_func(std::vector<xc_func_type> &funcs)
{
for(xc_func_type func : funcs)
for(xc_func_type func : funcs)
{
xc_func_end(&func);
}
xc_func_end(&func);
}
}

#endif
14 changes: 7 additions & 7 deletions source/source_hamilt/module_xc/xc_functional_libxc.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ namespace XC_Functional_Libxc
// xc_functional_libxc_vxc.cpp
//-------------------

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

// for mGGA functional
extern std::tuple<double,double,ModuleBase::matrix,ModuleBase::matrix> v_xc_meta(
Expand Down
17 changes: 2 additions & 15 deletions source/source_lcao/module_ri/Exx_LRI_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,20 +135,7 @@ void Exx_LRI_Interface<T, Tdata>::exx_beforescf(const int istep,
}
else
{
if (ucell.atoms[0].ncpp.xc_func == "HF" || ucell.atoms[0].ncpp.xc_func == "PBE0" || ucell.atoms[0].ncpp.xc_func == "HSE")
{
XC_Functional::set_xc_type("pbe");
}
else if (ucell.atoms[0].ncpp.xc_func == "SCAN0")
{
XC_Functional::set_xc_type("scan");
}
// added by jghan, 2024-07-07
else if ( ucell.atoms[0].ncpp.xc_func == "MULLER" || ucell.atoms[0].ncpp.xc_func == "POWER"
|| ucell.atoms[0].ncpp.xc_func == "WP22" || ucell.atoms[0].ncpp.xc_func == "CWP22" )
{
XC_Functional::set_xc_type("pbe");
}
XC_Functional::set_xc_first_loop(ucell);
}

this->cal_exx_ions(ucell,PARAM.inp.out_ri_cv);
Expand Down Expand Up @@ -313,7 +300,7 @@ void Exx_LRI_Interface<T, Tdata>::exx_iter_finish(const K_Vectors& kv,
{
chgmix.close_kerker_gg0();
}
// mohan update 2025-11-04
// mohan update 2025-11-04
this->dm_last_step = dm;
conv_esolver = this->exx_after_converge(
ucell,
Expand Down
Loading