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 Commands controlling electronic fillings algorithms
24
25 EnumStringMap<ElecInfo::SmearingType> smearingTypeMap(
26 ElecInfo::SmearingFermi, "Fermi",
27 ElecInfo::SmearingGauss, "Gauss",
28 ElecInfo::SmearingMP1, "MP1",
29 ElecInfo::SmearingCold, "Cold" );
30
31 EnumStringMap<ElecInfo::SmearingType> smearingTypeDescMap(
32 ElecInfo::SmearingFermi, "Use a Fermi-Dirac function for fillings",
33 ElecInfo::SmearingGauss, "Use a gaussian-based (erfc) function for fillings",
34 ElecInfo::SmearingMP1, "Use an order-1 Methfessel-Paxton \\cite MP1 function for fillings",
35 ElecInfo::SmearingCold, "Use the cold smearing function \\cite ColdSmearing to approximate zero temperature" );
36
37 struct CommandElecSmearing : public Command
38 {
CommandElecSmearingCommandElecSmearing39 CommandElecSmearing() : Command("elec-smearing", "jdftx/Electronic/Parameters")
40 {
41 format = "<smearingType>="+smearingTypeMap.optionList()+" <smearingWidth>";
42 comments =
43 "Use variable electronic fillings using a smearing function selected by <smearingType>:"
44 + addDescriptions(smearingTypeMap.optionList(), linkDescription(smearingTypeMap, smearingTypeDescMap))
45 + "\n\nwith width set by <smearingWidth> in Hartrees.\n"
46 "The width corresponds to kT (electronic temperature) for Fermi smearing,\n"
47 "and sigma/2 for the remaining gaussian-based options: this convention\n"
48 "results in roughly the same rate of k-point convergence for all smearing\n"
49 "methods using the same width. However, the entropy contribution at the\n"
50 "same width will follow the order Fermi > Gauss >> (Cold, MP1).";
51
52 require("lcao-params");
53 }
54
processCommandElecSmearing55 void process(ParamList& pl, Everything& e)
56 { ElecInfo& eInfo = e.eInfo;
57 pl.get(eInfo.smearingType, ElecInfo::SmearingFermi, smearingTypeMap, "smearingType", true);
58 pl.get(eInfo.smearingWidth, 0.0, "smearingWidth", true);
59 if(e.eInfo.smearingWidth<=0) throw string("<smearingWidth> must be positive.\n");
60 eInfo.fillingsUpdate = ElecInfo::FillingsHsub;
61 }
62
printStatusCommandElecSmearing63 void printStatus(Everything& e, int iRep)
64 { const ElecInfo& eInfo = e.eInfo;
65 logPrintf("%s %lg", smearingTypeMap.getString(eInfo.smearingType), eInfo.smearingWidth);
66 }
67 }
68 commandElecFermiFillings;
69
70 struct DeprecatedCommandElecFermiFillings : public DeprecatedCommand
DeprecatedCommandElecFermiFillingsDeprecatedCommandElecFermiFillings71 { DeprecatedCommandElecFermiFillings() : DeprecatedCommand("elec-fermi-fillings") { }
72
73 std::pair<string,string> replace(ParamList& pl) const
74 { string unusedParam; double kT;
75 pl.get(unusedParam, string(), "unusedParam", true);
76 pl.get(kT, 0.0, "kT", true);
77 ostringstream oss; oss << " Fermi " << kT;
78 return std::make_pair(string("elec-smearing"), oss.str());
79 }
80 }
81 deprecatedCommandElecFermiFillings;
82
83 //-------------------------------------------------------------------------------------------------
84
85 struct CommandTargetMu : public Command
86 {
CommandTargetMuCommandTargetMu87 CommandTargetMu() : Command("target-mu", "jdftx/Electronic/Parameters")
88 {
89 format = "<mu> [<outerLoop>=no]";
90 comments =
91 "Fixed chemical potential <mu> (instead of fixed charge).\n"
92 "Note that <mu> is absolute (relative to vacuum level) and in Hartrees.\n"
93 "For example, potential V (in Volts) relative to SHE corresponds to\n"
94 "mu = -(Vref + V)/27.2114, where Vref is the absolute SHE potential\n"
95 "in Volts below vacuum; you could set Vref = 4.44 based on experiment\n"
96 "or use the value calibrated using potentials of zero charge with\n"
97 "the solvation model in use.\n"
98 "\n"
99 "The default setting <outerLoop>=no directly performs variational minimization\n"
100 "or SCF in the grand canonical ensemble: keeping mu fixed throughout, letting\n"
101 "the number of electrons adjust continuously \\cite GC-DFT.\n"
102 "\n"
103 "Setting <outerLoop>=yes instead performs a sequence of conventional fixed-charge\n"
104 "optimizations, adjusting mu in an outer loop using the secant method.\n"
105 "This is usually much slower, and is only recommended if the default\n"
106 "direct grand canonical method fails.";
107
108 require("fluid-cation");
109 require("fluid-anion");
110 require("elec-smearing");
111 forbid("elec-initial-charge");
112 forbid("fix-electron-density");
113 forbid("fix-electron-potential");
114 }
115
processCommandTargetMu116 void process(ParamList& pl, Everything& e)
117 { pl.get(e.eInfo.mu, 0.0, "mu", true);
118 pl.get(e.eInfo.muLoop, false, boolMap, "outerLoop");
119 }
120
printStatusCommandTargetMu121 void printStatus(Everything& e, int iRep)
122 { logPrintf("%lg %s\n", e.eInfo.mu, boolMap.getString(e.eInfo.muLoop));
123 }
124 }
125 commandTargetMu;
126
127 //-------------------------------------------------------------------------------------------------
128
129 struct CommandTargetBz : public Command
130 {
CommandTargetBzCommandTargetBz131 CommandTargetBz() : Command("target-Bz", "jdftx/Electronic/Parameters")
132 {
133 format = "<Bz>";
134 comments =
135 "Fixed magnetic field <Bz> (instead of magnetization).\n"
136 "Note that <Bz> is in atomic units (1 T is approximately 4.26E-6 a.u.)\n"
137 "and in an electron-is-positive convention (Bz > 0 favors up spins).\n"
138 "Requires smearing and is only valid for spintype z-spin.";
139
140 require("elec-smearing");
141 require("elec-initial-magnetization");
142 forbid("fix-electron-density");
143 forbid("fix-electron-potential");
144 }
145
processCommandTargetBz146 void process(ParamList& pl, Everything& e)
147 { pl.get(e.eInfo.Bz, 0., "Bz", true);
148 }
149
printStatusCommandTargetBz150 void printStatus(Everything& e, int iRep)
151 { logPrintf("%lg\n", e.eInfo.Bz);
152 }
153 }
154 commandTargetBz;
155
156 //-------------------------------------------------------------------------------------------------
157
158 struct CommandElecInitialCharge : public Command
159 {
CommandElecInitialChargeCommandElecInitialCharge160 CommandElecInitialCharge() : Command("elec-initial-charge", "jdftx/Initialization")
161 {
162 format = "<QNet>";
163 comments =
164 "Initialize a system with <QNet> excess electrons compared to a neutral system.";
165
166 forbid("target-mu");
167 }
168
processCommandElecInitialCharge169 void process(ParamList& pl, Everything& e)
170 { pl.get(e.eInfo.Qinitial, 0., "QNet", true);
171 }
172
printStatusCommandElecInitialCharge173 void printStatus(Everything& e, int iRep)
174 { logPrintf("%lf", e.eInfo.Qinitial);
175 }
176 }
177 CommandElecInitialCharge;
178
179 //-------------------------------------------------------------------------------------------------
180
181 struct CommandElecInitialMagnetization : public Command
182 {
CommandElecInitialMagnetizationCommandElecInitialMagnetization183 CommandElecInitialMagnetization() : Command("elec-initial-magnetization", "jdftx/Initialization")
184 {
185 format = "<M> <constrain>=yes|no";
186 comments =
187 "Initialize system with total magnetization <M> (= Nup - Ndn).\n"
188 "With Fermi fillings, the magnetization will be constrained if <constrain>=yes,\n"
189 "and will equilibriate otherwise. Without Fermi fillings, the magnetization will\n"
190 "remain constrained regardless. Note: target-Bz will override <constrain> to no.\n"
191 "Only valid for spintype z-spin.";
192
193 require("spintype");
194 }
195
processCommandElecInitialMagnetization196 void process(ParamList& pl, Everything& e)
197 { if(e.eInfo.spinType != SpinZ)
198 throw(string("Total magnetization can only be specified for spintype z-spin"));
199 pl.get(e.eInfo.Minitial, 0., "M", true);
200 //Constraint parameter:
201 bool Mconstrain = true;
202 pl.get(Mconstrain, true, boolMap, "constrain", true);
203 e.eInfo.Bz = Mconstrain ? NAN : 0.; //nan B signifies M constrained, M free otherwise
204 }
205
printStatusCommandElecInitialMagnetization206 void printStatus(Everything& e, int iRep)
207 { logPrintf("%lf %s", e.eInfo.Minitial, boolMap.getString(std::isnan(e.eInfo.Bz)));
208 }
209 }
210 CommandElecInitialMagnetization;
211
212 //-------------------------------------------------------------------------------------------------
213
214 struct CommandElecInitialFillings : public Command
215 {
CommandElecInitialFillingsCommandElecInitialFillings216 CommandElecInitialFillings() : Command("elec-initial-fillings", "jdftx/Initialization")
217 {
218 format = "read <filename> [<nBandsOld>]";
219 comments =
220 "Initial electronic fillings are read from <filename> instead of computed automatically (default).\n"
221 "+ <nBandsOld> specifies the number of bands in the file being read, if different from current nBands.\n"
222 " Extra new bands are filled with 0s, fillings of extra old bands are accumulated into other bands.\n"
223 " Default: 0 => fillings file has same number of bands as this run.";
224
225 forbid("initial-state");
226 }
227
processCommandElecInitialFillings228 void process(ParamList& pl, Everything& e)
229 { string key; pl.get(key, string(), "read", true);
230 if(key!=string("read")) throw "First parameter must be 'read', encountered " + key;
231 pl.get(e.eInfo.initialFillingsFilename, string(), "filename", true);
232 pl.get(e.eInfo.nBandsOld, 0, "nBandsOld");
233 }
234
printStatusCommandElecInitialFillings235 void printStatus(Everything& e, int iRep)
236 { logPrintf("read %s %d", e.eInfo.initialFillingsFilename.c_str(), e.eInfo.nBandsOld);
237 }
238 }
239 commandElecInitialFillings;
240
241 //-------------------------------------------------------------------------------------------------
242
243 struct CommandElecInitialEigenvals : public Command
244 {
CommandElecInitialEigenvalsCommandElecInitialEigenvals245 CommandElecInitialEigenvals() : Command("elec-initial-eigenvals", "jdftx/Initialization")
246 {
247 format = "<filename>";
248 comments = "Read the initial eigenvalues for variable fillings (default: derive from subspace hamiltonian)\n";
249
250 forbid("initial-state");
251 }
252
processCommandElecInitialEigenvals253 void process(ParamList& pl, Everything& e)
254 { pl.get(e.eVars.eigsFilename, string(), "filename", true);
255 }
256
printStatusCommandElecInitialEigenvals257 void printStatus(Everything& e, int iRep)
258 { logPrintf("%s", e.eVars.eigsFilename.c_str());
259 }
260 }
261 commandElecInitialEigenvals;
262
263 //-------------------------------------------------------------------------------------------------
264
265 struct CommandSubspaceRotationFactor : public Command
266 {
CommandSubspaceRotationFactorCommandSubspaceRotationFactor267 CommandSubspaceRotationFactor() : Command("subspace-rotation-factor", "jdftx/Electronic/Optimization")
268 { format = "<factor> <adjust>=yes|no";
269 comments =
270 "Preconditioning factor for subspace rotations generated by the\n"
271 "auxiliary Hamiltonian used for minimization with variable fillings.\n"
272 "With <adjust> = yes (default), the factor is heuristically adjusted\n"
273 "during the minimization to optimize convergence.";
274 hasDefault = true;
275 }
276
processCommandSubspaceRotationFactor277 void process(ParamList& pl, Everything& e)
278 { pl.get(e.cntrl.subspaceRotationFactor, 1., "factor");
279 pl.get(e.cntrl.subspaceRotationAdjust, true, boolMap, "adjust");
280 }
281
printStatusCommandSubspaceRotationFactor282 void printStatus(Everything& e, int iRep)
283 { logPrintf("%lg %s", e.cntrl.subspaceRotationFactor, boolMap.getString(e.cntrl.subspaceRotationAdjust));
284 }
285 }
286 commandSubspaceRotationFactor;
287