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 //! @file elec_misc.cpp Miscellaneous properties of the electronic system
24
25 struct CommandElecCutoff : public Command
26 {
CommandElecCutoffCommandElecCutoff27 CommandElecCutoff() : Command("elec-cutoff", "jdftx/Electronic/Parameters")
28 {
29 format = "<Ecut> [<EcutRho>=0]";
30 comments = "Electronic planewave cutoff in Hartree. Optionally specify charge density cutoff\n"
31 "<EcutRho> in hartrees. If unspecified or zero, EcutRho is taken to be 4*Ecut.";
32 hasDefault = true;
33 }
34
processCommandElecCutoff35 void process(ParamList& pl, Everything& e)
36 { pl.get(e.cntrl.Ecut, 20., "Ecut");
37 pl.get(e.cntrl.EcutRho, 0., "EcutRho");
38 if(e.cntrl.EcutRho && e.cntrl.EcutRho < 4*e.cntrl.Ecut)
39 throw string("<EcutRho> must be at least 4 <Ecut>");
40 }
41
printStatusCommandElecCutoff42 void printStatus(Everything& e, int iRep)
43 { logPrintf("%lg", e.cntrl.Ecut);
44 if(e.cntrl.EcutRho)
45 logPrintf(" %lg", e.cntrl.EcutRho);
46 }
47 }
48 commandElecCutoff;
49
50 //-------------------------------------------------------------------------------------------------
51
52 struct CommandFftbox : public Command
53 {
CommandFftboxCommandFftbox54 CommandFftbox() : Command("fftbox", "jdftx/Electronic/Parameters")
55 {
56 format = "<S0> <S1> <S2>";
57 comments = "Manually override the real space grid dimensions used for scalar fields.\n"
58 "(The default values are calculated based on the EcutRho setting from elec-cutoff).";
59 }
60
processCommandFftbox61 void process(ParamList& pl, Everything& e)
62 { pl.get(e.gInfo.S[0], 0, "S0", true);
63 pl.get(e.gInfo.S[1], 0, "S1", true);
64 pl.get(e.gInfo.S[2], 0, "S2", true);
65 }
66
printStatusCommandFftbox67 void printStatus(Everything& e, int iRep)
68 { logPrintf("%d %d %d", e.gInfo.S[0], e.gInfo.S[1], e.gInfo.S[2]);
69 }
70 }
71 commandFftbox;
72
73 //-------------------------------------------------------------------------------------------------
74
75 struct CommandElecNbands : public Command
76 {
CommandElecNbandsCommandElecNbands77 CommandElecNbands() : Command("elec-n-bands", "jdftx/Electronic/Parameters")
78 {
79 format = "<n>";
80 comments = "Manually specify the number of bands.\n\n"
81 "(Default: set nBands assuming insulator, or in calculations with\n"
82 "fermi-fillings, set equal to total number of atomic orbitals.)";
83 }
84
processCommandElecNbands85 void process(ParamList& pl, Everything& e)
86 { pl.get(e.eInfo.nBands, 0, "n", true);
87 if(e.eInfo.nBands<=0) throw string("<n> must be positive.\n");
88 }
89
printStatusCommandElecNbands90 void printStatus(Everything& e, int iRep)
91 { logPrintf("%d", e.eInfo.nBands);
92 }
93 }
94 commandElecNbands;
95
96 //-------------------------------------------------------------------------------------------------
97
98 struct CommandDavidsonBandRatio : public Command
99 {
CommandDavidsonBandRatioCommandDavidsonBandRatio100 CommandDavidsonBandRatio() : Command("davidson-band-ratio", "jdftx/Electronic/Optimization")
101 {
102 format = "[<ratio>=1.1]";
103 comments =
104 "Ratio of number of bands in the Davidson working set to the\n"
105 "number of actual bands in the calculation. Increasing this\n"
106 "number should improve eigen-problem convergence at the\n"
107 "expense of increased memory requirements.";
108 hasDefault = true;
109 }
110
processCommandDavidsonBandRatio111 void process(ParamList& pl, Everything& e)
112 { pl.get(e.cntrl.davidsonBandRatio, 1.1, "ratio");
113 if(e.cntrl.davidsonBandRatio < 1.)
114 throw string("<ratio> must be at least 1");
115 }
116
printStatusCommandDavidsonBandRatio117 void printStatus(Everything& e, int iRep)
118 { logPrintf("%lg", e.cntrl.davidsonBandRatio);
119 }
120 }
121 commandDavidsonBandRatio;
122
123 //-------------------------------------------------------------------------------------------------
124
125 struct CommandLcaoParams : public Command
126 {
CommandLcaoParamsCommandLcaoParams127 CommandLcaoParams() : Command("lcao-params", "jdftx/Initialization")
128 {
129 format = "[<nIter>=-1] [<Ediff>=1e-6] [<smeaingWidth>=1e-3]";
130 comments = "Control LCAO wavefunction initialization:\n"
131 "+ <nIter>: maximum subspace iterations in LCAO (negative => auto-select)\n"
132 "+ <Ediff>: energy-difference convergence threshold for subspace iteration\n"
133 "+ <smearingWidth>: smearing width for the subspace iteration for constant fillings calculations.\n"
134 " If present, the smearing width from elec-smearing overrides this.\n";
135 hasDefault = true;
136 }
137
processCommandLcaoParams138 void process(ParamList& pl, Everything& e)
139 { pl.get(e.eVars.lcaoIter, -1, "nIter");
140 pl.get(e.eVars.lcaoTol, 1e-6, "Ediff");
141 pl.get(e.eInfo.smearingWidth, 1e-3, "smearingWidth");
142 if(e.eInfo.smearingWidth<=0) throw string("<smearingWidth> must be positive.\n");
143 }
144
printStatusCommandLcaoParams145 void printStatus(Everything& e, int iRep)
146 { logPrintf("%d %lg %lg", e.eVars.lcaoIter, e.eVars.lcaoTol, e.eInfo.smearingWidth);
147 }
148 }
149 commandLcaoParams;
150
151 //-------------------------------------------------------------------------------------------------
152
153 EnumStringMap<SpinType> spinMap
154 ( SpinNone, "no-spin",
155 SpinZ, "z-spin",
156 SpinVector, "vector-spin",
157 SpinOrbit, "spin-orbit"
158 );
159
160 EnumStringMap<SpinType> spinDescMap
161 ( SpinNone, "Unpolarized calculation",
162 SpinZ, "Spin-polarized calculation",
163 SpinVector, "Non-collinear magnetism (supports spin-orbit coupling)",
164 SpinOrbit, "Non-collinear without magnetization, to allow for spin-orbit"
165 );
166
167 struct CommandSpintype : public Command
168 {
CommandSpintypeCommandSpintype169 CommandSpintype() : Command("spintype", "jdftx/Electronic/Parameters")
170 {
171 format = "<type>=" + spinMap.optionList();
172 comments = "Select spin-polarization type:"
173 + addDescriptions(spinMap.optionList(), linkDescription(spinMap, spinDescMap));
174 hasDefault = true;
175 }
176
processCommandSpintype177 void process(ParamList& pl, Everything& e)
178 { pl.get(e.eInfo.spinType, SpinNone, spinMap, "type");
179 }
180
printStatusCommandSpintype181 void printStatus(Everything& e, int iRep)
182 { fputs(spinMap.getString(e.eInfo.spinType), globalLog);
183 }
184 }
185 commandSpintype;
186
187 //-------------------------------------------------------------------------------------------------
188
189 //Base class for fix-electron-density and fix-electron-potential
190 struct CommandFixElectronHamiltonian : public Command
191 {
CommandFixElectronHamiltonianCommandFixElectronHamiltonian192 CommandFixElectronHamiltonian(string name) : Command("fix-electron-"+name, "jdftx/Electronic/Optimization")
193 {
194 format = "<filenamePattern>";
195 comments = "Perform band structure calculations at fixed electron " + name + "\n"
196 "(or spin " + name + ") read from the specified <filenamePattern>.\n"
197 "This pattern must include $VAR which will be replaced by the appropriate\n"
198 "variable names accounting for spin-polarization (same as used for dump).\n"
199 "Meta-GGA calculations will also require the corresponding kinetic " + name + ".";
200
201 require("spintype");
202 forbid("elec-ex-corr-compare");
203 forbid("electronic-scf");
204 forbid("vibrations");
205 forbid("dump-only");
206 forbid("target-mu");
207 forbid("target-Bz");
208 }
209
processCommonCommandFixElectronHamiltonian210 void processCommon(ParamList& pl, Everything& e, string& targetFilenamePattern)
211 { pl.get(targetFilenamePattern, string(), "filenamePattern", true);
212 if(targetFilenamePattern.find("$VAR") == string::npos)
213 throw string("<filenamePattern> must contain $VAR");
214 e.cntrl.fixed_H = true;
215 }
216
printStatusCommonCommandFixElectronHamiltonian217 void printStatusCommon(Everything& e, int iRep, const string& targetFilenamePattern)
218 { logPrintf("%s", targetFilenamePattern.c_str());
219 }
220 };
221
222 struct CommandFixElectronDensity : public CommandFixElectronHamiltonian
CommandFixElectronDensityCommandFixElectronDensity223 { CommandFixElectronDensity() : CommandFixElectronHamiltonian("density") { forbid("fix-electron-potential"); }
224 void process(ParamList& pl, Everything& e) { processCommon(pl, e, e.eVars.nFilenamePattern); }
225 void printStatus(Everything& e, int iRep) { printStatusCommon(e, iRep, e.eVars.nFilenamePattern); }
226 }
227 commandFixElectronDensity;
228
229 struct CommandFixElectronPotential : public CommandFixElectronHamiltonian
CommandFixElectronPotentialCommandFixElectronPotential230 { CommandFixElectronPotential() : CommandFixElectronHamiltonian("potential") { forbid("fix-electron-density"); }
231 void process(ParamList& pl, Everything& e) { processCommon(pl, e, e.eVars.VFilenamePattern); }
232 void printStatus(Everything& e, int iRep) { printStatusCommon(e, iRep, e.eVars.VFilenamePattern); }
233 }
234 commandFixElectronPotential;
235
236 //-------------------------------------------------------------------------------------------------
237
238 struct CommandConvergeEmptyStates : public Command
239 {
CommandConvergeEmptyStatesCommandConvergeEmptyStates240 CommandConvergeEmptyStates() : Command("converge-empty-states", "jdftx/Electronic/Optimization")
241 {
242 format = "yes|no";
243 comments = "Whether to converge empty states after each electronic optimization (default no).\n"
244 "Not required unless empty states are used in post-processing and need to be accurate.\n"
245 "This is a shortcut to running a bandstructure calculation after a total energy\n"
246 "or SCF calculation, and helps simplify workflow for DOS, polarizability, wannier\n"
247 "and electron-phonon matrix element calculations.";
248 }
249
processCommandConvergeEmptyStates250 void process(ParamList& pl, Everything& e)
251 { pl.get(e.cntrl.convergeEmptyStates, false, boolMap, "shouldConverge", true);
252 }
253
printStatusCommandConvergeEmptyStates254 void printStatus(Everything& e, int iRep)
255 { logPrintf("%s", boolMap.getString(e.cntrl.convergeEmptyStates));
256 }
257 }
258 commandConvergeEmptyStates;
259
260 //-------------------------------------------------------------------------------------------------
261
262 struct CommandWavefunctionDrag : public Command
263 {
CommandWavefunctionDragCommandWavefunctionDrag264 CommandWavefunctionDrag() : Command("wavefunction-drag", "jdftx/Ionic/Optimization")
265 {
266 format = "yes|no";
267 comments =
268 "Drag wavefunctions when ions are moved using atomic orbital projections (yes by default).";
269 }
270
processCommandWavefunctionDrag271 void process(ParamList& pl, Everything& e)
272 { pl.get(e.cntrl.dragWavefunctions, true, boolMap, "shouldDrag", true);
273 }
274
printStatusCommandWavefunctionDrag275 void printStatus(Everything& e, int iRep)
276 { logPrintf("%s", boolMap.getString(e.cntrl.dragWavefunctions));
277 }
278 }
279 commandWavefunctionDrag;
280
281 //-------------------------------------------------------------------------------------------------
282
283 struct CommandCacheProjectors : public Command
284 {
CommandCacheProjectorsCommandCacheProjectors285 CommandCacheProjectors() : Command("cache-projectors", "jdftx/Miscellaneous")
286 {
287 format = "yes|no";
288 comments =
289 "Cache nonlocal-pseudopotential projectors (yes by default); turn off to save memory.";
290 }
291
processCommandCacheProjectors292 void process(ParamList& pl, Everything& e)
293 { pl.get(e.cntrl.cacheProjectors, true, boolMap, "shouldCache", true);
294 }
295
printStatusCommandCacheProjectors296 void printStatus(Everything& e, int iRep)
297 { logPrintf("%s", boolMap.getString(e.cntrl.cacheProjectors));
298 }
299 }
300 commandCacheProjectors;
301
302 //-------------------------------------------------------------------------------------------------
303
304 struct CommandBasis : public Command
305 {
CommandBasisCommandBasis306 CommandBasis() : Command("basis", "jdftx/Electronic/Parameters")
307 {
308 format = "<kdep>=" + kdepMap.optionList();
309 comments = "Basis set at each k-point (default), or single basis set at gamma point";
310 hasDefault = true;
311 }
312
processCommandBasis313 void process(ParamList& pl, Everything& e)
314 { pl.get(e.cntrl.basisKdep, BasisKpointDep, kdepMap, "kdep");
315 }
316
printStatusCommandBasis317 void printStatus(Everything& e, int iRep)
318 { fputs(kdepMap.getString(e.cntrl.basisKdep), globalLog);
319 }
320 }
321 commandBasis;
322
323
324 //-------------------------------------------------------------------------------------------------
325
326 static EnumStringMap<ElecEigenAlgo> elecEigenMap(ElecEigenCG, "CG", ElecEigenDavidson, "Davidson");
327
328 struct CommandElecEigenAlgo : public Command
329 {
CommandElecEigenAlgoCommandElecEigenAlgo330 CommandElecEigenAlgo() : Command("elec-eigen-algo", "jdftx/Electronic/Optimization")
331 {
332 format = "<algo>=" + elecEigenMap.optionList();
333 comments = "Selects eigenvalue algorithm for band-structure calculations or inner loop of SCF.";
334 hasDefault = true;
335 }
336
processCommandElecEigenAlgo337 void process(ParamList& pl, Everything& e)
338 { pl.get(e.cntrl.elecEigenAlgo, ElecEigenDavidson, elecEigenMap, "algo");
339 }
340
printStatusCommandElecEigenAlgo341 void printStatus(Everything& e, int iRep)
342 { fputs(elecEigenMap.getString(e.cntrl.elecEigenAlgo), globalLog);
343 }
344 }
345 commandElecEigenAlgo;
346
347 //-------------------------------------------------------------------------------------------------
348
349 struct CommandRhoExternal : public Command
350 {
CommandRhoExternalCommandRhoExternal351 CommandRhoExternal() : Command("rhoExternal", "jdftx/Coulomb interactions")
352 {
353 format = "<filename> [<includeSelfEnergy>=yes|no]";
354 comments =
355 "Include an external charge density [electrons/bohr^3] (real space binary)\n"
356 "which interacts electrostatically with the electrons, nuclei and fluid.\n"
357 "\n"
358 "If <includeSelfEnergy>=yes (default no), then the Coulomb self-energy\n"
359 "of rhoExternal is included in the output energy.";
360 }
361
processCommandRhoExternal362 void process(ParamList& pl, Everything& e)
363 { pl.get(e.eVars.rhoExternalFilename, string(), "filename", true);
364 pl.get(e.eVars.rhoExternalSelfEnergy, false, boolMap, "includeSelfEnergy");
365 }
366
printStatusCommandRhoExternal367 void printStatus(Everything& e, int iRep)
368 { logPrintf("%s %s", e.eVars.rhoExternalFilename.c_str(), boolMap.getString(e.eVars.rhoExternalSelfEnergy));
369 }
370 }
371 commandRhoExternal;
372
373 //-------------------------------------------------------------------------------------------------
374
375 struct CommandVexternal : public Command
376 {
CommandVexternalCommandVexternal377 CommandVexternal() : Command("Vexternal", "jdftx/Electronic/Parameters")
378 {
379 format = "<filename> | <filenameUp> <filenameDn>";
380 comments =
381 "Include an external potential (in hartrees) for the electrons\n"
382 "(real space binary). Specify two files if V is spin-polarized.";
383 }
384
processCommandVexternal385 void process(ParamList& pl, Everything& e)
386 { e.eVars.VexternalFilename.resize(1);
387 pl.get(e.eVars.VexternalFilename[0], string(), "filename", true);
388 //Check if a second file has been specified:
389 string filenameDn;
390 pl.get(filenameDn, string(), "filenameDn");
391 if(filenameDn.length())
392 e.eVars.VexternalFilename.push_back(filenameDn);
393 }
394
printStatusCommandVexternal395 void printStatus(Everything& e, int iRep)
396 { for(const string& filename: e.eVars.VexternalFilename)
397 logPrintf("%s ", filename.c_str());
398 }
399 }
400 commandVexternal;
401
402 //-------------------------------------------------------------------------------------------------
403
404 struct CommandBoxPotential : public Command
405 {
CommandBoxPotentialCommandBoxPotential406 CommandBoxPotential() : Command("box-potential", "jdftx/Electronic/Parameters")
407 {
408 format = "xmin xmax ymin ymax zmin zmax Vin Vout [<convolve_radius>=0.1]";
409 comments =
410 "Include an step-function shaped external potential (in hartrees) for the electrons";
411
412 allowMultiple = true;
413 }
414
processCommandBoxPotential415 void process(ParamList& pl, Everything& e)
416 { ElecVars::BoxPotential bP;
417 const char* dirNames[3] = { "x", "y", "z" };
418 for(int k=0; k<3; k++)
419 { pl.get(bP.min[k], 0., dirNames[k]+string("min"), true);
420 pl.get(bP.max[k], 0., dirNames[k]+string("max"), true);
421 if(bP.max[k]<bP.min[k])
422 throw(string("max must be smaller than min for each dimension"));
423 }
424 pl.get(bP.Vin, 0., "Vin", true);
425 pl.get(bP.Vout, 0., "Vout", true);
426 pl.get(bP.convolve_radius, 0.2, "convolve_radius", false);
427 e.eVars.boxPot.push_back(bP);
428 }
429
printStatusCommandBoxPotential430 void printStatus(Everything& e, int iRep)
431 { const ElecVars::BoxPotential& bP = e.eVars.boxPot[iRep];
432 logPrintf("%.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g %.5g",
433 bP.min[0], bP.max[0], bP.min[1], bP.max[1], bP.min[2], bP.max[2],
434 bP.Vin, bP.Vout, bP.convolve_radius);
435 }
436 }
437 commandBoxPot;
438
439 //-------------------------------------------------------------------------------------------------
440
441 struct CommandElectricField : public Command
442 {
CommandElectricFieldCommandElectricField443 CommandElectricField() : Command("electric-field", "jdftx/Electronic/Parameters")
444 {
445 format = "<Ex> <Ey> <Ez>";
446 comments =
447 "Apply an external electric field (in Cartesian coordinates, atomic\n"
448 "units [Eh/e/a_0] and electron-is-positive sign convention).\n\n"
449 "In truncated directions, the field will be applied as a ramp potential,\n"
450 "and for periodic directions, it will be applied as a plane wave with\n"
451 "the smallest commensurate wave vector and amplitude set by peak field.\n\n"
452 "Coulomb truncation, if any, must be in embedded mode (command coulomb-truncation-embed).\n"
453 "Symmetries will be automatically reduced to account for this field.";
454 }
455
processCommandElectricField456 void process(ParamList& pl, Everything& e)
457 { pl.get(e.coulombParams.Efield[0], 0., "Ex", true);
458 pl.get(e.coulombParams.Efield[1], 0., "Ey", true);
459 pl.get(e.coulombParams.Efield[2], 0., "Ez", true);
460 }
461
printStatusCommandElectricField462 void printStatus(Everything& e, int iRep)
463 { for(int k=0; k<3; k++) logPrintf("%lg ", e.coulombParams.Efield[k]);
464 }
465 }
466 commandElectricField;
467