1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.potential.nonbonded.pme;
39
40 import static java.lang.String.format;
41 import static org.apache.commons.math3.util.FastMath.pow;
42
43 import edu.rit.pj.IntegerSchedule;
44 import edu.rit.util.Range;
45 import ffx.crystal.Crystal;
46 import ffx.potential.parameters.ForceField;
47 import java.util.logging.Logger;
48
49 public class AlchemicalParameters {
50
51 private static final Logger logger = Logger.getLogger(AlchemicalParameters.class.getName());
52
53 private final Polarization polarization;
54
55
56 public double permLambdaAlpha = 1.0;
57
58 public double permLambdaExponent = 3.0;
59
60 public double permLambdaStart = 0.4;
61
62 public double permLambdaEnd = 1.0;
63
64
65
66
67 public double polLambdaStart = 0.75;
68 public double polLambdaEnd = 1.0;
69
70 public double polLambdaExponent = 3.0;
71
72 public boolean doLigandVaporElec = true;
73
74 public boolean doLigandGKElec = false;
75
76
77
78
79 public boolean doNoLigandCondensedSCF = true;
80
81 public double lAlpha = 0.0;
82 public double dlAlpha = 0.0;
83 public double d2lAlpha = 0.0;
84 public double dEdLSign = 1.0;
85
86 public double lPowPerm = 1.0;
87 public double dlPowPerm = 0.0;
88 public double d2lPowPerm = 0.0;
89 public boolean doPermanentRealSpace = true;
90 public double permanentScale = 1.0;
91
92 public double lPowPol = 1.0;
93 public double dlPowPol = 0.0;
94 public double d2lPowPol = 0.0;
95 public boolean doPolarization = true;
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public double polarizationScale = 1.0;
110
111
112
113
114 public double polLambda = 1.0;
115
116
117
118
119 public double permLambda = 1.0;
120
121 public Crystal vaporCrystal = null;
122 public int[][][] vaporLists = null;
123 public Range[] vacuumRanges = null;
124 public IntegerSchedule vaporPermanentSchedule = null;
125 public IntegerSchedule vaporEwaldSchedule = null;
126
127 public AlchemicalParameters(ForceField forceField, boolean lambdaTerm,
128 boolean nnTerm, Polarization polarization) {
129 this.polarization = polarization;
130 if (lambdaTerm) {
131
132 permLambdaAlpha = forceField.getDouble("PERMANENT_LAMBDA_ALPHA", 2.0);
133 if (permLambdaAlpha < 0.0 || permLambdaAlpha > 3.0) {
134 logger.warning("Invalid value for permanent-lambda-alpha (<0.0 || >3.0); reverting to 2.0");
135 permLambdaAlpha = 2.0;
136 }
137
138
139
140
141
142
143
144
145
146 permLambdaExponent = forceField.getDouble("PERMANENT_LAMBDA_EXPONENT", 3.0);
147 if (permLambdaExponent < 0.0) {
148 logger.warning("Invalid value for permanent-lambda-exponent (<0.0); reverting to 3.0");
149 permLambdaExponent = 3.0;
150 }
151
152
153
154
155
156
157
158
159
160 polLambdaExponent = forceField.getDouble("POLARIZATION_LAMBDA_EXPONENT", 3.0);
161 if (polLambdaExponent < 0.0) {
162 logger.warning("Invalid value for polarization-lambda-exponent (<0.0); reverting to 3.0");
163 polLambdaExponent = 3.0;
164 }
165
166
167 permLambdaStart = forceField.getDouble("PERMANENT_LAMBDA_START", 0.4);
168 if (permLambdaStart < 0.0 || permLambdaStart > 1.0) {
169 logger.warning("Invalid value for perm-lambda-start (<0.0 || >1.0); reverting to 0.4");
170 permLambdaStart = 0.4;
171 }
172
173
174 permLambdaEnd = forceField.getDouble("PERMANENT_LAMBDA_END", 1.0);
175 if (permLambdaEnd < permLambdaStart || permLambdaEnd > 1.0) {
176 logger.warning("Invalid value for perm-lambda-end (<start || >1.0); reverting to 1.0");
177 permLambdaEnd = 1.0;
178 }
179
180
181
182
183
184
185
186
187
188
189 polLambdaStart = forceField.getDouble("POLARIZATION_LAMBDA_START", 0.75);
190 if (polLambdaStart < 0.0 || polLambdaStart > 1.0) {
191 logger.warning("Invalid value for polarization-lambda-start; reverting to 0.75");
192 polLambdaStart = 0.75;
193 }
194
195
196
197
198
199
200 polLambdaEnd = forceField.getDouble("POLARIZATION_LAMBDA_END", 1.0);
201 if (polLambdaEnd < polLambdaStart || polLambdaEnd > 1.0) {
202 logger.warning(
203 "Invalid value for polarization-lambda-end (<start || >1.0); reverting to 1.0");
204 polLambdaEnd = 1.0;
205 }
206
207
208
209 doLigandVaporElec = forceField.getBoolean("LIGAND_VAPOR_ELEC", true);
210 doLigandGKElec = forceField.getBoolean("LIGAND_GK_ELEC", false);
211 doNoLigandCondensedSCF = forceField.getBoolean("NO_LIGAND_CONDENSED_SCF", true);
212 } else if (nnTerm) {
213 permLambdaAlpha = 0.0;
214 permLambdaExponent = 1.0;
215 polLambdaExponent = 1.0;
216 permLambdaStart = 0.0;
217 permLambdaEnd = 1.0;
218 polLambdaStart = 0.0;
219 polLambdaEnd = 1.0;
220
221
222 doLigandVaporElec = forceField.getBoolean("LIGAND_VAPOR_ELEC", true);
223 doLigandGKElec = false;
224 doNoLigandCondensedSCF = false;
225 }
226 }
227
228 public String toString() {
229 StringBuilder sb = new StringBuilder(" Alchemical Parameters\n");
230 sb.append(
231 format(
232 " Permanent Multipole Range: %5.3f-%5.3f\n", permLambdaStart, permLambdaEnd));
233 sb.append(format(" Permanent Multipole Softcore Alpha: %5.3f\n", permLambdaAlpha));
234 sb.append(format(" Permanent Multipole Lambda Exponent: %5.3f\n", permLambdaExponent));
235 if (polarization != Polarization.NONE) {
236 sb.append(format(" Polarization Lambda Exponent: %5.3f\n", polLambdaExponent));
237 sb.append(
238 format(
239 " Polarization Range: %5.3f-%5.3f\n", polLambdaStart, polLambdaEnd));
240 sb.append(format(" Condensed SCF Without Ligand: %B\n", doNoLigandCondensedSCF));
241 }
242 if (!doLigandGKElec) {
243 sb.append(format(" Vapor Electrostatics: %B\n", doLigandVaporElec));
244 } else {
245 sb.append(format(" GK Electrostatics at L=0: %B\n", doLigandGKElec));
246 }
247 return sb.toString();
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 public void update(double lambda) {
268
269 lPowPerm = 1.0;
270 dlPowPerm = 0.0;
271 d2lPowPerm = 0.0;
272 lAlpha = 0.0;
273 dlAlpha = 0.0;
274 d2lAlpha = 0.0;
275 if (lambda < permLambdaStart) {
276 lPowPerm = 0.0;
277 } else if (lambda <= permLambdaEnd) {
278 double permWindow = permLambdaEnd - permLambdaStart;
279 double permLambdaScale = 1.0 / permWindow;
280 permLambda = permLambdaScale * (lambda - permLambdaStart);
281
282 lAlpha = permLambdaAlpha * (1.0 - permLambda) * (1.0 - permLambda);
283 dlAlpha = permLambdaAlpha * (1.0 - permLambda);
284 d2lAlpha = -permLambdaAlpha;
285
286 lPowPerm = pow(permLambda, permLambdaExponent);
287 dlPowPerm = permLambdaExponent * pow(permLambda, permLambdaExponent - 1.0);
288 d2lPowPerm = 0.0;
289 if (permLambdaExponent >= 2.0) {
290 d2lPowPerm =
291 permLambdaExponent
292 * (permLambdaExponent - 1.0)
293 * pow(permLambda, permLambdaExponent - 2.0);
294 }
295
296 dlAlpha *= permLambdaScale;
297 d2lAlpha *= (permLambdaScale * permLambdaScale);
298 dlPowPerm *= permLambdaScale;
299 d2lPowPerm *= (permLambdaScale * permLambdaScale);
300 }
301
302
303 lPowPol = 1.0;
304 dlPowPol = 0.0;
305 d2lPowPol = 0.0;
306 if (lambda < polLambdaStart) {
307 lPowPol = 0.0;
308 } else if (lambda <= polLambdaEnd) {
309 double polWindow = polLambdaEnd - polLambdaStart;
310 double polLambdaScale = 1.0 / polWindow;
311 polLambda = polLambdaScale * (lambda - polLambdaStart);
312 if (polLambdaExponent > 0.0) {
313 lPowPol = pow(polLambda, polLambdaExponent);
314 if (polLambdaExponent >= 1.0) {
315 dlPowPol = polLambdaExponent * pow(polLambda, polLambdaExponent - 1.0);
316 if (polLambdaExponent >= 2.0) {
317 d2lPowPol =
318 polLambdaExponent
319 * (polLambdaExponent - 1.0)
320 * pow(polLambda, polLambdaExponent - 2.0);
321 }
322 }
323 }
324
325 dlPowPol *= polLambdaScale;
326 d2lPowPol *= (polLambdaScale * polLambdaScale);
327 }
328 }
329 }