Skip to content

Commit 3e8243a

Browse files
committed
Merge branch 'extended-dftd3' of https://github.com/kirk0830/abacus-develop into extended-dftd3
2 parents 7090cf8 + 15ca24a commit 3e8243a

File tree

12 files changed

+141
-43
lines changed

12 files changed

+141
-43
lines changed

docs/advanced/input_files/input-main.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2923,27 +2923,27 @@ These variables are used to control vdW-corrected related parameters.
29232923

29242924
- **Type**: Real
29252925
- **Availability**: `vdw_method` is set to `d2`, `d3_0`, or `d3_bj`
2926-
- **Description**: This scale factor is used to optimize the interaction energy deviations in van der Waals (vdW) corrected calculations. The recommended values of this parameter are dependent on the chosen vdW correction method and the DFT functional being used. For DFT-D2, the recommended values are 0.75 (PBE), 1.2 (BLYP), 1.05 (B-P86), 1.0 (TPSS), and 1.05 (B3LYP). If not set, will use values of PBE functional. For DFT-D3, recommended values with different DFT functionals can be found on the [here](https://www.chemiebn.uni-bonn.de/pctc/mulliken-center/software/dft-d3/dft-d3). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
2926+
- **Description**: This scale factor is used to optimize the interaction energy deviations in van der Waals (vdW) corrected calculations. The recommended values of this parameter are dependent on the chosen vdW correction method and the DFT functional being used. For DFT-D2, the recommended values are 0.75 (PBE), 1.2 (BLYP), 1.05 (B-P86), 1.0 (TPSS), and 1.05 (B3LYP). If not set, will use values of PBE functional. For DFT-D3, recommended values with different DFT functionals can be found on the [here](https://github.com/dftd3/simple-dftd3/blob/main/assets/parameters.toml). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
29272927
- **Default**:
29282928
- 0.75: if `vdw_method` is set to `d2`
29292929

29302930
### vdw_s8
29312931

29322932
- **Type**: Real
29332933
- **Availability**: `vdw_method` is set to `d3_0` or `d3_bj`
2934-
- **Description**: This scale factor is relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://www.chemiebn.uni-bonn.de/pctc/mulliken-center/software/dft-d3/dft-d3). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
2934+
- **Description**: This scale factor is relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://github.com/dftd3/simple-dftd3/blob/main/assets/parameters.toml). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
29352935

29362936
### vdw_a1
29372937

29382938
- **Type**: Real
29392939
- **Availability**: `vdw_method` is set to `d3_0` or `d3_bj`
2940-
- **Description**: This damping function parameter is relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://www.chemiebn.uni-bonn.de/pctc/mulliken-center/software/dft-d3/dft-d3). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
2940+
- **Description**: This damping function parameter is relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://github.com/dftd3/simple-dftd3/blob/main/assets/parameters.toml). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
29412941

29422942
### vdw_a2
29432943

29442944
- **Type**: Real
29452945
- **Availability**: `vdw_method` is set to `d3_0` or `d3_bj`
2946-
- **Description**: This damping function parameter is only relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://www.chemiebn.uni-bonn.de/pctc/mulliken-center/software/dft-d3/dft-d3). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
2946+
- **Description**: This damping function parameter is only relevant for D3(0) and D3(BJ) van der Waals (vdW) correction methods. The recommended values of this parameter with different DFT functionals can be found on the [webpage](https://github.com/dftd3/simple-dftd3/blob/main/assets/parameters.toml). If not set, will search in ABACUS built-in dataset based on the `dft_functional` keywords. User set value will overwrite the searched value.
29472947

29482948
### vdw_d
29492949

source/module_esolver/esolver_ks_pw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ void ESolver_KS_PW<T, Device>::before_scf(const int istep)
210210
//----------------------------------------------------------
211211
// about vdw, jiyy add vdwd3 and linpz add vdwd2
212212
//----------------------------------------------------------
213-
auto vdw_solver = vdw::make_vdw(GlobalC::ucell, PARAM.inp);
213+
auto vdw_solver = vdw::make_vdw(GlobalC::ucell, PARAM.inp, &(GlobalV::ofs_running));
214214
if (vdw_solver != nullptr)
215215
{
216216
this->pelec->f_en.evdw = vdw_solver->get_energy();

source/module_esolver/lcao_before_scf.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void ESolver_KS_LCAO<TK, TR>::before_scf(const int istep)
198198
//----------------------------------------------------------
199199
// about vdw, jiyy add vdwd3 and linpz add vdwd2
200200
//----------------------------------------------------------
201-
auto vdw_solver = vdw::make_vdw(GlobalC::ucell, PARAM.inp);
201+
auto vdw_solver = vdw::make_vdw(GlobalC::ucell, PARAM.inp, &(GlobalV::ofs_running));
202202
if (vdw_solver != nullptr)
203203
{
204204
this->pelec->f_en.evdw = vdw_solver->get_energy();

source/module_hamilt_general/module_vdw/dftd3_xc_name.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,14 @@ namespace DFTD3 {
344344
void _xcname_libxc_xplusc(const std::string& xcpattern, std::string& xname)
345345
{
346346
std::vector<std::string> xc_words = FmtCore::split(xcpattern, "+");
347+
std::for_each(xc_words.begin(), xc_words.end(), [](std::string& s) {
348+
s = (FmtCore::startswith(s, "XC_")? s: "XC_" + s); }); // add XC_ if not present
347349
assert(xc_words.size() == 2);
348350

349351
std::vector<std::string> words = FmtCore::split(xc_words[0], "_");
350-
const std::string key = (words[2] == "X")? xcpattern: xc_words[1] + "+" + xc_words[0];
351-
352+
const std::string key = (words[2] == "X")?
353+
xc_words[0] + "+" + xc_words[1]: xc_words[1] + "+" + xc_words[0];
354+
352355
if (xcname_libxc_xplusc_.find(key) != xcname_libxc_xplusc_.end()) {
353356
xname = xcname_libxc_xplusc_.at(key);
354357
} else {
@@ -359,9 +362,11 @@ namespace DFTD3 {
359362

360363
void _xcname_libxc_xc(const std::string& xcpattern, std::string& xname)
361364
{
362-
std::vector<std::string> words = FmtCore::split(xcpattern, "_");
363-
if (xcname_libxc_xc_.find(xcpattern) != xcname_libxc_xc_.end()) {
364-
xname = xcname_libxc_xc_.at(xcpattern);
365+
// add XC_ if not present
366+
const std::string key = FmtCore::startswith(xcpattern, "XC_")? xcpattern: "XC_" + xcpattern;
367+
368+
if (xcname_libxc_xc_.find(key) != xcname_libxc_xc_.end()) {
369+
xname = xcname_libxc_xc_.at(key);
365370
} else {
366371
ModuleBase::WARNING_QUIT("ModuleHamiltGeneral::ModuleVDW::DFTD3::xcname_libxc_xc",
367372
"XC's LibXC-notation on `" + xcpattern + "` not recognized");
@@ -380,9 +385,9 @@ namespace DFTD3 {
380385
std::string _xcname(const std::string& xcpattern)
381386
{
382387
std::string xcname = xcpattern;
383-
const std::regex pattern("XC_(LDA|GGA|MGGA|HYB|HYB_LDA|HYB_GGA|HYB_MGGA)_(X|C|XC|K)_(.*)");
388+
const std::regex pattern("(LDA|GGA|MGGA|HYB|HYB_LDA|HYB_GGA|HYB_MGGA)_(X|C|XC|K)_(.*)");
384389
// as long as there is piece in xcpattern that can match, we can search for the corresponding name
385-
if (std::regex_match(xcpattern, pattern)) {
390+
if (std::regex_search(xcpattern, pattern)) {
386391
_xcname_libxc(xcpattern, xcname);
387392
}
388393
return xcname;

source/module_hamilt_general/module_vdw/dftd3_xc_param.h

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ namespace DFTD3 {
421421
"XC (`" + xc + "`)'s DFT-D3M(0) parameters not found");
422422
}
423423
}
424-
else // zero
424+
else if (method == "zero")
425425
{
426426
if (zero.find(xc_lowercase) != zero.end())
427427
{
@@ -433,6 +433,11 @@ namespace DFTD3 {
433433
"XC (`" + xc + "`)'s DFT-D3(0) parameters not found");
434434
}
435435
}
436+
else // should not reach here
437+
{
438+
ModuleBase::WARNING_QUIT("ModuleHamiltGeneral::ModuleVDW::DFTD3::_search",
439+
"Unknown DFT-D3 method: " + method);
440+
}
436441
}
437442

438443
std::string _lowercase(const std::string& s)
@@ -474,7 +479,8 @@ namespace DFTD3 {
474479
double& s6,
475480
double& s8,
476481
double& a1,
477-
double& a2)
482+
double& a2,
483+
std::ofstream* plog = nullptr)
478484
{
479485
const std::map<std::string, std::string> param_map = {
480486
{"d3_bj", "bj"}, {"d3_0", "zero"}, {"d3_bjm", "bjm"}, {"d3_0m", "zerom"},
@@ -498,12 +504,16 @@ namespace DFTD3 {
498504
s8 = (s8_in == "default") ? param[3] : std::stod(s8_in);
499505
a1 = (a1_in == "default") ? param[2] : std::stod(a1_in);
500506
a2 = (a2_in == "default") ? param[5] : std::stod(a2_in);
501-
// param = {s6, s8, a1, a2};
502-
// FmtTable vdwd3tab({"Parameters", "Original", "Autoset"}, 4, {"%10s", "%10s", "%10.4f"});
503-
// const std::vector<std::string> items = {"s6", "s8", "a1", "a2"};
504-
// vdwd3tab << items << flag << param;
505-
// std::cout << "DFT-D3 Dispersion correction parameters autoset\n" << vdwd3tab.str()
506-
// << std::flush;
507+
if (plog != nullptr) // logging the autoset
508+
{
509+
param = {s6, s8, a1, a2};
510+
FmtTable vdwd3tab({"Parameters", "Original", "Autoset"}, 4, {"%10s", "%10s", "%10.4f"});
511+
const std::vector<std::string> items = {"s6", "s8", "a1", "a2"};
512+
vdwd3tab << items << flag << param;
513+
(*plog) << "\nDFT-D3 Dispersion correction parameters autoset\n" << vdwd3tab.str()
514+
<< "XC functional: " << xc_in << std::endl;
515+
}
516+
507517
}
508518
}
509519
}

source/module_hamilt_general/module_vdw/test/dftd3_xc_test.cpp

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,31 @@
44

55
TEST(DFTD3XCTest, SearchXcnameLibXCXplusC)
66
{
7-
std::string xcpattern = "XC_GGA_X_PBE+XC_GGA_C_OP_PBE";
87
std::string xname;
9-
DFTD3::_xcname_libxc_xplusc(xcpattern, xname);
8+
DFTD3::_xcname_libxc_xplusc("XC_GGA_X_PBE+XC_GGA_C_OP_PBE", xname);
9+
EXPECT_EQ(xname, "pbeop");
10+
// then test the case with out prefix XC_
11+
DFTD3::_xcname_libxc_xplusc("GGA_X_PBE+GGA_C_OP_PBE", xname);
1012
EXPECT_EQ(xname, "pbeop");
1113
}
1214

1315
TEST(DFTD3XCTest, SearchXcnameLibXCXC)
1416
{
15-
std::string xcpattern = "XC_LDA_XC_TETER93";
1617
std::string xname;
17-
DFTD3::_xcname_libxc_xc(xcpattern, xname);
18+
DFTD3::_xcname_libxc_xc("XC_LDA_XC_TETER93", xname);
19+
EXPECT_EQ(xname, "teter93");
20+
// then test the case with out prefix XC_
21+
DFTD3::_xcname_libxc_xc("LDA_XC_TETER93", xname);
1822
EXPECT_EQ(xname, "teter93");
1923
}
2024

2125
TEST(DFTD3XCTest, SearchXcnameLibXC)
2226
{
23-
std::string xcpattern = "XC_GGA_X_PBE+XC_GGA_C_OP_PBE";
2427
std::string xname;
25-
DFTD3::_xcname_libxc(xcpattern, xname);
28+
DFTD3::_xcname_libxc("XC_GGA_X_PBE+XC_GGA_C_OP_PBE", xname);
29+
EXPECT_EQ(xname, "pbeop");
30+
// then test the case with out prefix XC_
31+
DFTD3::_xcname_libxc("GGA_X_PBE+GGA_C_OP_PBE", xname);
2632
EXPECT_EQ(xname, "pbeop");
2733
}
2834

@@ -45,6 +51,52 @@ TEST(DFTD3XCTest, SearchXcname)
4551
EXPECT_EQ(xname, "pbe");
4652
}
4753

54+
TEST(DFTD3XCTest, SuccessfulSearch)
55+
{
56+
std::string xc = "pbe";
57+
std::string d3method = "d3_0";
58+
std::string s6_in = "default";
59+
std::string s8_in = "default";
60+
std::string a1_in = "default";
61+
std::string a2_in = "default";
62+
double s6, s8, a1, a2;
63+
DFTD3::dftd3_params(xc, d3method, s6_in, s8_in, a1_in, a2_in, s6, s8, a1, a2);
64+
EXPECT_DOUBLE_EQ(s6, 1.0);
65+
EXPECT_DOUBLE_EQ(s8, 0.722);
66+
EXPECT_DOUBLE_EQ(a1, 1.217);
67+
EXPECT_DOUBLE_EQ(a2, 1.0);
68+
69+
// a more complicated case: MGGA_X_SCAN+MGGA_C_SCAN
70+
xc = "XC_MGGA_X_SCAN+XC_MGGA_C_SCAN";
71+
DFTD3::dftd3_params(xc, d3method, s6_in, s8_in, a1_in, a2_in, s6, s8, a1, a2);
72+
EXPECT_DOUBLE_EQ(s6, 1.0);
73+
EXPECT_DOUBLE_EQ(s8, 0.0);
74+
EXPECT_DOUBLE_EQ(a1, 1.324);
75+
EXPECT_DOUBLE_EQ(a2, 1.0);
76+
77+
// user defines all parameters
78+
s6_in = "1.1";
79+
s8_in = "0.1";
80+
a1_in = "1.325";
81+
a2_in = "1.1";
82+
DFTD3::dftd3_params(xc, d3method, s6_in, s8_in, a1_in, a2_in, s6, s8, a1, a2);
83+
EXPECT_DOUBLE_EQ(s6, 1.1);
84+
EXPECT_DOUBLE_EQ(s8, 0.1);
85+
EXPECT_DOUBLE_EQ(a1, 1.325);
86+
EXPECT_DOUBLE_EQ(a2, 1.1);
87+
88+
// user defines one parameter
89+
s6_in = "1.1";
90+
s8_in = "default";
91+
a1_in = "default";
92+
a2_in = "default";
93+
DFTD3::dftd3_params(xc, d3method, s6_in, s8_in, a1_in, a2_in, s6, s8, a1, a2);
94+
EXPECT_DOUBLE_EQ(s6, 1.1);
95+
EXPECT_DOUBLE_EQ(s8, 0.0);
96+
EXPECT_DOUBLE_EQ(a1, 1.324);
97+
EXPECT_DOUBLE_EQ(a2, 1.0);
98+
}
99+
48100
int main(int argc, char **argv)
49101
{
50102
::testing::InitGoogleTest(&argc, argv);

source/module_hamilt_general/module_vdw/vdw.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,35 @@
66
namespace vdw
77
{
88

9-
std::unique_ptr<Vdw> make_vdw(const UnitCell &ucell, const Input_para &input)
9+
std::unique_ptr<Vdw> make_vdw(const UnitCell &ucell,
10+
const Input_para &input,
11+
std::ofstream* plog)
1012
{
11-
if (ucell.nat < 2 && input.vdw_method != "none")
12-
{
13-
ModuleBase::WARNING("VDW", "Only one atom in this system, and will not do the calculation of VDW");
14-
return nullptr;
15-
}
16-
else if (input.vdw_method == "d2")
13+
// if (ucell.nat < 2 && input.vdw_method != "none")
14+
// {
15+
// ModuleBase::WARNING("VDW", "Only one atom in this system, and will not do the calculation of VDW");
16+
// return nullptr;
17+
// }
18+
if (input.vdw_method == "d2")
1719
{
1820
std::unique_ptr<Vdwd2> vdw_ptr = make_unique<Vdwd2>(ucell);
19-
vdw_ptr->parameter().initial_parameters(input);
21+
vdw_ptr->parameter().initial_parameters(input, plog);
2022
vdw_ptr->parameter().initset(ucell);
2123
return vdw_ptr;
2224
}
2325
else if (input.vdw_method == "d3_0" || input.vdw_method == "d3_bj")
2426
{
2527
std::unique_ptr<Vdwd3> vdw_ptr = make_unique<Vdwd3>(ucell);
26-
vdw_ptr->parameter().initial_parameters(input);
28+
vdw_ptr->parameter().initial_parameters(input, plog);
2729
return vdw_ptr;
2830
}
29-
else
31+
else if (input.vdw_method != "none")
3032
{
33+
ModuleBase::WARNING_QUIT("ModuleHamiltGeneral::ModuleVDW::make_vdw",
34+
"Unrecognized Van der Waals correction method: " + input.vdw_method);
3135
return nullptr;
3236
}
37+
return nullptr; // "none" method
3338
}
3439

3540
} // namespace vdw

source/module_hamilt_general/module_vdw/vdw.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,17 @@ class Vdw
4848
virtual void cal_stress() = 0;
4949
};
5050

51-
std::unique_ptr<Vdw> make_vdw(const UnitCell &ucell, const Input_para &input);
51+
/**
52+
* @brief make vdw correction object
53+
*
54+
* @param ucell UnitCell instance
55+
* @param input Parameter instance
56+
* @param plog optional, for logging the parameter setting process
57+
* @return std::unique_ptr<Vdw>
58+
*/
59+
std::unique_ptr<Vdw> make_vdw(const UnitCell &ucell,
60+
const Input_para &input,
61+
std::ofstream* plog = nullptr);
5262

5363
} // namespace vdw
5464

source/module_hamilt_general/module_vdw/vdwd2_parameters.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace vdw
1010
{
1111

12-
void Vdwd2Parameters::initial_parameters(const Input_para &input)
12+
void Vdwd2Parameters::initial_parameters(const Input_para &input, std::ofstream* plog)
1313
{
1414
scaling_ = std::stod(input.vdw_s6);
1515
damping_ = input.vdw_d;

source/module_hamilt_general/module_vdw/vdwd2_parameters.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ class Vdwd2Parameters : public VdwParameters
3131
void R0_input(const std::string &file, const std::string &unit);
3232

3333
void initset(const UnitCell &ucell); // init sets of vdwd2 once this correction is called
34-
void initial_parameters(const Input_para &input); // initial parameters of Vdwd2 with INPUT file
34+
35+
/**
36+
* @brief initial parameters of Vdwd2 with INPUT file
37+
*
38+
* @param input Parameter instance
39+
* @param plog optional, for logging the parameter setting process (not implemented)
40+
*/
41+
void initial_parameters(const Input_para &input,
42+
std::ofstream* plog = nullptr);
3543

3644
inline const std::map<std::string, double> C6() const { return C6_; }
3745
inline const std::map<std::string, double> R0() const { return R0_; }

0 commit comments

Comments
 (0)