Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RPMD features #51

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
feb7dae
Fix to polarization correction
Jan 23, 2014
ce56a7a
Merge branch 'master' of github.com:leeping/forcebalance
Jan 28, 2014
7322bbc
Merge branch 'master' of https://github.com/leeping/forcebalance
Feb 11, 2014
bc3a415
Begin adding interface for RP contraction
Feb 11, 2014
17ebcd3
Added RPMD kinetic energy calculation
Mar 19, 2014
8eb02fa
Merge branch 'master' of github.com:leeping/forcebalance
Mar 19, 2014
c5ce8b5
test commit
Mar 19, 2014
4186cab
Test
Mar 19, 2014
98b2a15
TEST
Mar 19, 2014
7adaafe
test1
Mar 19, 2014
b0a74f9
CustomBondForce
Mar 20, 2014
ce5c264
CustomBondForce(error in getPerBondParameterName)
Mar 20, 2014
bee0c4d
CustomBondForce(working version)
Mar 22, 2014
d2a1c65
RPMD input should be list of integer not number
Mar 23, 2014
4e15d71
Energy estimator
Mar 26, 2014
a1a1970
Merge branch 'master' of github.com:leeping/forcebalance
Mar 26, 2014
9b3524d
Merge branch 'master' of github.com:leeping/forcebalance
Mar 26, 2014
d2abf50
Update rpmd energy estimating(centroid instead of primitive energy es…
Mar 26, 2014
16939e4
Centroid Energy Estimator
Mar 27, 2014
0ed58f5
test setposition
Apr 2, 2014
1c55582
RPMD set_position (test)
Apr 4, 2014
c8524e4
Undo get multipole function
Apr 5, 2014
5ffd3fb
update energy estimator
Apr 7, 2014
5f55c7e
Implement Potential and Kinetic energy calculators for RPMD simulatio…
Apr 9, 2014
83817f3
Replace code that calculate quantum kinetic energy by function
Apr 9, 2014
fc50a07
Fix a few RPMD related bug
Apr 9, 2014
f1a5cde
Adding centroid position calculator
Apr 9, 2014
9cdf137
Change nothing, just test
Apr 9, 2014
8b69702
Fix some minor(but important!) bug.
Apr 9, 2014
520ede4
Try again.
Apr 9, 2014
8a7d23d
RPMD Virtual Site
Apr 10, 2014
96bea44
change nothing
Apr 10, 2014
67b6c75
fix syntax error
Apr 10, 2014
b826b1d
Use centroid KE to calculate KE in RPMD
Apr 10, 2014
cc9abba
Edit the fractionation ratio energy function
May 5, 2014
9a89502
edit HD
May 5, 2014
5a427d9
":"
May 5, 2014
0994408
undo last step
May 5, 2014
a80f321
undo
May 6, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/data/npt.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def main():
# Number of threads, multiple timestep integrator, anisotropic box etc.
threads = TgtOptions.get('md_threads', 1)
mts = TgtOptions.get('mts_integrator', 0)
rpmd_beads = TgtOptions.get('rpmd_beads', 0)
rpmd_beads = TgtOptions.get('rpmd_beads', [])
force_cuda = TgtOptions.get('force_cuda', 0)
anisotropic = TgtOptions.get('anisotropic_box', 0)
minimize = TgtOptions.get('minimize_energy', 1)
Expand Down Expand Up @@ -366,7 +366,7 @@ def main():
EngOpts["gas"]["gmx_top"] = os.path.splitext(gas_fnm)[0] + ".top"
EngOpts["gas"]["gmx_mdp"] = os.path.splitext(gas_fnm)[0] + ".mdp"
if force_cuda: logger.warn("force_cuda option has no effect on Gromacs engine.")
if rpmd_beads > 0: raise RuntimeError("Gromacs cannot handle RPMD.")
if len(rpmd_beads) > 0: raise RuntimeError("Gromacs cannot handle RPMD.")
if mts: logger.warn("Gromacs not configured for multiple timestep integrator.")
if anisotropic: logger.warn("Gromacs not configured for anisotropic box scaling.")
elif engname == "tinker":
Expand All @@ -375,7 +375,7 @@ def main():
EngOpts["liquid"]["tinker_key"] = os.path.splitext(liquid_fnm)[0] + ".key"
EngOpts["gas"]["tinker_key"] = os.path.splitext(gas_fnm)[0] + ".key"
if force_cuda: logger.warn("force_cuda option has no effect on Tinker engine.")
if rpmd_beads > 0: raise RuntimeError("TINKER cannot handle RPMD.")
if len(rpmd_beads) > 0: raise RuntimeError("TINKER cannot handle RPMD.")
if mts: logger.warn("Tinker not configured for multiple timestep integrator.")
EngOpts["liquid"].update(GenOpts)
EngOpts["gas"].update(GenOpts)
Expand Down
5 changes: 3 additions & 2 deletions src/forcefield.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ def __init__(self, options, verbose=True):
## AMOEBA mutual dipole convergence tolerance.
self.set_option(options, 'amoeba_eps')
## Switch for rigid water molecules
self.set_option(options, 'rigid_water')
self.set_option(options, 'rigid_water', forceprint=True)
## Bypass the transformation and use physical parameters directly
self.set_option(options, 'use_pvals')

Expand Down Expand Up @@ -1115,7 +1115,8 @@ def build_qtrans2(tq, qid, qmap):
def list_map(self):
""" Create the plist, which is like a reversed version of the parameter map. More convenient for printing. """
if len(self.map) == 0:
warn_press_key('The parameter map has no elements (Okay if we are not actually tuning any parameters.)')
#warn_press_key('The parameter map has no elements (Okay if we are not actually tuning any parameters.)')
logger.warning('The parameter map has no elements (Okay if we are not actually tuning any parameters.)\n')
else:
self.plist = [[] for j in range(max([self.map[i] for i in self.map])+1)]
for i in self.map:
Expand Down
80 changes: 70 additions & 10 deletions src/openmmio.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,16 @@ def CopyNonbondedParameters(src, dest):
for i in range(src.getNumExceptions()):
dest.setExceptionParameters(i,*src.getExceptionParameters(i))

def CopyCustomBondParameters(src, dest):
dest.setEnergyFunction(src.getEnergyFunction())
for i in range(src.getNumGlobalParameters()):
dest.setGlobalParameterName(i,src.GlobalParameterName(i))
for i in range(src.getNumGlobalParameters()):
dest.setGlobalParameterDefaultValue(i,*src.getGlobalParameterDefaultValue(i))
for i in range(src.getNumPerBondParameters()):
dest.setPerBondParameterName(i,src.getPerBondParameterName(i))
for i in range(src.getNumBonds()):
dest.setBondParameters(i,*src.getBondParameters(i))
def do_nothing(src, dest):
return

Expand All @@ -226,6 +236,7 @@ def CopySystemParameters(src,dest):
'HarmonicAngleForce':CopyHarmonicAngleParameters,
'PeriodicTorsionForce':CopyPeriodicTorsionParameters,
'NonbondedForce':CopyNonbondedParameters,
'CustomBondForce':CopyCustomBondParameters,
'CMMotionRemover':do_nothing}
for i in range(src.getNumForces()):
nm = src.getForce(i).__class__.__name__
Expand Down Expand Up @@ -566,35 +577,68 @@ def prepare(self, pbc=False, mmopts={}, **kwargs):
self.AtomLists['ResidueNumber'] = [a.residue.index for a in Atoms]
self.AtomMask = [a == 'A' for a in self.AtomLists['ParticleType']]

def create_simulation(self, timestep=1.0, faststep=0.25, temperature=None, pressure=None, anisotropic=False, mts=False, collision=1.0, nbarostat=25, rpmd_beads=0, **kwargs):
def create_simulation(self, timestep=1.0, faststep=0.25, temperature=None, pressure=None, anisotropic=False, mts=False, collision=1.0, nbarostat=25, rpmd_beads=[], **kwargs):

"""
Create simulation object. Note that this also takes in some
options pertinent to system setup, including the type of MD
integrator and type of pressure control.
"""

# Divisor for the temperature (RPMD sets it to nonzero.)
self.tdiv = 1

## Determine the integrator.
if temperature:
## If temperature control is turned on, then run Langevin dynamics.
if mts:
if rpmd_beads > 0:
if len(rpmd_beads) > 0:
raise RuntimeError("No multiple timestep integrator without temperature control.")
integrator = MTSVVVRIntegrator(temperature*kelvin, collision/picosecond,
timestep*femtosecond, self.system, ninnersteps=int(timestep/faststep))
else:
if rpmd_beads > 0:
logger.info("Creating RPMD integrator with %i beads.\n" % rpmd_beads)
self.tdiv = rpmd_beads
integrator = RPMDIntegrator(rpmd_beads, temperature*kelvin, collision/picosecond, timestep*femtosecond)
if len(rpmd_beads) > 0:
self.tdiv = int(rpmd_beads[0])
if len(rpmd_beads) == 1:
logger.info("Creating RPMD integrator with %i beads.\n" % int(rpmd_beads[0]))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond)
elif len(rpmd_beads) == 2:
contract = False
for frc in self.system.getForces():
if any([isinstance(frc, fc) for fc in [NonbondedForce, AmoebaMultipoleForce, AmoebaVdwForce, CustomNonbondedForce]]):
contract = True
frc.setForceGroup(1)
if contract:
logger.info("Creating RPMD integrator with %i beads (NB forces contracted to %i).\n" % (int(rpmd_beads[0]), int(rpmd_beads[1])))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond, {1:int(rpmd_beads[1])})
else:
logger.info("Creating RPMD integrator with %i beads (no NB forces to contract).\n" % (int(rpmd_beads[0])))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond)
elif len(rpmd_beads) == 3:
contract = False
contract_recip = False
for frc in self.system.getForces():
if any([isinstance(frc, fc) for fc in [NonbondedForce, AmoebaMultipoleForce, AmoebaVdwForce, CustomNonbondedForce]]):
contract = True
frc.setForceGroup(1)
if isinstance(frc, NonbondedForce):
contract_recip = True
frc.setReciprocalSpaceForceGroup(2)
if contract_recip:
logger.info("Creating RPMD integrator with %i beads (NB/Recip forces contracted to %i/%i).\n" % (int(rpmd_beads[0]), int(rpmd_beads[1]), int(rpmd_beads[2])))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond, {1:int(rpmd_beads[1]), 2:int(rpmd_beads[2])})
elif contract:
logger.info("Creating RPMD integrator with %i beads (NB forces contracted to %i, no Recip).\n" % (int(rpmd_beads[0]), int(rpmd_beads[1])))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond, {1:int(rpmd_beads[1])})
else:
logger.info("Creating RPMD integrator with %i beads (no NB forces to contract).\n" % (int(rpmd_beads[0])))
integrator = RPMDIntegrator(int(rpmd_beads[0]), temperature*kelvin, collision/picosecond, timestep*femtosecond)
else:
raise RuntimeError("Please provide a list of length 1, 2, or 3 to rpmd_beads")
else:
integrator = LangevinIntegrator(temperature*kelvin, collision/picosecond, timestep*femtosecond)
else:
## If no temperature control, default to the Verlet integrator.
if rpmd_beads > 0:
if len(rpmd_beads) > 0:
raise RuntimeError("No RPMD integrator without temperature control.")
if mts: warn_once("No multiple timestep integrator without temperature control.")
integrator = VerletIntegrator(timestep*femtoseconds)
Expand All @@ -610,13 +654,13 @@ def create_simulation(self, timestep=1.0, faststep=0.25, temperature=None, press
elif pressure != None: warn_once("Pressure is ignored because pbc is set to False.")

## Set up for energy component analysis.
if not mts:
if not mts and len(rpmd_beads) == 0:
for i, j in enumerate(self.system.getForces()):
j.setForceGroup(i)

## If virtual particles are used with AMOEBA...
SetAmoebaVirtualExclusions(self.system)

## Finally create the simulation object.
self.simulation = Simulation(self.mod.topology, self.system, integrator, self.platform)

Expand Down Expand Up @@ -951,8 +995,24 @@ def molecular_dynamics(self, nsteps, timestep, temperature=None, pressure=None,
if iteration >= 0:
self.simulation.step(nsave)
state = self.simulation.context.getState(getEnergy=True,getPositions=True,getVelocities=False,getForces=False)
#####
# if self.tdiv>=2:
# hbar=0.0635078*kilojoule*picosecond/mole
# pimdstate=["?"]*self.tdiv
# kinetic=0.0*kilojoule/mole
# potential=0.0*kilojoule/mole
# for i in range(self.tdiv):
# pimdstate[i]=integrator.getstate(i,getEnergy=True,getPositions=True,group=-1)
# potential=potential+pimdstate[i].getPotentialEnergy()/self.tdiv
# kinetic=kinetic+pimdstate[i].getKineticEnergy()/self.tdiv
# for i in range(self.tdiv):
# ii=(i+1)%self.tdiv
# deltabead=np.array(pimdstate[i].getPositions())-np.array(pimdstate[ii].getPositions())
# kinetic=kinetic-np.sum(((deltabead*deltabead).sum(axis=1))*np.array([getParticleMass(j) for j in range (system.getNumParticles())]))*(kB**2*integrator.getTemperature()**2*self.tdiv)/(2.0*hbar**2)
# else:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these comments intended to be the kinetic energy calculation?

kinetic = state.getKineticEnergy()/self.tdiv
potential = state.getPotentialEnergy()
#####Energy Estimator
if self.pbc:
box_vectors = state.getPeriodicBoxVectors()
volume = self.compute_volume(box_vectors)
Expand Down
4 changes: 2 additions & 2 deletions src/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@
},
'lists' : {"forcefield" : ([], 200, 'The names of force fields, corresponding to directory forcefields/file_name.(itp,xml,prm,frcmod,mol2)', 'All (important)'),
"scanindex_num" : ([], -100, 'Numerical index of the parameter to scan over', 'Job types scan_mvals and scan_pvals'),
"scanindex_name" : ([], -100, 'Parameter name to scan over (should convert to a numerical index)', 'Job types scan_mvals and scan_pvals')
"scanindex_name" : ([], -100, 'Parameter name to scan over (should convert to a numerical index)', 'Job types scan_mvals and scan_pvals'),
"rpmd_beads" : ([], -160, 'Number of beads / NB contracted beads / Recip contracted beads in ring polymer MD', 'Condensed phase property targets (advanced usage)', 'liquid_openmm'),
},
'ints' : {"maxstep" : (100, 50, 'Maximum number of steps in an optimization', 'Main Optimizer'),
"objective_history" : (2, 20, 'Number of good optimization steps to average over when checking the objective convergence criterion', 'Main Optimizer (jobtype "newton")'),
"wq_port" : (0, 0, 'The port number to use for Work Queue', 'Targets that use Work Queue (advanced usage)'),
"criteria" : (1, 160, 'The number of convergence criteria that must be met for main optimizer to converge', 'Main Optimizer'),
"rpmd_beads" : (0, -160, 'Number of beads in ring polymer MD (zero to disable)', 'Condensed phase property targets (advanced usage)', 'liquid_openmm'),
},
'bools' : {"backup" : (1, 10, 'Write temp directories to backup before wiping them'),
"writechk_step" : (1, -50, 'Write the checkpoint file at every optimization step'),
Expand Down