1 /*-------------------------------------------------------------------
2 Copyright 2011 Ravishankar Sundararaman
3
4 This file is part of JDFTx.
5
6 JDFTx is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 JDFTx is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with JDFTx. If not, see <http://www.gnu.org/licenses/>.
18 -------------------------------------------------------------------*/
19
20 #include <commands/command.h>
21 #include <electronic/Everything.h>
22
23
24 EnumStringMap<ExCorrType> exCorrTypeMap(
25 ExCorrLDA_PZ, "lda", //Default LDA is PZ
26 ExCorrLDA_PZ, "lda-PZ",
27 ExCorrLDA_PW, "lda-PW",
28 ExCorrLDA_PW_prec, "lda-PW-prec",
29 ExCorrLDA_VWN, "lda-VWN",
30 ExCorrLDA_Teter, "lda-Teter",
31 ExCorrGGA_PBE, "gga", //Default GGA is PBE
32 ExCorrGGA_PBE, "gga-PBE",
33 ExCorrGGA_PBEsol, "gga-PBEsol",
34 ExCorrGGA_PW91, "gga-PW91",
35 ExCorrMGGA_TPSS, "mgga-TPSS",
36 ExCorrMGGA_revTPSS, "mgga-revTPSS",
37 ExCorrORB_GLLBsc, "orb-GLLBsc",
38 ExCorrPOT_LB94, "pot-LB94",
39 ExCorrHYB_PBE0, "hyb-PBE0",
40 ExCorrHYB_HSE06, "hyb-HSE06",
41 ExCorrHYB_HSE12, "hyb-HSE12",
42 ExCorrHYB_HSE12s, "hyb-HSE12s",
43 ExCorrHF, "Hartree-Fock"
44 );
45 EnumStringMap<ExCorrType> exCorrDescriptionMap(
46 ExCorrLDA_PZ, "Perdew-Zunger LDA",
47 ExCorrLDA_PW, "Perdew-Wang LDA",
48 ExCorrLDA_PW_prec, "Perdew-Wang LDA with extended precision (used by PBE)",
49 ExCorrLDA_VWN, "Vosko-Wilk-Nusair LDA",
50 ExCorrLDA_Teter, "Teter93 LSDA",
51 ExCorrGGA_PBE, "Perdew-Burke-Ernzerhof GGA",
52 ExCorrGGA_PBEsol, "Perdew-Burke-Ernzerhof GGA reparametrized for solids",
53 ExCorrGGA_PW91, "Perdew-Wang GGA",
54 ExCorrMGGA_TPSS, "Tao-Perdew-Staroverov-Scuseria meta GGA",
55 ExCorrMGGA_revTPSS, "revised Tao-Perdew-Staroverov-Scuseria meta GGA",
56 ExCorrORB_GLLBsc, "Orbital-dependent GLLB-sc potential (no total energy)",
57 ExCorrPOT_LB94, "van Leeuwen-Baerends model potential (no total energy)",
58 ExCorrHYB_PBE0, "Hybrid PBE with 1/4 exact exchange",
59 ExCorrHYB_HSE06, "HSE06 'wPBEh' hybrid with 1/4 screened exact exchange",
60 ExCorrHYB_HSE12, "Reparametrized screened exchange functional for accuracy (w=0.185 A^-1 and a=0.313)",
61 ExCorrHYB_HSE12s, "Reparametrized screened exchange functional for k-point convergence (w=0.408 A^-1 and a=0.425)",
62 ExCorrHF, "Full exact exchange with no correlation"
63 );
64
65 EnumStringMap<KineticType> kineticTypeMap(
66 KineticTF, "lda-TF",
67 KineticVW, "gga-vW",
68 KineticPW91, "gga-PW91k"
69 );
70 EnumStringMap<KineticType> kineticDescriptionMap(
71 KineticTF, "Thomas-Fermi LDA kinetic energy",
72 KineticVW, "von Weisacker correction to LDA kinetic energy",
73 KineticPW91, "Perdew-Wang GGA kinetic energy parameterized by Lembarki and Chermette"
74 );
75
76
77 #ifdef LIBXC_ENABLED
78 #include <xc.h>
79 #include <xcMap.h> //autogenerated during cmake
80
81 //Get description by temporarily initializing functional:
getLibXCdescription(const string & name,const EnumStringMap<int> & map)82 string getLibXCdescription(const string& name, const EnumStringMap<int>& map)
83 { int xcCode = 0;
84 bool xcFound = map.getEnum(name.c_str(), xcCode);
85 assert(xcFound && xcCode);
86 xc_func_type func;
87 if(xc_func_init(&func, xcCode, XC_UNPOLARIZED) != 0)
88 die("Error obtaining description for LibXC functional %s.\n", name.c_str());
89 string desc(func.info->name);
90 xc_func_end(&func);
91 return desc;
92 }
getLibXCdescription_X(const string & name)93 string getLibXCdescription_X(const string& name) { return getLibXCdescription(name, xcMap_X); }
getLibXCdescription_C(const string & name)94 string getLibXCdescription_C(const string& name) { return getLibXCdescription(name, xcMap_C); }
getLibXCdescription_XC(const string & name)95 string getLibXCdescription_XC(const string& name) { return getLibXCdescription(name, xcMap_XC); }
getLibXCdescription_K(const string & name)96 string getLibXCdescription_K(const string& name) { return getLibXCdescription(name, xcMap_K); }
97 #endif //LIBXC_ENABLED
98
99
100 struct CommandElecExCorr : public Command
101 {
CommandElecExCorrCommandElecExCorr102 CommandElecExCorr(const char* cmdName = "elec-ex-corr", string path="jdftx/Electronic/Functional") : Command(cmdName, path)
103 {
104 format = "<functional>";
105 comments = "Specify the exchange-correlation functional, where <functional> is one of:"
106 + addDescriptions(exCorrTypeMap.optionList(), linkDescription(exCorrTypeMap, exCorrDescriptionMap))
107 + ".\n\nNote that lda is an alias for lda-pz, and gga for gga-pbe.\n\n";
108 hasDefault = true;
109 emptyParamError = " eXchange/Correlation functional(s) must be specified.";
110
111 #ifdef LIBXC_ENABLED
112 format += "\n\t| <funcX> <funcC>\n\t| <funcXC>";
113 comments +=
114 "The second and third lines use eXchange/Correlation functionals from libXC \\cite LibXC.\n"
115 "The exact entries below will depend on the version of LibXC linked against.\n"
116 "Here, <funcX> is one of:"
117 + addDescriptions(xcMap_X.optionList(), getLibXCdescription_X)
118 + ",\n\n<funcC> is one of:"
119 + addDescriptions(xcMap_C.optionList(), getLibXCdescription_C)
120 + ",\n\nand <funcXC> is one of:"
121 + addDescriptions(xcMap_XC.optionList(), getLibXCdescription_XC)
122 + ".";
123 #else
124 comments += "Additional functionals can be enabled by compiling with LibXC support \\cite LibXC.";
125 #endif
126 }
127
processCommandElecExCorr128 void process(ParamList& pl, Everything& e)
129 { process(pl, e.exCorr);
130 }
131
printStatusCommandElecExCorr132 void printStatus(Everything& e, int iRep)
133 { printStatus(e.exCorr);
134 }
135
136 protected:
processCommandElecExCorr137 void process(ParamList& pl, ExCorr& exCorr)
138 { string key;
139 pl.get(key, string(), "functional");
140 if(key.length()) //Otherwise default functional set by ExCorr constructor
141 { if(exCorrTypeMap.getEnum(key.c_str(), exCorr.exCorrType)) //Found internal ExCorr functional
142 { //Set the functional name:
143 exCorr.xcName = string(exCorrTypeMap.getString(exCorr.exCorrType));
144 }
145 #ifdef LIBXC_ENABLED
146 else if(xcMap_X.getEnum(key.c_str(), exCorr.xcExchange)) {} //Found LibXC Exchange functional
147 else if(xcMap_XC.getEnum(key.c_str(), exCorr.xcExcorr)) {} //Found LibXC ExCorr functional
148 #endif
149 else throw key + " is not a recognized exchange or exchange-correlation functional";
150 }
151 #ifdef LIBXC_ENABLED
152 if((exCorr.xcExchange || exCorr.xcExcorr) && !exCorr.xcCorr)
153 { //LibXC will be used:
154 exCorr.exCorrType = ExCorrLibXC;
155 if(exCorr.xcExchange)
156 pl.get(exCorr.xcCorr, 0, xcMap_C, "funcC", true); //required correlation functional
157 //Set the short name:
158 if(exCorr.xcExcorr)
159 exCorr.xcName = string(xcMap_XC.getString(exCorr.xcExcorr));
160 else
161 exCorr.xcName = string(xcMap_X.getString(exCorr.xcExchange))
162 + ':' + string(xcMap_C.getString(exCorr.xcCorr));
163 }
164 #endif
165 }
166
printStatusCommandElecExCorr167 void printStatus(const ExCorr& exCorr)
168 { switch(exCorr.exCorrType)
169 {
170 #ifdef LIBXC_ENABLED
171 case ExCorrLibXC:
172 { if(exCorr.xcExcorr)
173 logPrintf("%s", xcMap_XC.getString(exCorr.xcExcorr));
174 else
175 logPrintf("%s %s", xcMap_X.getString(exCorr.xcExchange), xcMap_C.getString(exCorr.xcCorr));
176 break;
177 }
178 #endif
179 default:
180 logPrintf("%s", exCorrTypeMap.getString(exCorr.exCorrType));
181 }
182 }
183 }
184 commandElecExCorr;
185
186
187 struct CommandElecExCorrCompare : public CommandElecExCorr
188 {
CommandElecExCorrCompareCommandElecExCorrCompare189 CommandElecExCorrCompare() : CommandElecExCorr("elec-ex-corr-compare")
190 {
191 format = "<functional>";
192 comments =
193 "Compute total energies for other functionals at the final state for comparison.\n"
194 "The available options for each parameter are identical to elec-ex-corr.\n"
195 "\n"
196 "This command may be specified multiple times. It invokes 'dump End ExcCompare'\n"
197 "automatically, but the compute frequency can be controlled using dump explicitly.";
198 hasDefault = false;
199 allowMultiple = true;
200 emptyParamError = " eXchange/Correlation functional(s) must be specified.";
201
202 #ifdef LIBXC_ENABLED
203 format += "\n\t| <funcX> <funcC>\n\t| <funcXC>";
204 #endif
205 forbid("fix-electron-density");
206 forbid("fix-electron-potential");
207 }
208
processCommandElecExCorrCompare209 void process(ParamList& pl, Everything& e)
210 { e.exCorrDiff.push_back(std::shared_ptr<ExCorr>(new ExCorr));
211 CommandElecExCorr::process(pl, *e.exCorrDiff.back());
212 e.dump.insert(std::make_pair(DumpFreq_End, DumpExcCompare));
213 }
214
printStatusCommandElecExCorrCompare215 void printStatus(Everything& e, int iRep)
216 { CommandElecExCorr::printStatus(*e.exCorrDiff[iRep]);
217 }
218 }
219 commandElecExCorrCompare;
220
221
222 struct CommandFluidExCorr : public CommandElecExCorr
223 {
CommandFluidExCorrCommandFluidExCorr224 CommandFluidExCorr() : CommandElecExCorr("fluid-ex-corr", "jdftx/Fluid/Parameters")
225 {
226 format = "<kinetic> [<exchange-correlation>]";
227 comments =
228 "Kinetic energy functional for fluid convolution coupling where <kinetic> is one of:"
229 + addDescriptions(kineticTypeMap.optionList(), linkDescription(kineticTypeMap, kineticDescriptionMap)) +
230 #ifdef LIBXC_ENABLED
231 addDescriptions(xcMap_K.optionList(), getLibXCdescription_K) +
232 #endif
233 ".\n\nThe available options for <exchange-correlation> are identical to elec-ex-corr\n"
234 "and defaults to lda-pz.";
235 hasDefault = true;
236 emptyParamError = " A kinetic energy functional must be specified.";
237 require("elec-ex-corr");
238 }
239
processCommandFluidExCorr240 void process(ParamList& pl, Everything& e)
241 { ExCorr& fluidExCorr = e.eVars.fluidParams.exCorr;
242 //Get kinetic energy functional:
243 string key; pl.get(key, string(), "kinetic");
244 if(!key.length()) fluidExCorr.kineticType = KineticTF; //default: Thomas-Fermi
245 else
246 { if(kineticTypeMap.getEnum(key.c_str(), fluidExCorr.kineticType)) {} //Found internal kinetic functional
247 #ifdef LIBXC_ENABLED
248 else if(xcMap_K.getEnum(key.c_str(), fluidExCorr.xcKinetic)) { fluidExCorr.kineticType = KineticLibXC; } //Found LibXC kinetic functional
249 #endif
250 else throw key + " is not a recognized kinetic energy functional";
251 }
252 //Set default exchange-correlation to be LDA
253 fluidExCorr.exCorrType = ExCorrLDA_PZ;
254 fluidExCorr.xcName = exCorrTypeMap.getString(ExCorrLDA_PZ);
255
256 CommandElecExCorr::process(pl, fluidExCorr);
257 }
258
printStatusCommandFluidExCorr259 void printStatus(Everything& e, int iRep)
260 { const ExCorr& fluidExCorr = e.eVars.fluidParams.exCorr;
261 switch(fluidExCorr.exCorrType)
262 {
263 #ifdef LIBXC_ENABLED
264 case KineticLibXC: logPrintf("%s ", xcMap_K.getString(fluidExCorr.xcKinetic)); break;
265 #endif
266 default: logPrintf("%s ", kineticTypeMap.getString(fluidExCorr.kineticType));
267 }
268 CommandElecExCorr::printStatus(fluidExCorr);
269 }
270 }
271 commandFluidExCorr;
272
273
274 struct CommandVanDerWaals : public Command
275 {
CommandVanDerWaalsCommandVanDerWaals276 CommandVanDerWaals() : Command("van-der-waals", "jdftx/Electronic/Functional")
277 {
278 format = "[<scaleOverride>=0]";
279 comments =
280 "DFT+D2 pair-potential corrections for the long range Van der Waals\n"
281 "interaction [S. Grimme, J. Comput. Chem. 27: 1787–1799 (2006)].\n"
282 "\n"
283 "Default scale factors are available for the gga-PBE, hyb-gga-xc-b3lyp\n"
284 "and mgga-TPSS exchange-correlation functionals (see elec-ex-corr).\n"
285 "Manually specify <scaleOverride> to use with other functionals";
286 }
287
processCommandVanDerWaals288 void process(ParamList& pl, Everything& e)
289 { e.iInfo.vdWenable = true;
290 pl.get(e.iInfo.vdWscale, 0., "scaleOverride");
291 }
292
printStatusCommandVanDerWaals293 void printStatus(Everything& e, int iRep)
294 { if(e.iInfo.vdWscale) logPrintf("%lg", e.iInfo.vdWscale);
295 }
296 }
297 commandVanDerWaals;
298
299
300 struct CommandExchangeParameters : public Command
301 {
CommandExchangeParametersCommandExchangeParameters302 CommandExchangeParameters() : Command("exchange-parameters", "jdftx/Electronic/Functional")
303 {
304 format = "<exxScale> [<exxOmega>=0]";
305 comments =
306 "Override exact-exchange parameters in a hybrid functional.\n"
307 "Here <exxScale> is the scale fraction of exact exchange,\n"
308 "and <exxOmega> is the screening parameter.\n"
309 "This is only supported for internal hybrid functionals PBE0\n"
310 "and HSExx, and not for the LibXC hybrid functionals.";
311 }
312
processCommandExchangeParameters313 void process(ParamList& pl, Everything& e)
314 { pl.get(e.exCorr.exxScaleOverride, 0., "exxScale", true);
315 pl.get(e.exCorr.exxOmegaOverride, 0., "exxOmega");
316 if(e.exCorr.exxScaleOverride <= 0.) throw string("<exxScale> must be >= 0");
317 }
318
printStatusCommandExchangeParameters319 void printStatus(Everything& e, int iRep)
320 { logPrintf(" %lg", e.exCorr.exxScaleOverride);
321 if(e.exCorr.exxOmegaOverride) logPrintf(" %lg", e.exCorr.exxOmegaOverride);
322 }
323 }
324 commandExchangeParameters;
325
326
327 struct CommandExchangeBlockSize : public Command
328 {
CommandExchangeBlockSizeCommandExchangeBlockSize329 CommandExchangeBlockSize() : Command("exchange-block-size", "jdftx/Electronic/Functional")
330 {
331 format = "<blockSize>";
332 comments =
333 "Number of bands in blocks of FFTs used in exact-exchange calculation.\n"
334 "Larger values should improve performance, at the expense of greater\n"
335 "memory requirements. (Default: 16)";
336 }
337
processCommandExchangeBlockSize338 void process(ParamList& pl, Everything& e)
339 { pl.get(e.cntrl.exxBlockSize, 0, "blockSize", true);
340 if(e.cntrl.exxBlockSize < 1) throw string("<blockSize> must be >= 1");
341 }
342
printStatusCommandExchangeBlockSize343 void printStatus(Everything& e, int iRep)
344 { logPrintf(" %d", e.cntrl.exxBlockSize);
345 }
346 }
347 commandExchangeBlockSize;
348