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 EnumStringMap<PCMVariant> pcmVariantMap 24 ( PCM_CANDLE, "CANDLE", 25 PCM_SGA13, "SGA13", 26 PCM_GLSSA13, "GLSSA13", 27 PCM_LA12, "LA12", 28 PCM_SoftSphere, "SoftSphere", 29 PCM_FixedCavity, "FixedCavity", 30 PCM_SCCS_g09, "SCCS_g09", 31 PCM_SCCS_g03, "SCCS_g03", 32 PCM_SCCS_g03p, "SCCS_g03p", 33 PCM_SCCS_g09beta, "SCCS_g09beta", 34 PCM_SCCS_g03beta, "SCCS_g03beta", 35 PCM_SCCS_g03pbeta, "SCCS_g03pbeta", 36 PCM_SCCS_cation, "SCCS_cation", 37 PCM_SCCS_anion, "SCCS_anion" 38 ); 39 EnumStringMap<PCMVariant> pcmVariantDescMap 40 ( PCM_CANDLE, "Charge-asymmetry corrected, local-response, nonlocal-cavity solvation model \\cite CANDLE", 41 PCM_SGA13, "PCM with weighted-density cavitation and dispersion \\cite CavityWDA", 42 PCM_GLSSA13, "PCM with empirical cavity tension \\cite NonlinearPCM", 43 PCM_LA12, "PCM with no cavitation/dispersion contributions \\cite PCM-Kendra", 44 PCM_SoftSphere, "Soft-sphere continuum solvation model \\cite PCM-SoftSphere", 45 PCM_FixedCavity, "Use a cavity read in using cavityFile in pcm-params and only calculate electrostatic solvation", 46 PCM_SCCS_g09, "g09 parametrization of SCCS local linear model for water \\cite PCM-SCCS", 47 PCM_SCCS_g03, "g03 parametrization of SCCS local linear model for water \\cite PCM-SCCS", 48 PCM_SCCS_g03p, "g03' parametrization of SCCS local linear model for water \\cite PCM-SCCS", 49 PCM_SCCS_g09beta, "g09+beta parametrization of SCCS local linear model for water \\cite PCM-SCCS", 50 PCM_SCCS_g03beta, "g03+beta parametrization of SCCS local linear model for water \\cite PCM-SCCS", 51 PCM_SCCS_g03pbeta, "g03'+beta parametrization of SCCS local linear model for water \\cite PCM-SCCS", 52 PCM_SCCS_cation, "cations-only parametrization of SCCS local linear model for water \\cite PCM-SCCS-charged", 53 PCM_SCCS_anion, "anions-only parametrization of SCCS local linear model for water \\cite PCM-SCCS-charged" 54 ); 55 56 struct CommandPcmVariant : public Command 57 { CommandPcmVariantCommandPcmVariant58 CommandPcmVariant() : Command("pcm-variant", "jdftx/Fluid/Parameters") 59 { 60 format = "[<variant>=GLSSA13]"; 61 comments = "Select <variant> of LinearPCM or NonlinearPCM that determines\n" 62 "the cavity and related energies (cavitation, dispersion etc.).\n" 63 "CANDLE and SCCS variants are only supported for LinearPCM.\n" 64 "Here, <variant> must be one of:" 65 + addDescriptions(pcmVariantMap.optionList(), linkDescription(pcmVariantMap, pcmVariantDescMap)); 66 hasDefault = true; 67 require("fluid"); 68 } 69 processCommandPcmVariant70 void process(ParamList& pl, Everything& e) 71 { FluidSolverParams& fsp = e.eVars.fluidParams; 72 pl.get(fsp.pcmVariant, PCM_GLSSA13, pcmVariantMap, "variant"); 73 if(fsp.fluidType==FluidSaLSA) 74 fsp.pcmVariant = PCM_SaLSA; //only option for SaLSA 75 //Check variant compatibility with fluidType 76 if(fsp.fluidType!=FluidNone) 77 { //check only when fluid is not None, so that you can switch any 78 //fluid input file to vacuum simply by commenting out fluid line 79 if(fsp.fluidType!=FluidLinearPCM && ( fsp.pcmVariant==PCM_CANDLE || isPCM_SCCS(fsp.pcmVariant) ) ) 80 throw string("CANDLE and SCCS variants can only be used with fluid LinearPCM"); 81 } 82 } 83 printStatusCommandPcmVariant84 void printStatus(Everything& e, int iRep) 85 { const FluidSolverParams& fsp = e.eVars.fluidParams; 86 if(fsp.fluidType==FluidSaLSA) logPrintf("SaLSA"); //only option for SaLSA 87 else logPrintf("%s", pcmVariantMap.getString(fsp.pcmVariant)); 88 } 89 } 90 commandPcmVariant; 91 92 enum PCMparameter 93 { PCMp_lMax, //!< angular momentum truncation in SaLSA 94 PCMp_nc, //!< critical density for the PCM cavity shape function 95 PCMp_sigma, //!< smoothing factor for the PCM cavity shape function 96 PCMp_cavityTension, //!< effective surface tension (including dispersion etc.) of the cavity (hartree per bohr^2) 97 PCMp_cavityPressure, //!< effective pressure on the cavity (hartree per bohr^3) for SCCS and SoftSphere models 98 PCMp_cavityScale, //!< atomic radius scale factor for soft sphere solvation model 99 PCMp_ionSpacing, //!< extra spacing from dielectric to ionic cavity in bohrs for soft sphere model 100 PCMp_cavityFile, //!< filename for fixed cavity model 101 PCMp_zMask0, //z center in lattice coordinates for cavity mask 102 PCMp_zMaskH, //half-width in z lattice coordinates for cavity mask 103 PCMp_zMaskIonH, //half-width in z lattice coordinates for ion cavity mask 104 PCMp_zMaskSigma, //smoothness of z-mask in bohrs 105 PCMp_rhoMin, //!< min electron density (bohr^-3) for SCCS cavity switching function 106 PCMp_rhoMax, //!< max electron density (bohr^-3) for SCCS cavity switching function 107 PCMp_rhoDelta, //!< electron density change (bohr^-3) for SCCS cavity area calculation 108 PCMp_eta_wDiel, //!< fit parameter for dielectric cavity in CANDLE 109 PCMp_sqrtC6eff, //!< sqrt(effective molecule C6 coefficient) for CANDLE 110 PCMp_pCavity, //!< sensitivity of cavity to surface electric fields [e-a0/Eh] in CANDLE 111 PCMp_Ztot, //! Total valence charge on the solvent, used by CANDLE 112 PCMp_screenOverride, //! Overrides screening length 113 PCMp_Delim //!< Delimiter used in parsing 114 }; 115 EnumStringMap<PCMparameter> pcmParamMap 116 ( PCMp_lMax, "lMax", 117 PCMp_nc, "nc", 118 PCMp_sigma, "sigma", 119 PCMp_cavityTension, "cavityTension", 120 PCMp_cavityPressure, "cavityPressure", 121 PCMp_cavityScale, "cavityScale", 122 PCMp_ionSpacing, "ionSpacing", 123 PCMp_cavityFile, "cavityFile", 124 PCMp_zMask0, "zMask0", 125 PCMp_zMaskH, "zMaskH", 126 PCMp_zMaskIonH, "zMaskIonH", 127 PCMp_zMaskSigma, "zMaskSigma", 128 PCMp_rhoMin, "rhoMin", 129 PCMp_rhoMax, "rhoMax", 130 PCMp_rhoDelta, "rhoDelta", 131 PCMp_eta_wDiel, "eta_wDiel", 132 PCMp_sqrtC6eff, "sqrtC6eff", 133 PCMp_pCavity, "pCavity", 134 PCMp_Ztot, "Ztot", 135 PCMp_screenOverride, "screenOverride" 136 ); 137 EnumStringMap<PCMparameter> pcmParamDescMap 138 ( PCMp_lMax, "angular momentum truncation in SaLSA", 139 PCMp_nc, "critical density for the PCM cavity shape function", 140 PCMp_sigma, "smoothing factor for the PCM cavity shape function", 141 PCMp_cavityTension, "effective surface tension (including dispersion etc.) of the cavity (hartree per bohr^2)", 142 PCMp_cavityPressure, "effective pressure on the cavity (hartree per bohr^3) for SCCS and soft sphere models", 143 PCMp_cavityScale, "atomic radius scale factor for soft sphere model", 144 PCMp_ionSpacing, "extra spacing from dielectric to ionic cavity in bohrs for soft sphere model", 145 PCMp_cavityFile, "filename for fixed cavity model (should be on double-sized box when using Coulomb truncation)", 146 PCMp_zMask0, "center in z lattice coordinates for cavity mask (default: 0)", 147 PCMp_zMaskIonH, "half-width in z lattice coordinates for ion cavity mask (default: 0 => disabled)", 148 PCMp_zMaskH, "half-width in z lattice coordinates for cavity mask (default: 0 => disabled)", 149 PCMp_zMaskSigma, "smoothness of z-mask in bohrs (default: 0.5)", 150 PCMp_rhoMin, "min electron density (bohr^-3) for SCCS cavity switching function", 151 PCMp_rhoMax, "max electron density (bohr^-3) for SCCS cavity switching function", 152 PCMp_rhoDelta, "electron density change (bohr^-3) for SCCS cavity area calculation", 153 PCMp_eta_wDiel, "fit parameter for dielectric cavity in CANDLE", 154 PCMp_sqrtC6eff, "sqrt(effective molecule C6 coefficient) for CANDLE", 155 PCMp_pCavity, "sensitivity of cavity to surface electric fields [a.u.] in CANDLE", 156 PCMp_Ztot, "total valence charge on the solvent, used by CANDLE", 157 PCMp_screenOverride, "overrides the screening length calculated from fluid-components" 158 ); 159 160 struct CommandPcmParams : public Command 161 { CommandPcmParamsCommandPcmParams162 CommandPcmParams() : Command("pcm-params", "jdftx/Fluid/Parameters") 163 { 164 format = "<key1> <value1> <key2> <value2> ..."; 165 comments = "Adjust PCM solvent parameters. Possible keys and value types are:" 166 + addDescriptions(pcmParamMap.optionList(), linkDescription(pcmParamMap, pcmParamDescMap)) 167 + "\n\nAny number of these key-value pairs may be specified in any order."; 168 169 require("fluid-solvent"); 170 } 171 processCommandPcmParams172 void process(ParamList& pl, Everything& e) 173 { FluidSolverParams& fsp = e.eVars.fluidParams; 174 while(true) 175 { PCMparameter key; 176 pl.get(key, PCMp_Delim, pcmParamMap, "key"); 177 #define READ_AND_CHECK(param, op, val) \ 178 case PCMp_##param: \ 179 pl.get(fsp.param, val, #param, true); \ 180 if(!(fsp.param op val)) throw string(#param " must be " #op " " #val); \ 181 break; 182 switch(key) 183 { READ_AND_CHECK(lMax, >=, 0) 184 READ_AND_CHECK(nc, >, 0.) 185 READ_AND_CHECK(sigma, >, 0.) 186 READ_AND_CHECK(cavityTension, <, DBL_MAX) 187 READ_AND_CHECK(cavityPressure, <, DBL_MAX) 188 READ_AND_CHECK(cavityScale, >, 0.) 189 READ_AND_CHECK(ionSpacing, >=, 0.) 190 case PCMp_cavityFile: 191 pl.get(fsp.cavityFile, string(), "filename", true); 192 break; 193 READ_AND_CHECK(zMask0, <, DBL_MAX) 194 READ_AND_CHECK(zMaskH, >=, 0.) 195 READ_AND_CHECK(zMaskIonH, >=, 0.) 196 READ_AND_CHECK(zMaskSigma, >, 0.) 197 READ_AND_CHECK(rhoMin, >, 0.) 198 READ_AND_CHECK(rhoMax, >, 0.) 199 READ_AND_CHECK(rhoDelta, >, 0.) 200 READ_AND_CHECK(eta_wDiel, >=, 0.) 201 READ_AND_CHECK(sqrtC6eff, >=, 0.) 202 READ_AND_CHECK(pCavity, <, DBL_MAX) 203 READ_AND_CHECK(Ztot, >, 0.) 204 READ_AND_CHECK(screenOverride, >, 0.) 205 case PCMp_Delim: return; //end of input 206 } 207 #undef READ_AND_CHECK 208 } 209 } 210 printStatusCommandPcmParams211 void printStatus(Everything& e, int iRep) 212 { const FluidSolverParams& fsp = e.eVars.fluidParams; 213 #define PRINT(param) logPrintf(" \\\n\t" #param " %lg", fsp.param); 214 logPrintf(" \\\n\tlMax %d", fsp.lMax); 215 PRINT(nc) 216 PRINT(sigma) 217 PRINT(cavityTension) 218 PRINT(cavityPressure) 219 PRINT(cavityScale) 220 PRINT(ionSpacing) 221 logPrintf(" \\\n\tcavityFile %s", fsp.cavityFile.c_str()); 222 PRINT(zMask0) 223 PRINT(zMaskH) 224 PRINT(zMaskIonH) 225 PRINT(zMaskSigma) 226 PRINT(rhoMin) 227 PRINT(rhoMax) 228 PRINT(rhoDelta) 229 PRINT(eta_wDiel) 230 PRINT(sqrtC6eff) 231 PRINT(pCavity) 232 PRINT(Ztot) 233 PRINT(screenOverride) 234 #undef PRINT 235 } 236 } 237 commandPcmParams; 238 239 240 struct CommandPcmNonlinearDebug : public Command 241 { CommandPcmNonlinearDebugCommandPcmNonlinearDebug242 CommandPcmNonlinearDebug() : Command("pcm-nonlinear-debug", "jdftx/Fluid/Parameters") 243 { 244 format = "<linearDielectric>=" + boolMap.optionList() + " <linearScreening>=" + boolMap.optionList(); 245 comments = "Emulate linear response of the dielectric or screening within NonlinearPCM (for debugging purposes only)"; 246 } 247 processCommandPcmNonlinearDebug248 void process(ParamList& pl, Everything& e) 249 { FluidSolverParams& fsp = e.eVars.fluidParams; 250 pl.get(fsp.linearDielectric, false, boolMap, "linearDielectric", true); 251 pl.get(fsp.linearScreening, false, boolMap, "linearScreening", true); 252 } 253 printStatusCommandPcmNonlinearDebug254 void printStatus(Everything& e, int iRep) 255 { const FluidSolverParams& fsp = e.eVars.fluidParams; 256 logPrintf("%s %s", boolMap.getString(fsp.linearDielectric), boolMap.getString(fsp.linearScreening)); 257 } 258 } 259 commandPcmNonlinearDebug; 260 261 262 263 struct CommandIonWidth : public Command 264 { CommandIonWidthCommandIonWidth265 CommandIonWidth() : Command("ion-width", "jdftx/Fluid/Parameters") 266 { 267 format = "Ecut | fftbox | <width>"; 268 comments = "Manually specify width of gaussian representations of nuclear charge in bohr\n" 269 "or set automatically based on either energy cut-off (Ecut) or grid spacing (fftbox).\n" 270 "The widened charges are only used in the interaction with fluids, and does not\n" 271 "affect the energy of the electronic system. Default is Ecut-based selection\n" 272 "for LinearPCM/NonlinearPCM and 0 (no widening) for all other fluid types."; 273 hasDefault = true; 274 require("fluid"); 275 } 276 processCommandIonWidth277 void process(ParamList& pl, Everything& e) 278 { string key; pl.get(key, string(), "width"); 279 if(!key.length()) //default 280 { switch(e.eVars.fluidParams.fluidType) 281 { case FluidLinearPCM: 282 case FluidNonlinearPCM: 283 e.iInfo.ionWidthMethod = IonInfo::IonWidthEcut; 284 break; 285 default: 286 e.iInfo.ionWidthMethod = IonInfo::IonWidthManual; 287 e.iInfo.ionWidth = 0.; 288 } 289 } 290 else if(key=="Ecut") e.iInfo.ionWidthMethod = IonInfo::IonWidthEcut; 291 else if(key=="fftbox") e.iInfo.ionWidthMethod = IonInfo::IonWidthFFTbox; 292 else 293 { istringstream iss(key); 294 iss >> e.iInfo.ionWidth; 295 if(iss.fail()) throw string("<width> must be Ecut, fftbox or a value in bohrs"); 296 e.iInfo.ionWidthMethod = IonInfo::IonWidthManual; 297 } 298 } 299 printStatusCommandIonWidth300 void printStatus(Everything& e, int iRep) 301 { switch(e.iInfo.ionWidthMethod) 302 { case IonInfo::IonWidthFFTbox: logPrintf("fftbox"); break; 303 case IonInfo::IonWidthEcut: logPrintf("Ecut"); break; 304 case IonInfo::IonWidthManual: logPrintf("%lg", e.iInfo.ionWidth); break; 305 } 306 } 307 } 308 commandIonWidth; 309