Skip to content

Missing PBC in bonded forces when using to_openmm_simulation causes large energies in polymersΒ #1335

@galioguo

Description

@galioguo

Description and Output

I want to preface this by saying that I'm not sure if this issue is interesting to OpenFF, but I wanted to raise it here in case it is.

I'm using interchange to transfer a polymer sample (13337 atoms with component molecules of sizes 70, 80, 80, 147, 224, 425, 435, 800, and 11076) from GROMACS into OpenMM. When using Interchange to generate the simulation, I found very large initial potential energy (~1.6 billion kJ/mole). Breaking down the energy contributions by forces and whether or not OpenMM recognizes them as periodic:

Nonbonded force IS PERIODIC and has an associated potential of -8243.501361666567 kJ/mol
PeriodicTorsionForce IS NOT PERIODIC and has an associated potential of 32323.733276367188 kJ/mol
HarmonicAngleForce IS NOT PERIODIC and has an associated potential of 626883.4873046875 kJ/mol
HarmonicBondForce IS NOT PERIODIC and has an associated potential of 1606060598.0 kJ/mol
The total potential energy is 1606711561.7192194 kJ/mol

This suggested to me that bonded interactions spanning periodic boundaries are not being correctly assigned their true bond distances. When I manually added in forces in accordance with SMARTS strings in the Sage 2.2.1 XML file, I made sure to add force.setUsesPeriodicBoundaryConditions(True) for all three bonded forces, and it led to the following reasonable behavior:

HarmonicBondForce IS PERIODIC and has an associated potential of 3501.7182302474976 kJ/mol
HarmonicAngleForce IS PERIODIC and has an associated potential of 53255.296142578125 kJ/mol
PeriodicTorsionForce IS PERIODIC and has an associated potential of 31368.817489624023 kJ/mol
NonbondedForce IS PERIODIC and has an associated potential of -7977.904557150272 kJ/mol
The total potential energy is 80147.92730529938 kJ/mol

When trying to reproduce this issue for a smaller system, I found it interesting that the bad energy due to PBCs wasn't as bad. Only 516 harmonic bonds span the periodic box in the geometry above, leading to a contribution of around 3.1 million kJ/mol for each bond. But when I compare the same issue for a single ethane molecule in a box of the same size, this leads to a much smaller difference between the case when the carbon-carbon bond spans the boundary and when it does not.

For the spanning case using interchange:

Nonbonded force IS PERIODIC and has an associated potential of 2.367626820928623 kJ/mol
PeriodicTorsionForce IS NOT PERIODIC and has an associated potential of 2.384521451403998e-07 kJ/mol
HarmonicAngleForce IS NOT PERIODIC and has an associated potential of 0.18148180842399597 kJ/mol
HarmonicBondForce IS NOT PERIODIC and has an associated potential of 2.6079044342041016 kJ/mol
The total potential energy is 5.157013302008865 kJ/mol

For the centered (non-spanning) case using interchange:

Nonbonded force IS PERIODIC and has an associated potential of 2.372286502870795 kJ/mol
PeriodicTorsionForce IS NOT PERIODIC and has an associated potential of 2.384521451403998e-07 kJ/mol
HarmonicAngleForce IS NOT PERIODIC and has an associated potential of 0.20093707740306854 kJ/mol
HarmonicBondForce IS NOT PERIODIC and has an associated potential of 0.4211483895778656 kJ/mol
The total potential energy is 2.9943722083038744 kJ/mol

This suggests to me that the effects of the missing PBCs for bonded forces might be exacerbated in larger molecules.

Reproduction

To reproduce the above, I've attached three YAML files containing the molecular geometry and some code:

Large polymer: xlink_offmol.yaml
Ethane centered in periodic box: ethane_centered_offmol.yaml
Ethane C-C bond spanning periodic boundary: ethane_uncentered_offmol.yaml

import yaml
import numpy as np

import openff.toolkit as tk
from openff.interchange import Interchange

from openmm import *
from openmm.app import *
from openmm.unit import *

filename = 'offmol.yaml' # set as one of the three above

# read file into offmol
with open(filename, 'r') as file:
    data = yaml.safe_load(file)
offmol = tk.Molecule.from_dict(data)

sage = tk.ForceField('openff_unconstrained-2.2.1.offxml')

# generate topology and interchange
topology = tk.Topology.from_molecules(offmol)
topology.box_vectors = tk.Quantity(np.diag([50.3391, 50.3391, 50.3391]), 'angstrom')
topology.is_periodic = True
topology.set_positions(offmol.conformers[0])

interchange = Interchange.from_smirnoff(
    force_field = sage,
    topology = topology,
    charge_from_molecules = [offmol],
    allow_nonintegral_charges = True
)

integrator = LangevinMiddleIntegrator(
    300 * kelvin,
    1/picosecond,
    1 * femtosecond
)

omm_simulation = interchange.to_openmm_simulation(integrator = integrator)

# move each force into a different force group for accounting
for index, force in enumerate(omm_simulation.system.getForces()):
    force.setForceGroup(index)
omm_simulation.context.reinitialize(preserveState=True) # reinitialize context with existing atom positions 

# print information
total_potential_energy = 0.0 * kilojoule * mole ** -1
for index, force in enumerate(omm_simulation.system.getForces()):
    state = omm_simulation.context.getState(getEnergy=True,groups={index})
    to_print = f'{force.getName()}'
    if not force.usesPeriodicBoundaryConditions():
        to_print += ' IS NOT PERIODIC '
    else:
        to_print += ' IS PERIODIC '
    to_print += f'and has an associated potential of {state.getPotentialEnergy()}'
    print(to_print)
    total_potential_energy += state.getPotentialEnergy()
print('The total potential energy is', total_potential_energy)

Software versions

  • OpenFF and OpenMM through conda.
  • OpenFF Interchange 0.3.22
  • OpenMM 8.1.2
  • Python 3.10.16

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions