1 """ @package forcebalance.liquid Matching of liquid bulk properties. Under development. 6 from __future__
import division
7 from __future__
import print_function
9 from builtins
import str
10 from builtins
import zip
11 from builtins
import range
18 from forcebalance.target
import Target
21 from re
import match, sub
23 from subprocess
import PIPE
25 from lxml
import etree
27 from pymbar
import pymbar
30 from collections
import defaultdict, namedtuple, OrderedDict
34 from forcebalance.output
import getLogger
35 logger = getLogger(__name__)
37 def weight_info(W, PT, N_k, verbose=True, PTS=None):
41 I = np.exp(-1*np.sum((W*np.log(W))))
43 C.append(sum(W[N:N+ns]))
47 if len(PTS) != len(N_k):
48 logger.error(
"PTS array (phase point labels) must equal length of N_k array (# of trajectories)\n")
50 fs = max([len(i)
for i
in PTS])
54 logger.info(
"MBAR Results for Phase Point %s, Contributions:\n" % str(PT))
60 pl = 0
if PTS
is not None else 1
61 for i, Ci
in enumerate(C):
63 line1 +=
"%%%is " % fs % PTS[i]
65 line2 +=
"\x1b[91m%%%i.1f%%%%\x1b[0m " % (fs-1) % (Ci*100)
68 line2 +=
"%%%i.1f%%%% " % (fs-1) % (Ci*100)
72 if pl: logger.info(line1+
"\n")
73 if pl: logger.info(line2+
"\n")
77 pl = 0
if PTS
is not None else 1
80 logger.info(line1+
"\n")
81 logger.info(line2+
"\n")
83 logger.info(
"InfoContent: % .2f snapshots (%.2f %%)\n" % (I, 100*I/len(W)))
90 """ Subclass of Target for liquid property matching.""" 92 def __init__(self,options,tgt_opts,forcefield):
94 super(Liquid,self).
__init__(options,tgt_opts,forcefield)
96 self.set_option(tgt_opts,
'w_rho',forceprint=
True)
98 self.set_option(tgt_opts,
'w_hvap',forceprint=
True)
100 self.set_option(tgt_opts,
'w_alpha',forceprint=
True)
102 self.set_option(tgt_opts,
'w_kappa',forceprint=
True)
104 self.set_option(tgt_opts,
'w_cp',forceprint=
True)
106 self.set_option(tgt_opts,
'w_eps0',forceprint=
True)
108 self.set_option(tgt_opts,
'w_normalize',forceprint=
True)
110 self.set_option(tgt_opts,
'manual')
112 self.set_option(tgt_opts,
'hvap_subaverage')
114 self.set_option(tgt_opts,
'liquid_eq_steps',forceprint=
True)
116 self.set_option(tgt_opts,
'liquid_md_steps',forceprint=
True)
118 self.set_option(tgt_opts,
'gas_eq_steps',forceprint=
True)
120 self.set_option(tgt_opts,
'gas_md_steps',forceprint=
True)
122 if tgt_opts[
'nonbonded_cutoff']
is not None:
123 self.set_option(tgt_opts,
'nonbonded_cutoff')
125 if tgt_opts[
'vdw_cutoff']
is not None:
126 self.set_option(tgt_opts,
'vdw_cutoff')
128 self.set_option(tgt_opts,
'liquid_timestep',forceprint=
True)
130 self.set_option(tgt_opts,
'liquid_interval',forceprint=
True)
132 self.set_option(tgt_opts,
'gas_timestep',forceprint=
True)
134 self.set_option(tgt_opts,
'gas_interval',forceprint=
True)
136 self.set_option(tgt_opts,
'adapt_errors',forceprint=
True)
138 self.set_option(tgt_opts,
'minimize_energy',forceprint=
True)
140 self.set_option(tgt_opts,
'self_pol_mu0',forceprint=
True)
142 self.set_option(tgt_opts,
'self_pol_alpha',forceprint=
True)
144 self.
do_self_pol = (self.self_pol_mu0 > 0.0
and self.self_pol_alpha > 0.0)
146 self.set_option(tgt_opts,
'anisotropic_box',forceprint=
True)
148 self.set_option(tgt_opts,
'save_traj')
150 self.set_option(tgt_opts,
'n_molecules')
152 self.set_option(tgt_opts,
'w_surf_ten',forceprint=
True)
154 self.set_option(tgt_opts,
'nvt_eq_steps', forceprint=
True)
156 self.set_option(tgt_opts,
'nvt_md_steps', forceprint=
True)
158 self.set_option(tgt_opts,
'nvt_timestep', forceprint=
True)
160 self.set_option(tgt_opts,
'nvt_interval', forceprint=
True)
162 self.set_option(tgt_opts,
'pure_num_grad', forceprint=
True)
164 self.set_option(tgt_opts,
'liquid_fdiff_h', forceprint=
True)
172 if not os.path.exists(os.path.join(self.root, self.tgtdir, self.liquid_coords)):
173 logger.error(
"%s doesn't exist; please provide liquid_coords option\n" % self.liquid_coords)
175 self.
liquid_mol = Molecule(os.path.join(self.root, self.tgtdir, self.liquid_coords), toppbc=
True)
180 logger.info(
"User-provided number of molecules matches auto-detected value (%i)\n" % self.
n_molecules)
182 logger.info(
"User-provided number of molecules (%i) overrides auto-detected value (%i)\n" % (self.
n_molecules, len(self.
liquid_mol.molecules)))
185 if len(set([len(m)
for m
in self.
liquid_mol.molecules])) != 1:
186 warn_press_key(
"Possible issue because molecules are not all the same size! Sizes detected: %s" % str(set([len(m)
for m
in self.
liquid_mol.molecules])), timeout=30)
188 logger.info(
"Autodetected %i molecules with %i atoms each in liquid coordinates\n" % (self.
n_molecules, len(self.
liquid_mol.molecules[0])))
191 if not os.path.exists(os.path.join(self.root, self.tgtdir, self.gas_coords)):
192 logger.error(
"%s doesn't exist; please provide gas_coords option\n" % self.gas_coords)
194 self.
gas_mol = Molecule(os.path.join(self.root, self.tgtdir, self.gas_coords))
202 self.nptfiles += [self.liquid_coords, self.gas_coords]
204 self.scripts += [
'npt.py']
208 if not os.path.exists(os.path.join(self.root, self.tgtdir, self.nvt_coords)):
209 logger.error(
"Surface tension calculation requires %s, but it is not found."%self.nvt_coords)
211 self.
surf_ten_mol = Molecule(os.path.join(self.root, self.tgtdir, self.nvt_coords), toppbc=
True)
213 self.nvtfiles += [self.nvt_coords]
214 self.scripts += [
'nvt.py']
222 np.set_printoptions(precision=4, linewidth=100)
223 np.seterr(under=
'ignore')
230 self.
AllResults = defaultdict(
lambda:defaultdict(list))
237 self.gas_engine_args.update(self.OptionDict)
238 self.gas_engine_args.update(options)
239 del self.gas_engine_args[
'name']
241 self.
gas_engine = self.engine_(target=self, mol=self.
gas_mol, name=
"selfpol", **self.gas_engine_args)
247 """ Prepare the temporary directory by copying in important files. """ 248 abstempdir = os.path.join(self.root,self.tempdir)
249 for f
in self.nptfiles + (self.nvtfiles
if hasattr(self,
'nvtfiles')
else []):
250 LinkFile(os.path.join(self.root, self.tgtdir, f), os.path.join(abstempdir, f))
251 for f
in self.scripts:
252 LinkFile(os.path.join(os.path.split(__file__)[0],
"data",f),os.path.join(abstempdir,f))
256 with open(os.path.join(self.tgtdir,
'data.csv'),
'rU')
as f: R0 = list(csv.reader(f))
258 R1 = [[sub(
'#.*$',
'',word)
for word
in line]
for line
in R0
if len(line[0]) > 0
and line[0][0] !=
"#"]
260 R = [[wrd.lower()
for wrd
in line]
for line
in R1
if any([len(wrd)
for wrd
in line]) > 0]
261 global_opts = OrderedDict()
262 found_headings =
False 263 known_vars = [
'mbar',
'rho',
'hvap',
'alpha',
'kappa',
'cp',
'eps0',
'cvib_intra',
264 'cvib_inter',
'cni',
'devib_intra',
'devib_inter',
'surf_ten']
267 if line[0] ==
"global":
270 global_opts[line[1]] = float(line[2])
271 elif line[2].lower() ==
'false':
272 global_opts[line[1]] =
False 273 elif line[2].lower() ==
'true':
274 global_opts[line[1]] =
True 275 elif not found_headings:
276 found_headings =
True 278 if len(set(headings)) != len(headings):
279 logger.error(
'Column headings in data.csv must be unique\n')
281 if 'p' not in headings:
282 logger.error(
'There must be a pressure column heading labeled by "p" in data.csv\n')
284 if 't' not in headings:
285 logger.error(
'There must be a temperature column heading labeled by "t" in data.csv\n')
290 t = [float(val)
for head, val
in zip(headings,line)
if head ==
't'][0]
292 pval = [float(val.split()[0])
for head, val
in zip(headings,line)
if head ==
'p'][0]
293 punit = [val.split()[1]
if len(val.split()) >= 1
else "atm" for head, val
in zip(headings,line)
if head ==
'p'][0]
294 unrec = set([punit]).difference([
'atm',
'bar'])
296 logger.error(
'The pressure unit %s is not recognized, please use bar or atm\n' % unrec[0])
299 for head, val
in zip(headings,line):
300 if head ==
't' or head ==
'p' :
continue 302 self.
RefData.setdefault(head,OrderedDict([]))[(t,pval,punit)] = float(val)
303 elif val.lower() ==
'true':
304 self.
RefData.setdefault(head,OrderedDict([]))[(t,pval,punit)] =
True 305 elif val.lower() ==
'false':
306 self.
RefData.setdefault(head,OrderedDict([]))[(t,pval,punit)] =
False 308 logger.error(line +
'\n')
309 logger.error(
'Encountered an error reading this line!\n')
312 logger.error(line +
'\n')
313 logger.error(
'I did not recognize this line!\n')
316 default_denoms = defaultdict(int)
318 RefData_copy = copy.deepcopy(self.
RefData)
320 if head
not in known_vars+[i+
"_wt" for i
in known_vars]:
322 logger.error(
"The column heading %s is not recognized in data.csv\n" % head)
324 if head
in known_vars:
325 if head+
"_wt" not in self.
RefData:
327 RefData_copy[head+
"_wt"] = OrderedDict([(key, 1.0)
for key
in self.
RefData[head]])
328 wts = np.array(list(RefData_copy[head+
"_wt"].values()))
329 dat = np.array(list(self.
RefData[head].values()))
330 avg = np.average(dat, weights=wts)
334 default_denoms[head+
"_denom"] = np.sqrt(np.dot(wts, (dat-avg)**2)/wts.sum())
338 default_denoms[head+
"_denom"] = np.sqrt(np.abs(dat[0]))
339 PhasePoints |= set(self.
RefData[head].keys())
344 self.
PhasePoints = sorted(list(PhasePoints), key=
lambda x: (x[1], x[0]))
347 logger.debug(
"global_opts:\n%s\n" % str(global_opts))
348 logger.debug(
"default_denoms:\n%s\n" % str(default_denoms))
349 for opt
in global_opts:
352 self.set_option(global_opts,opt,default=default_denoms[opt])
354 self.set_option(global_opts,opt)
357 there = os.path.abspath(there)
360 for d
in os.listdir(there):
362 if os.path.exists(os.path.join(there, d,
'npt_result.p')):
364 if (float(havepts)/len(self.
Labels)) > 0.75:
370 """ Submit a NPT simulation to the Work Queue. """ 372 if not os.path.exists(
'npt_result.p'):
376 cmdstr =
'%s python npt.py %s %.3f %.3f' % (self.nptpfx, self.
engname, temperature, pressure)
378 logger.info(
"Running condensed phase simulation locally.\n")
379 logger.info(
"You may tail -f %s/npt.out in another terminal window\n" % os.getcwd())
380 _exec(cmdstr, copy_stderr=
True, outfnm=
'npt.out')
382 if hasattr(self,
'mol2'):
383 if hasattr(self,
'FF'):
384 mol2_send = list(set(self.mol2).difference(set(self.FF.fnms)))
386 mol2_send = self.mol2
389 queue_up(wq, command = cmdstr+
' > npt.out 2>&1 ',
390 input_files = self.nptfiles + self.scripts + mol2_send + [
'forcebalance.p'],
391 output_files = [
'npt_result.p',
'npt.out'] + self.
extra_output, tgt=self)
394 """ Submit a NVT simulation to the Work Queue. """ 396 if not os.path.exists(
'nvt_result.p'):
398 cmdstr =
'%s python nvt.py %s %.3f' % (self.nptpfx, self.
engname, temperature)
400 logger.info(
"Running condensed phase simulation locally.\n")
401 logger.info(
"You may tail -f %s/nvt.out in another terminal window\n" % os.getcwd())
402 _exec(cmdstr, copy_stderr=
True, outfnm=
'nvt.out')
404 if hasattr(self,
'mol2'):
405 if hasattr(self,
'FF'):
406 mol2_send = list(set(self.mol2).difference(set(self.FF.fnms)))
408 mol2_send = self.mol2
411 queue_up(wq, command = cmdstr+
' > nvt.out 2>&1 ',
412 input_files = self.nvtfiles + self.scripts + mol2_send + [
'forcebalance.p'],
413 output_files = [
'nvt_result.p',
'nvt.out'] + self.
extra_output, tgt=self)
418 ddict = self.
gas_engine.multipole_moments(optimize=
True)[
'dipole']
419 d = np.array(list(ddict.values()))
421 logger.info(
"The molecular dipole moment is % .3f debye\n" % np.linalg.norm(d))
429 convert = 60.240179789402056
430 dd2 = (np.linalg.norm(d)-self.self_pol_mu0)**2
431 epol = 0.5*convert*dd2/self.self_pol_alpha
435 AGrad = hasattr(self,
'Gp')
436 PrintDict = OrderedDict()
437 def print_item(key, heading, physunit):
439 printcool_dictionary(self.
Pp[key], title=
'%s %s%s\nTemperature Pressure Reference Calculated +- Stdev Delta Weight Term ' %
440 (self.name, heading,
" (%s) " % physunit
if physunit
else ""), bold=
True, color=4, keywidth=15)
441 bar =
printcool(
"%s objective function: % .3f%s" % (heading, self.
Xp[key],
", Derivative:" if AGrad
else ""))
443 self.FF.print_map(vals=self.
Gp[key])
445 PrintDict[heading] =
"% 10.5f % 8.3f % 14.5e" % (self.
Xp[key], self.
Wp[key], self.
Xp[key]*self.
Wp[key])
447 print_item(
"Rho",
"Density",
"kg m^-3")
448 print_item(
"Hvap",
"Enthalpy of Vaporization",
"kJ mol^-1")
449 print_item(
"Alpha",
"Thermal Expansion Coefficient",
"10^-4 K^-1")
450 print_item(
"Kappa",
"Isothermal Compressibility",
"10^-6 bar^-1")
451 print_item(
"Cp",
"Isobaric Heat Capacity",
"cal mol^-1 K^-1")
452 print_item(
"Eps0",
"Dielectric Constant",
None)
453 print_item(
"Surf_ten",
"Surface Tension",
"mN m^-1")
455 PrintDict[
'Total'] =
"% 10s % 8s % 14.5e" % (
"",
"",self.
Objective)
457 Title =
"%s Condensed Phase Properties:\n %-20s %40s" % (self.name,
"Property Name",
"Residual x Weight = Contribution")
461 def objective_term(self, points, expname, calc, err, grad, name="Quantity", SubAverage=False):
464 Weights = self.
RefData[expname+
"_wt"]
465 Denom = getattr(self,expname+
"_denom",1.0)
468 return 0.0, np.zeros(self.FF.np), np.zeros((self.FF.np,self.FF.np)),
None 470 Sum = sum(Weights.values())
473 logger.info(
"Weights have been renormalized to " + str(sum(Weights.values())) +
"\n")
477 logger.info(
"Physical quantity %s uses denominator = % .4f\n" % (name, Denom))
486 Gradient = np.zeros(self.FF.np)
487 Hessian = np.zeros((self.FF.np,self.FF.np))
492 avgGrad = np.zeros(self.FF.np)
495 avgCalc += Weights[PT]*calc[PT]
496 avgExp += Weights[PT]*exp[PT]
497 avgGrad += Weights[PT]*grad[PT]
499 for i, PT
in enumerate(points):
502 Delta = calc[PT] - exp[PT] - avgCalc + avgExp
505 Delta = calc[PT] - exp[PT]
508 ThisObj = Weights[PT] * Delta ** 2 / Denom**2
510 ThisGrad = 2.0 * Weights[PT] * Delta * G / Denom**2
515 Hessian += 2.0 * Weights[PT] * (np.outer(G, G)) / Denom**2
520 ThisObj = Weights[PT] * (S**0.5-D) / Denom
521 ThisGrad = Weights[PT] * (Delta/S**0.5) * G / Denom
522 ThisHess = Weights[PT] * (1/S**0.5-Delta**2/S**1.5) * np.outer(G,G) / Denom
528 GradMapPrint = [[
"#PhasePoint"] + self.FF.plist]
529 for PT, g
in zip(points,GradMap):
530 GradMapPrint.append([
' %8.2f %8.1f %3s' % PT] + [
"% 9.3e" % i
for i
in g])
531 o =
wopen(
'gradient_%s.dat' % name)
532 for line
in GradMapPrint:
533 print(
' '.join(line), file=o)
536 Delta = np.array([calc[PT] - exp[PT]
for PT
in points])
537 delt = {PT : r
for PT, r
in zip(points,Delta)}
538 print_out = OrderedDict([(
' %8.2f %8.1f %3s' % PT,
"%9.3f %9.3f +- %-7.3f % 7.3f % 9.5f % 9.5f" % (exp[PT],calc[PT],err[PT],delt[PT],Weights[PT],Objs[PT]))
for PT
in calc])
539 return Objective, Gradient, Hessian, print_out
541 def submit_jobs(self, mvals, AGrad=True, AHess=True):
546 printcool(
"Target: %s - launching MD simulations\nTime steps: %i (eq) + %i (md)" % (self.name, self.liquid_eq_steps, self.liquid_md_steps), color=0)
548 logger.info(
"Launching additional NVT simulations for computing surface tension. Time steps: %i (eq) + %i (md)\n" % (self.nvt_eq_steps, self.nvt_md_steps))
550 if AGrad
and self.pure_num_grad:
551 lp_dump((self.FF,mvals,self.OptionDict,
False),
'forcebalance.p')
553 lp_dump((self.FF,mvals,self.OptionDict,AGrad),
'forcebalance.p')
556 if (
not self.evaluated)
and self.manual:
557 warn_press_key(
"Now's our chance to fill the temp directory up with data!", timeout=7200)
560 if self.evaluated
and self.goodstep
and self.save_traj < 2:
562 if os.path.exists(fn):
566 def submit_one_setm():
574 if not os.path.exists(label):
586 if AGrad
and self.pure_num_grad:
587 logger.info(
"Running in Pure Numerical Gradient Mode! Two additional simulation will be submitted for each parameter.\n")
588 for i_m
in range(len(mvals)):
589 for delta_m
in [-self.liquid_fdiff_h, +self.liquid_fdiff_h]:
590 pure_num_grad_label =
'mvals_%03d_%f' % (i_m, delta_m)
591 if not os.path.exists(pure_num_grad_label):
592 os.mkdir(pure_num_grad_label)
593 os.chdir(pure_num_grad_label)
595 new_mvals = copy.copy(mvals)
596 new_mvals[i_m] += delta_m
598 lp_dump((self.FF, new_mvals, self.OptionDict,
False),
'forcebalance.p')
602 rundir_backup = self.
rundir 608 self.
rundir = rundir_backup
612 def read(self, mvals, AGrad=True, AHess=True):
615 Read in time series for all previous iterations. 618 unpack =
lp_load(
'forcebalance.p')
620 if len(mvals) > 0
and (np.max(np.abs(mvals1 - mvals)) > 1e-3):
621 warn_press_key(
"mvals from forcebalance.p does not match up with internal values! (Are you reading data from a previous run?)\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
623 for dn
in range(
Counter()-1, -1, -1):
625 os.chdir(self.absrd(inum=dn))
626 mprev = np.loadtxt(
'mvals.txt')
631 logger.info(
'Reading liquid data from %s\n' % os.getcwd())
633 if os.path.exists(
'./%s/npt_result.p' % label):
635 Results[tt] =
lp_load(
'./%s/npt_result.p' % label)
636 if 'hvap' in self.
RefData and PT[0]
not in [i[0]
for i
in mPoints]:
640 logger.warning(
'In %s :\n' % os.getcwd())
641 logger.warning(
'The file ./%s/npt_result.p does not exist so we cannot read it\n' % label)
644 logger.error(
'The liquid simulations have terminated with \x1b[1;91mno readable data\x1b[0m - this is a problem!\n')
648 Rhos, Vols, Potentials, Energies, Dips, Grads, GDips, mPotentials, mEnergies, mGrads, \
649 Rho_errs, Hvap_errs, Alpha_errs, Kappa_errs, Cp_errs, Eps0_errs, NMols = ([Results[t][i]
for t
in range(len(Points))]
for i
in range(17))
651 if len(set(NMols)) != 1:
652 logger.error(str(NMols))
653 logger.error(
'The above list should only contain one number - the number of molecules\n')
656 NMol = list(set(NMols))[0]
658 if not self.adapt_errors:
659 self.
AllResults = defaultdict(
lambda:defaultdict(list))
662 if len(Points) != len(self.
Labels):
663 logger.info(
"Data sets is not full, will not use for concatenation.\n")
667 self.
AllResults[astrm][
'mPts'].append(mPoints)
668 self.
AllResults[astrm][
'E'].append(np.array(Energies))
669 self.
AllResults[astrm][
'V'].append(np.array(Vols))
670 self.
AllResults[astrm][
'R'].append(np.array(Rhos)) 671 self.AllResults[astrm]['Dx'].append(np.array([d[:,0]
for d
in Dips]))
672 self.
AllResults[astrm][
'Dy'].append(np.array([d[:,1]
for d
in Dips]))
673 self.
AllResults[astrm][
'Dz'].append(np.array([d[:,2]
for d
in Dips]))
674 self.
AllResults[astrm][
'G'].append(np.array(Grads))
675 self.
AllResults[astrm][
'GDx'].append(np.array([gd[0]
for gd
in GDips]))
676 self.
AllResults[astrm][
'GDy'].append(np.array([gd[1]
for gd
in GDips]))
677 self.
AllResults[astrm][
'GDz'].append(np.array([gd[2]
for gd
in GDips]))
678 self.
AllResults[astrm][
'L'].append(len(Energies[0]))
679 self.
AllResults[astrm][
'Steps'].append(self.liquid_md_steps)
682 self.
AllResults[astrm][
'mE'].append(np.array([i
for pt, i
in zip(Points,mEnergies)
if pt
in mPoints]))
683 self.
AllResults[astrm][
'mG'].append(np.array([i
for pt, i
in zip(Points,mGrads)
if pt
in mPoints]))
687 return self.
get(mvals, AGrad, AHess)
689 def get(self, mvals, AGrad=True, AHess=True):
690 """ Wrapper of self.get_normal() and self.get_pure_num_grad() """ 691 if self.pure_num_grad:
694 property_results = self.
get_normal(mvals, AGrad=AGrad, AHess=AHess)
695 return self.
form_get_result(property_results, AGrad=AGrad, AHess=AHess)
700 Fitting of liquid bulk properties. This is the current major 701 direction of development for ForceBalance. Basically, fitting 702 the QM energies / forces alone does not always give us the 703 best simulation behavior. In many cases it makes more sense 704 to try and reproduce some experimentally known data as well. 706 In order to reproduce experimentally known data, we need to 707 run a simulation and compare the simulation result to 708 experiment. The main challenge here is that the simulations 709 are computationally intensive (i.e. they require energy and 710 force evaluations), and furthermore the results are noisy. We 711 need to run the simulations automatically and remotely 712 (i.e. on clusters) and a good way to calculate the derivatives 713 of the simulation results with respect to the parameter values. 715 This function contains some experimentally known values of the 716 density and enthalpy of vaporization (Hvap) of liquid water. 717 It launches the density and Hvap calculations on the cluster, 718 and gathers the results / derivatives. The actual calculation 719 of results / derivatives is done in a separate file. 721 After the results come back, they are gathered together to form 722 an objective function. 724 @param[in] mvals Mathematical parameter values 725 @param[in] AGrad Switch to turn on analytic gradient 726 @param[in] AHess Switch to turn on analytic Hessian 727 @return property_results 731 unpack =
lp_load(
'forcebalance.p')
733 if len(mvals) > 0
and (np.max(np.abs(mvals1 - mvals)) > 1e-3):
734 warn_press_key(
"mvals from forcebalance.p does not match up with internal values! (Are you reading data from a previous run?)\nmvals(call)=%s mvals(disk)=%s" % (mvals, mvals1))
748 if os.path.exists(
'./%s/npt_result.p' % label):
749 logger.info(
'Reading information from ./%s/npt_result.p\n' % label)
751 Results[tt] =
lp_load(
'./%s/npt_result.p' % label)
752 if 'hvap' in self.
RefData and PT[0]
not in [i[0]
for i
in mPoints]:
756 if 'hvap' in self.
RefData and PT[0]
not in [i[0]
for i
in mBPoints]:
759 if os.path.exists(
'./%s/nvt_result.p' % label):
760 stResults[PT] =
lp_load(
'./%s/nvt_result.p' % label)
762 logger.warning(
'In %s :\n' % os.getcwd())
763 logger.warning(
'The file ./%s/nvt_result.p does not exist so we cannot read it\n' % label)
767 logger.warning(
'In %s :\n' % os.getcwd())
768 logger.warning(
'The file ./%s/npt_result.p does not exist so we cannot read it\n' % label)
771 logger.error(
'The liquid simulations have terminated with \x1b[1;91mno readable data\x1b[0m - this is a problem!\n')
775 if len(BPoints) == 1:
777 if len(mBPoints) == 1:
781 Rhos, Vols, Potentials, Energies, Dips, Grads, GDips, mPotentials, mEnergies, mGrads, \
782 Rho_errs, Hvap_errs, Alpha_errs, Kappa_errs, Cp_errs, Eps0_errs, NMols = ([Results[t][i]
for t
in range(len(Points))]
for i
in range(17))
784 if len(set(NMols)) != 1:
785 logger.error(str(NMols))
786 logger.error(
'The above list should only contain one number - the number of molecules\n')
789 NMol = list(set(NMols))[0]
791 if not self.adapt_errors:
792 self.
AllResults = defaultdict(
lambda:defaultdict(list))
795 if len(Points) != len(self.
Labels):
796 logger.info(
"Data sets is not full, will not use for concatenation.")
800 self.
AllResults[astrm][
'E'].append(np.array(Energies))
801 self.
AllResults[astrm][
'V'].append(np.array(Vols))
802 self.
AllResults[astrm][
'R'].append(np.array(Rhos)) 803 self.AllResults[astrm]['Dx'].append(np.array([d[:,0]
for d
in Dips]))
804 self.
AllResults[astrm][
'Dy'].append(np.array([d[:,1]
for d
in Dips]))
805 self.
AllResults[astrm][
'Dz'].append(np.array([d[:,2]
for d
in Dips]))
806 self.
AllResults[astrm][
'G'].append(np.array(Grads))
807 self.
AllResults[astrm][
'GDx'].append(np.array([gd[0]
for gd
in GDips]))
808 self.
AllResults[astrm][
'GDy'].append(np.array([gd[1]
for gd
in GDips]))
809 self.
AllResults[astrm][
'GDz'].append(np.array([gd[2]
for gd
in GDips]))
810 self.
AllResults[astrm][
'L'].append(len(Energies[0]))
811 self.
AllResults[astrm][
'Steps'].append(self.liquid_md_steps)
817 all_mEs, all_mGs = [], []
818 for pt, mEs, mGs
in zip(Points, mEnergies, mGrads):
822 mE_idx_dict[pt] = mE_idx
824 self.
AllResults[astrm][
'mE'].append(np.array(all_mEs))
825 self.
AllResults[astrm][
'mG'].append(np.array(all_mGs))
829 sumsteps = sum(self.AllResults[astrm]['Steps'])
830 if self.liquid_md_steps != sumsteps:
831 printcool(
"This objective function evaluation combines %i datasets\n" \
832 "Increasing simulation length: %i -> %i steps" % \
833 (Nrpt, self.liquid_md_steps, sumsteps), color=6)
834 if self.liquid_md_steps * 2 != sumsteps:
835 logger.error(
"Spoo!\n")
837 self.liquid_eq_steps *= 2
838 self.liquid_md_steps *= 2
839 self.gas_eq_steps *= 2
840 self.gas_md_steps *= 2
843 E, V, R, Dx, Dy, Dz = \
844 (np.hstack(tuple(self.
AllResults[astrm][i]))
for i
in \
845 [
'E',
'V',
'R', 'Dx', 'Dy', 'Dz'])
848 (np.hstack((np.concatenate(tuple(self.
AllResults[astrm][i]), axis=2)))
for i
in [
'G',
'GDx',
'GDy',
'GDz'])
851 mE = np.hstack(tuple(self.
AllResults[astrm][
'mE']))
852 mG = np.hstack((np.concatenate(tuple(self.
AllResults[astrm][
'mG']), axis=2)))
853 Rho_calc = OrderedDict([])
854 Rho_grad = OrderedDict([])
855 Rho_std = OrderedDict([])
856 Hvap_calc = OrderedDict([])
857 Hvap_grad = OrderedDict([])
858 Hvap_std = OrderedDict([])
859 Alpha_calc = OrderedDict([])
860 Alpha_grad = OrderedDict([])
861 Alpha_std = OrderedDict([])
862 Kappa_calc = OrderedDict([])
863 Kappa_grad = OrderedDict([])
864 Kappa_std = OrderedDict([])
865 Cp_calc = OrderedDict([])
866 Cp_grad = OrderedDict([])
867 Cp_std = OrderedDict([])
868 Eps0_calc = OrderedDict([])
869 Eps0_grad = OrderedDict([])
870 Eps0_std = OrderedDict([])
871 Surf_ten_calc = OrderedDict([])
872 Surf_ten_grad = OrderedDict([])
873 Surf_ten_std = OrderedDict([])
876 pvkj=0.061019351687175
881 N_k = np.ones(BSims, dtype=int)*Shots
883 U_kln = np.zeros([BSims,BSims,Shots])
884 for m, PT
in enumerate(BPoints):
886 P = PT[1] / 1.01325
if PT[2] ==
'bar' else PT[1]
888 for k
in range(BSims):
892 kk = Points.index(BPoints[k])
893 U_kln[k, m, :] = E[kk] + P*V[kk]*pvkj
894 U_kln[k, m, :] *= beta
897 logger.info(
"Running MBAR analysis on %i states...\n" % len(BPoints))
898 mbar = pymbar.MBAR(U_kln, N_k, verbose=mbar_verbose, relative_tolerance=5.0e-8)
899 W1 = mbar.getWeights()
900 logger.info(
"Done\n")
901 elif len(BPoints) == 1:
902 W1 = np.ones((Shots,1))
905 def fill_weights(weights, phase_points, mbar_points, snapshots):
906 """ Fill in the weight matrix with MBAR weights where MBAR was run, 907 and equal weights otherwise. """ 908 new_weights = np.zeros([len(phase_points)*snapshots,len(phase_points)])
909 for m, PT
in enumerate(phase_points):
910 if PT
in mbar_points:
911 mm = mbar_points.index(PT)
912 for kk, PT1
in enumerate(mbar_points):
913 k = phase_points.index(PT1)
914 logger.debug(
"Will fill W2[%i:%i,%i] with W1[%i:%i,%i]\n" % (k*snapshots,k*snapshots+snapshots,m,kk*snapshots,kk*snapshots+snapshots,mm))
915 new_weights[k*snapshots:(k+1)*snapshots,m] = weights[kk*snapshots:(kk+1)*snapshots,mm]
917 logger.debug(
"Will fill W2[%i:%i,%i] with equal weights\n" % (m*snapshots,(m+1)*snapshots,m))
918 new_weights[m*snapshots:(m+1)*snapshots,m] = 1.0/snapshots
921 W2 = fill_weights(W1, Points, BPoints, Shots)
927 if len(mBPoints) > 1:
928 mBSims = len(mBPoints)
929 mN_k = np.ones(mBSims, dtype=int)*mShots
930 mU_kln = np.zeros([mBSims,mBSims,mShots])
931 for m, PT
in enumerate(mBPoints):
934 for k
in range(mBSims):
935 mE_idx = mE_idx_dict[mBPoints[k]]
936 mU_kln[k, m, :] = mE[mE_idx]
937 mU_kln[k, m, :] *= beta
938 if np.abs(np.std(mE)) > 1e-6
and mBSims > 1:
939 mmbar = pymbar.MBAR(mU_kln, mN_k, verbose=
False, relative_tolerance=5.0e-8, method=
'self-consistent-iteration')
940 mW1 = mmbar.getWeights()
941 elif len(mBPoints) == 1:
942 mW1 = np.ones((mShots,1))
944 mW2 = fill_weights(mW1, mPoints, mBPoints, mShots)
949 bar =
printcool(
"Self-polarization correction to \nenthalpy of vaporization is % .3f kJ/mol%s" % (EPol,
", Derivative:" if AGrad
else ""))
951 self.FF.print_map(vals=GEPol)
961 if len(mPoints) > 0: mE = mE.flatten()
963 for i, PT
in enumerate(Points):
965 P = PT[1] / 1.01325
if PT[2] ==
'bar' else PT[1]
970 C =
weight_info(W, PT, np.ones(len(Points), dtype=int)*Shots, verbose=mbar_verbose)
979 return flat(np.dot(G,
col(W*vec))) - avg(vec)*Gbar
981 return flat(np.dot(G,
col(W*vec)))
983 Rho_calc[PT] = np.dot(W,R)
984 Rho_grad[PT] = mBeta*(
flat(np.dot(G,
col(W*R))) - np.dot(W,R)*Gbar)
987 ii = mPoints.index(PT)
989 mGbar =
flat(np.dot(mG,
col(mW)))
990 Hvap_calc[PT] = np.dot(mW,mE) - np.dot(W,E)/NMol + kb*T - np.dot(W, PV)/NMol
991 Hvap_grad[PT] = mGbar + mBeta*(
flat(np.dot(mG,
col(mW*mE))) - np.dot(mW,mE)*mGbar)
992 Hvap_grad[PT] -= (Gbar + mBeta*(
flat(np.dot(G,
col(W*E))) - np.dot(W,E)*Gbar)) / NMol
993 Hvap_grad[PT] -= (mBeta*(
flat(np.dot(G,
col(W*PV))) - np.dot(W,PV)*Gbar)) / NMol
995 Hvap_calc[PT] -= EPol
996 Hvap_grad[PT] -= GEPol
997 if hasattr(self,
'use_cni')
and self.use_cni:
999 logger.error(
'Asked for a nonideality correction but not provided in reference data (data.csv). Either disable the option in data.csv or add data.\n')
1001 logger.debug(
"Adding % .3f to enthalpy of vaporization at " % self.
RefData[
'cni'][PT] + str(PT) +
'\n')
1002 Hvap_calc[PT] += self.
RefData[
'cni'][PT]
1003 if hasattr(self,
'use_cvib_intra')
and self.use_cvib_intra:
1004 if not (
'cvib_intra' in self.
RefData and self.
RefData[
'cvib_intra'][PT]):
1005 logger.error(
'Asked for a quantum intramolecular vibrational correction but not provided in reference data (data.csv). Either disable the option in data.csv or add data.\n')
1007 logger.debug(
"Adding % .3f to enthalpy of vaporization at " % self.
RefData[
'cvib_intra'][PT] + str(PT) +
'\n')
1008 Hvap_calc[PT] += self.
RefData[
'cvib_intra'][PT]
1009 if hasattr(self,
'use_cvib_inter')
and self.use_cvib_inter:
1010 if not (
'cvib_inter' in self.
RefData and self.
RefData[
'cvib_inter'][PT]):
1011 logger.error(
'Asked for a quantum intermolecular vibrational correction but not provided in reference data (data.csv). Either disable the option in data.csv or add data.\n')
1013 logger.debug(
"Adding % .3f to enthalpy of vaporization at " % self.
RefData[
'cvib_inter'][PT] + str(PT) +
'\n')
1014 Hvap_calc[PT] += self.
RefData[
'cvib_inter'][PT]
1017 Hvap_grad[PT] = np.zeros(self.FF.np)
1019 Alpha_calc[PT] = 1e4 * (avg(H*V)-avg(H)*avg(V))/avg(V)/(kT*T)
1020 GAlpha1 = -1 * Beta * deprod(H*V) * avg(V) / avg(V)**2
1021 GAlpha2 = +1 * Beta * avg(H*V) * deprod(V) / avg(V)**2
1022 GAlpha3 = deprod(V)/avg(V) - Gbar
1023 GAlpha4 = Beta * covde(H)
1024 Alpha_grad[PT] = 1e4 * (GAlpha1 + GAlpha2 + GAlpha3 + GAlpha4)/(kT*T)
1026 bar_unit = 0.06022141793 * 1e6
1027 Kappa_calc[PT] = bar_unit / kT * (avg(V**2)-avg(V)**2)/avg(V)
1028 GKappa1 = +1 * Beta**2 * avg(V**2) * deprod(V) / avg(V)**2
1029 GKappa2 = -1 * Beta**2 * avg(V) * deprod(V**2) / avg(V)**2
1030 GKappa3 = +1 * Beta**2 * covde(V)
1031 Kappa_grad[PT] = bar_unit*(GKappa1 + GKappa2 + GKappa3)
1033 Cp_calc[PT] = 1000/(4.184*NMol*kT*T) * (avg(H**2) - avg(H)**2)
1034 if hasattr(self,
'use_cvib_intra')
and self.use_cvib_intra:
1035 logger.debug(
"Adding " + str(self.
RefData[
'devib_intra'][PT]) +
" to the heat capacity\n")
1036 Cp_calc[PT] += self.
RefData[
'devib_intra'][PT]
1037 if hasattr(self,
'use_cvib_inter')
and self.use_cvib_inter:
1038 logger.debug(
"Adding " + str(self.
RefData[
'devib_inter'][PT]) +
" to the heat capacity\n")
1039 Cp_calc[PT] += self.
RefData[
'devib_inter'][PT]
1040 GCp1 = 2*covde(H) * 1000 / 4.184 / (NMol*kT*T)
1041 GCp2 = mBeta*covde(H**2) * 1000 / 4.184 / (NMol*kT*T)
1042 GCp3 = 2*Beta*avg(H)*covde(H) * 1000 / 4.184 / (NMol*kT*T)
1043 Cp_grad[PT] = GCp1 + GCp2 + GCp3
1045 prefactor = 30.348705333964077
1046 D2 = avg(Dx**2)+avg(Dy**2)+avg(Dz**2)-avg(Dx)**2-avg(Dy)**2-avg(Dz)**2
1047 Eps0_calc[PT] = 1.0 + prefactor*(D2/avg(V))/T
1048 GD2 = 2*(
flat(np.dot(GDx,
col(W*Dx))) - avg(Dx)*
flat(np.dot(GDx,
col(W)))) - Beta*(covde(Dx**2) - 2*avg(Dx)*covde(Dx))
1049 GD2 += 2*(
flat(np.dot(GDy,
col(W*Dy))) - avg(Dy)*
flat(np.dot(GDy,
col(W)))) - Beta*(covde(Dy**2) - 2*avg(Dy)*covde(Dy))
1050 GD2 += 2*(
flat(np.dot(GDz,
col(W*Dz))) - avg(Dz)*
flat(np.dot(GDz,
col(W)))) - Beta*(covde(Dz**2) - 2*avg(Dz)*covde(Dz))
1051 Eps0_grad[PT] = prefactor*(GD2/avg(V) - mBeta*covde(V)*D2/avg(V)**2)/T
1054 Surf_ten_calc[PT] = stResults[PT][
"surf_ten"]
1055 Surf_ten_grad[PT] = stResults[PT][
"G_surf_ten"]
1056 Surf_ten_std[PT] = stResults[PT][
"surf_ten_err"]
1058 Rho_std[PT] = np.sqrt(sum(C**2 * np.array(Rho_errs)**2))
1060 Hvap_std[PT] = np.sqrt(sum(C**2 * np.array(Hvap_errs)**2))
1063 Alpha_std[PT] = np.sqrt(sum(C**2 * np.array(Alpha_errs)**2)) * 1e4
1064 Kappa_std[PT] = np.sqrt(sum(C**2 * np.array(Kappa_errs)**2)) * 1e6
1065 Cp_std[PT] = np.sqrt(sum(C**2 * np.array(Cp_errs)**2))
1066 Eps0_std[PT] = np.sqrt(sum(C**2 * np.array(Eps0_errs)**2))
1068 property_results = dict()
1069 property_results[
'rho'] = Rho_calc, Rho_std, Rho_grad
1070 property_results[
'hvap'] = Hvap_calc, Hvap_std, Hvap_grad
1071 property_results[
'alpha'] = Alpha_calc, Alpha_std, Alpha_grad
1072 property_results[
'kappa'] = Kappa_calc, Kappa_std, Kappa_grad
1073 property_results[
'cp'] = Cp_calc, Cp_std, Cp_grad
1074 property_results[
'eps0'] = Eps0_calc, Eps0_std, Eps0_grad
1075 property_results[
'surf_ten'] = Surf_ten_calc, Surf_ten_std, Surf_ten_grad
1076 return property_results
1080 This function calls self.get_normal(AGrad=False) to get the property values and std_err, 1081 but compute the property gradients using finite difference of the FF parameters. 1083 @param[in] mvals Mathematical parameter values 1084 @param[in] AGrad Switch to turn on analytic gradient 1085 @param[in] AHess Switch to turn on analytic Hessian 1086 @return property_results 1089 if not self.pure_num_grad:
1090 raise RuntimeError(
"Not running in pure numerical gradients mode. Please use self.get_normal() instead!")
1093 return self.
get_normal(mvals, AGrad=AGrad, AHess=AHess)
1096 property_results = self.
get_normal(mvals, AGrad=
False, AHess=
False)
1098 logger.info(
"Pure numerical gradient mode: loading property values from sub-directorys.\n")
1100 for i_m
in range(len(mvals)):
1101 property_results_pm = dict()
1102 for delta_m
in [+self.liquid_fdiff_h, -self.liquid_fdiff_h]:
1103 pure_num_grad_label =
'mvals_%03d_%f' % (i_m, delta_m)
1104 logger.info(
"Reading from sub-directory %s\n" % pure_num_grad_label)
1105 os.chdir(pure_num_grad_label)
1107 new_mvals = copy.copy(mvals)
1108 new_mvals[i_m] += delta_m
1111 property_results_pm[delta_m] = self.
get_normal(new_mvals, AGrad=
False, AHess=
False)
1113 for key
in property_results:
1114 for PT
in property_results[key][2].keys():
1115 property_results[key][2][PT][i_m] = (property_results_pm[+self.liquid_fdiff_h][key][0][PT] - property_results_pm[-self.liquid_fdiff_h][key][0][PT]) / (2.0*self.liquid_fdiff_h)
1117 return property_results
1121 This function takes the property_results from get_normal() or get_pure_num_grad() 1122 and form the answer for the return of the self.get() function 1124 @in property_results 1125 @return Answer Contribution to the objective function 1129 Rho_calc, Rho_std, Rho_grad = property_results[
'rho']
1130 Hvap_calc, Hvap_std, Hvap_grad = property_results[
'hvap']
1131 Alpha_calc, Alpha_std, Alpha_grad = property_results[
'alpha']
1132 Kappa_calc, Kappa_std, Kappa_grad = property_results[
'kappa']
1133 Cp_calc, Cp_std, Cp_grad = property_results[
'cp']
1134 Eps0_calc, Eps0_std, Eps0_grad = property_results[
'eps0']
1135 Surf_ten_calc, Surf_ten_std, Surf_ten_grad = property_results[
'surf_ten']
1137 Points = list(Rho_calc.keys())
1140 X_Rho, G_Rho, H_Rho, RhoPrint = self.
objective_term(Points,
'rho', Rho_calc, Rho_std, Rho_grad, name=
"Density")
1141 X_Hvap, G_Hvap, H_Hvap, HvapPrint = self.
objective_term(Points,
'hvap', Hvap_calc, Hvap_std, Hvap_grad, name=
"H_vap", SubAverage=self.hvap_subaverage)
1142 X_Alpha, G_Alpha, H_Alpha, AlphaPrint = self.
objective_term(Points,
'alpha', Alpha_calc, Alpha_std, Alpha_grad, name=
"Thermal Expansion")
1143 X_Kappa, G_Kappa, H_Kappa, KappaPrint = self.
objective_term(Points,
'kappa', Kappa_calc, Kappa_std, Kappa_grad, name=
"Compressibility")
1144 X_Cp, G_Cp, H_Cp, CpPrint = self.
objective_term(Points,
'cp', Cp_calc, Cp_std, Cp_grad, name=
"Heat Capacity")
1145 X_Eps0, G_Eps0, H_Eps0, Eps0Print = self.
objective_term(Points,
'eps0', Eps0_calc, Eps0_std, Eps0_grad, name=
"Dielectric Constant")
1146 X_Surf_ten, G_Surf_ten, H_Surf_ten, Surf_tenPrint = self.
objective_term(list(Surf_ten_calc.keys()),
'surf_ten', Surf_ten_calc, Surf_ten_std, Surf_ten_grad, name=
"Surface Tension")
1148 Gradient = np.zeros(self.FF.np)
1149 Hessian = np.zeros((self.FF.np,self.FF.np))
1151 if X_Rho == 0: self.
w_rho = 0.0
1152 if X_Hvap == 0: self.
w_hvap = 0.0
1153 if X_Alpha == 0: self.
w_alpha = 0.0
1154 if X_Kappa == 0: self.
w_kappa = 0.0
1155 if X_Cp == 0: self.
w_cp = 0.0
1156 if X_Eps0 == 0: self.
w_eps0 = 0.0
1159 if self.w_normalize:
1171 Objective = w_1 * X_Rho + w_2 * X_Hvap + w_3 * X_Alpha + w_4 * X_Kappa + w_5 * X_Cp + w_6 * X_Eps0 + w_7 * X_Surf_ten
1173 Gradient = w_1 * G_Rho + w_2 * G_Hvap + w_3 * G_Alpha + w_4 * G_Kappa + w_5 * G_Cp + w_6 * G_Eps0 + w_7 * G_Surf_ten
1175 Hessian = w_1 * H_Rho + w_2 * H_Hvap + w_3 * H_Alpha + w_4 * H_Kappa + w_5 * H_Cp + w_6 * H_Eps0 + w_7 * H_Surf_ten
1178 self.
Xp = {
"Rho" : X_Rho,
"Hvap" : X_Hvap,
"Alpha" : X_Alpha,
1179 "Kappa" : X_Kappa,
"Cp" : X_Cp,
"Eps0" : X_Eps0,
"Surf_ten": X_Surf_ten}
1180 self.
Wp = {
"Rho" : w_1,
"Hvap" : w_2,
"Alpha" : w_3,
1181 "Kappa" : w_4,
"Cp" : w_5,
"Eps0" : w_6,
"Surf_ten" : w_7}
1182 self.
Pp = {
"Rho" : RhoPrint,
"Hvap" : HvapPrint,
"Alpha" : AlphaPrint,
1183 "Kappa" : KappaPrint,
"Cp" : CpPrint,
"Eps0" : Eps0Print,
"Surf_ten": Surf_tenPrint}
1185 self.
Gp = {
"Rho" : G_Rho,
"Hvap" : G_Hvap,
"Alpha" : G_Alpha,
1186 "Kappa" : G_Kappa,
"Cp" : G_Cp,
"Eps0" : G_Eps0,
"Surf_ten": G_Surf_ten}
1189 Answer = {
'X':Objective,
'G':Gradient,
'H':Hessian}
def get_pure_num_grad(self, mvals, AGrad=True, AHess=True)
This function calls self.get_normal(AGrad=False) to get the property values and std_err, but compute the property gradients using finite difference of the FF parameters.
def lp_load(fnm)
Read an object from a bzipped file specified by the path.
Nifty functions, intended to be imported by any module within ForceBalance.
MBarEnergy
Evaluated energies for all trajectories (i.e.
def LinkFile(src, dest, nosrcok=False)
def flat(vec)
Given any list, array, or matrix, return a single-index array.
def polarization_correction(self, mvals)
def objective_term(self, points, expname, calc, err, grad, name="Quantity", SubAverage=False)
def in_fd()
Invoking this function from anywhere will tell us whether we're being called by a finite-difference f...
def fdwrap(func, mvals0, pidx, key=None, kwargs)
A function wrapper for finite difference designed for differentiating 'get'-type functions.
def queue_up(wq, command, input_files, output_files, tag=None, tgt=None, verbose=True, print_time=60)
Submit a job to the Work Queue.
def lp_dump(obj, fnm, protocol=0)
Write an object to a zipped pickle file specified by the path.
def col(vec)
Given any list, array, or matrix, return a 1-column 2D array.
def get(self, mvals, AGrad=True, AHess=True)
Wrapper of self.get_normal() and self.get_pure_num_grad()
def link_dir_contents(abssrcdir, absdestdir)
def nvt_simulation(self, temperature)
Submit a NVT simulation to the Work Queue.
Subclass of Target for liquid property matching.
def warn_press_key(warning, timeout=10)
def printcool_dictionary(Dict, title="Dictionary Keys : Values", bold=False, color=2, keywidth=25, topwidth=50, center=True, leftpad=0)
See documentation for printcool; this is a nice way to print out keys/values in a dictionary...
def __init__(self, options, tgt_opts, forcefield)
def form_get_result(self, property_results, AGrad=True, AHess=True)
This function takes the property_results from get_normal() or get_pure_num_grad() and form the answer...
def npt_simulation(self, temperature, pressure, simnum)
Submit a NPT simulation to the Work Queue.
def read(self, mvals, AGrad=True, AHess=True)
Read in time series for all previous iterations.
def printcool(text, sym="#", bold=False, color=2, ansi=None, bottom='-', minwidth=50, center=True, sym2="=")
Cool-looking printout for slick formatting of output.
surf_ten_mol
Read the reference data.
def submit_jobs(self, mvals, AGrad=True, AHess=True)
SavedTraj
Saved trajectories for all iterations and all temperatures.
def get_normal(self, mvals, AGrad=True, AHess=True)
Fitting of liquid bulk properties.
def weight_info(W, PT, N_k, verbose=True, PTS=None)
def prepare_temp_directory(self)
Prepare the temporary directory by copying in important files.
AllResults
Saved results for all iterations self.SavedMVals = [].
def f12d3p(f, h, f0=None)
A three-point finite difference stencil.
def post_init(self, options)
def astr(vec1d, precision=4)
Write an array to a string so we can use it to key a dictionary.
loop_over_snapshots
LPW 2018-02-11: This is set to True if the target calculates a single-point property over several exi...
def isfloat(word)
Matches ANY number; it can be a decimal, scientific notation, integer, or what have you...
def wopen(dest, binary=False)
If trying to write to a symbolic link, remove it first.
def check_files(self, there)