Page MenuHomec4science

opls_imp.py
No OneTemporary

File Metadata

Created
Wed, Jun 19, 09:49

opls_imp.py

from nbody_graph_search import Ugraph
# This file defines how improper interactions are generated in OPLS.
# To use it, add "(opls_imp.py)" to the name of the "Data Impropers By Type"
# section, and make sure this file is located in the "common" directory.
# For example:
# write_once("Data Impropers By Type (opls_imp.py)") {
# ...
# }
# To find 4-body "improper" interactions,
# (by default, most of the time), we would use this subgraph:
# 0
# * 1st bond connects atoms 2 and 0
# | => 2nd bond connects atoms 2 and 1
# _.*._ 3rd bond connects atoms 2 and 3
# *' 2 `*
# 1 3
#
# In OPLS (as implemented in TINKER .PRM files), the central atom
# is the third atom ("2").
bond_pattern = Ugraph([(2,0), (2,1), (2,3)])
# As with other force-fields, the improper-angle is the angle between the planes
# defined by the first three atoms (0,1,2) and last three atoms (1,2,3).
# (This is implemented in LAMMPS using an improper_style which requires
# that the atoms in the interaction will be listed in this order: 0,1,2,3.)
def canonical_order(match):
"""
Before defining a new interaction, we must check to see if an
interaction between these same 4 atoms has already been created
(perhaps listed in a different, but equivalent order).
If we don't check for this this, we will create many unnecessary redundant
interactions (which can slow down he simulation).
To avoid this, I define a "canonical_order" function which sorts the atoms
and bonds in a way which is consistent with the symmetry of the interaction
being generated... Later the re-ordered list of atom and bond ids will be
tested against the list of atom/bond ids in the matches-found-so-far,
before it is added to the list of interactions found so far. Note that
the energy of an improper interactions is a function of the improper angle.
The improper-angle is usually defined as the angle between planes formed
by atoms 0,1,2 & 1,2,3. (Alternately, it is sometimes defined as the
angle between the 0,1,2 plane and atom 3.)
This angle does not change when swapping the OUTER pair of atoms (0 and 3)
(except for a change of sign, which does not matter since the energy functions
used are typically sign invariant. Furthermore, neither of OUTER pair of atoms
are the central atom. There are 3!=6 ways of ordering the remaining 3 atoms.)
Consequently it does not make sense to define a separate 4-body improper-
interaction between atoms 0,1,2,3 AS WELL AS between 3,1,2,0.
So we sort the atoms and bonds so that the first atom has a always has
a lower atomID than the last atom. (Later we will check to see if we
have already defined an interaction between these 4 atoms. If not then
we create a new one.)
"""
atom0 = match[0][0]
atom1 = match[0][1]
atom2 = match[0][2]
atom3 = match[0][3]
# match[1][0:2] contains the ID numbers for the 3 bonds
bond0 = match[1][0]
bond1 = match[1][1]
bond2 = match[1][2]
if atom0 <= atom3:
#return ((atom0,atom1,atom2,atom3), (bond0, bond1, bond2))
# But this is the same thing as:
return match
else:
return ((atom3,atom1,atom2,atom0), (bond2,bond1,bond0))

Event Timeline