forcefields_example

This notebook imports the fundamental objects of the streamm.forcefields module and goes through the functionality of each

from pprint import pprint
import logging
logging.basicConfig(filename='forcefield_example.log',level=logging.DEBUG)
from pathlib2 import Path
import os
import streamm.forcefields.particletype as particletype

Let’s start with an ethane molecule from the buildingblocks_example.ipynb example

We have an sp3 carbon bonded to hydrogens

Let’s create the force field parameters object for a ‘CT’ carbon and an ‘HC’ hydrogen

CT = particletype.Particletype('CT')
HC = particletype.Particletype('HC')

Set some parameters from J. Am. Chem. Soc., 1996, 118 (45), pp 11225–11236

https://pubs.acs.org/doi/abs/10.1021/ja9621760

In general you should pick a force field that has been shown to work well for your system and set up the parameters

Check that we have our units set right

print(CT.unit_conf['energy'],CT.unit_conf['length'])

Our potential is in kCal/mol (kCalmol) so let’s get the unit dictionary and create our own default

import copy
oplsaa_unit_conf = copy.deepcopy(CT.unit_conf)
oplsaa_unit_conf['energy'] = 'kCalmol'
pprint(oplsaa_unit_conf)
CT.update_units(oplsaa_unit_conf)
HC.update_units(oplsaa_unit_conf)
CT.epsilon = 0.066 # kcal/mol
CT.sigma = 3.5 # Angstroms
HC.epsilon = 0.03 # kcal/mol
HC.sigma = 2.5 # Angstroms

Set mass using periodic table

import pymatgen_core.core.periodic_table as periodic_table
CT.mass =  periodic_table.Element['C'].atomic_mass.real
HC.mass =  periodic_table.Element['H'].atomic_mass.real

Set the bond stretching parameters

import streamm.forcefields.bondtype as bondtype
C_H = bondtype.Bondtype('CT','HC',unit_conf=oplsaa_unit_conf)
C_H.setharmonic(1.080,367.0)
print(C_H)
C_C = bondtype.Bondtype('CT','CT',unit_conf=oplsaa_unit_conf)
C_C.setharmonic(1.53,268.0)
import streamm.forcefields.angletype as angletype
H_C_H = angletype.Angletype('HC','CT','HC',unit_conf=oplsaa_unit_conf)
H_C_H.setharmonic(110.7,37.50)
print(H_C_H)
H_C_C = angletype.Angletype('HC','CT','CT',unit_conf=oplsaa_unit_conf)
H_C_C.setharmonic(110.7,37.50)

Now we need a dihedral potential for the HC-CT-CT-HC dihedral

import streamm.forcefields.dihtype as dihtype
H_C_C_H = dihtype.Dihtype('HC','CT','CT','HC',unit_conf=oplsaa_unit_conf)
H_C_C_H.type ='opls'
H_C_C_H.setopls(0.0,0.0,0.3,0.0)

Let’s create a parameter container to keep track of our parameters

import streamm.forcefields.parameters as parameters
paramC = parameters.Parameters('oplsaa',unit_conf=oplsaa_unit_conf)

Add parameters to the container

paramC.add_particletype(CT)
paramC.add_particletype(HC)
paramC.add_bondtype(C_H)
paramC.add_bondtype(C_C)
paramC.add_angletype(H_C_H)
paramC.add_angletype(H_C_C)
paramC.add_dihtype(H_C_C_H)
print(paramC)
for ptkey,pt in paramC.particletypes.items():
    print(ptkey,pt,pt.unit_conf['energy'],pt.unit_conf['length'])
for btkey,bt in paramC.bondtypes.items():
    print(btkey,bt,bt.unit_conf['harm_bond_coeff'],pt.unit_conf['length'])
for atkey,at in paramC.angletypes.items():
    print(atkey,at,at.unit_conf['energy'],at.unit_conf['length'])
print(paramC.tag)
paramC.unit_conf

We can dump a pickle file

paramC.dump_pickle()

Or we can export a json object

paramC_json = paramC.export_json()

Read in ethane .json file from the structures example

import streamm.structures.buildingblock as bb
need_files = ['ethane_struc.json']
for f in need_files:
    path = Path(f)
    if not path.is_file():
        print("Need to run buildingblocks_example.ipynb")
        os.system("jupyter nbconvert --to python  buildingblocks_example.ipynb")
        os.system("python buildingblocks_example.py")
mol_i = bb.Buildingblock('ethane')
mol_i.import_json()
print(mol_i.print_properties())

Let’s set the paramkey for each particle based on the symbol.

for pk,p in mol_i.particles.items():
    print(p.symbol)
    if( p.symbol == 'C' ):
        p.paramkey = 'CA'
    elif( p.symbol == 'H' ):
        p.paramkey = 'HA'
    print(p.paramkey ,mol_i.bonded_nblist.calc_nnab(pk))

This is a bit redundant, but we can think of a more complex molecule where we could use the number of neighbors to write a more complex routine

print(mol_i.n_particles)

Now we can set the particles, bonds, bond angles and dihedrals of the molecule to have parameters

First lets set the particle types

for pk,p in mol_i.particles.items():
    if( p.paramkey == 'CA' ):
        p.param = CT
        p.param_index = 0
    elif( p.paramkey == 'HA' ):
        p.param = HC
        p.param_index = 1

Now we can set the bond types

for bk,b in mol_i.bonds.items():
    b.param = C_H
    b.param_index = 0
for ak,a in mol_i.angles.items():
    a.param = H_C_H
    b.param_index = 0
for dk,d in mol_i.dihedrals.items():
    d.param = H_C_C_H
    d.param_index = 0
print("Particles ")
for pk,p in mol_i.particles.items():
    print(p,p.param, p.param_index)
print("\n Bonds ")
for bk,b in mol_i.bonds.items():
    print(b,b.param, b.param_index)
print("\n Bond angles ")
for ak,a in mol_i.angles.items():
    print(a,a.param, a.param_index)
print("\n Dihedrals ")
for ak,a in mol_i.dihedrals.items():
    print(a,a.param, a.param_index)

Now our molecule has forcefield parameters for all the interactions

Now let’s say we want to use a software package like GROMACS that used kJ/mol instead of kCal/mol

gromacs_unit_conf = copy.deepcopy(oplsaa_unit_conf)
gromacs_unit_conf['energy'] = 'kJmol'
gromacs_unit_conf['length'] = 'nm'

gromacs_unit_conf['harm_bond_coeff'] = 'kJmolsqnm' #*
  • The harmonic bond coefficient harm_bond_coeff has to be changed as well since it has special units of energy/length^2

pprint(gromacs_unit_conf)
mol_i.update_units(gromacs_unit_conf)
print("Particles ")
for pk,p in mol_i.particles.items():
    print(p,p.param, p.param_index)
print("\n Bonds ")
for bk,b in mol_i.bonds.items():
    print(b,b.param, b.param_index)
print("\n Bond angles ")
for ak,a in mol_i.angles.items():
    print(a,a.param, a.param_index)
print("\n Dihedrals ")
for ak,a in mol_i.dihedrals.items():
    print(a,a.param, a.param_index)
mol_i.update_units(oplsaa_unit_conf)
print("Particles ")
for pk,p in mol_i.particles.items():
    print(p,p.param, p.param_index)
print("\n Bonds ")
for bk,b in mol_i.bonds.items():
    print(b,b.param, b.param_index)
print("\n Bond angles ")
for ak,a in mol_i.angles.items():
    print(a,a.param, a.param_index)
print("\n Dihedrals ")
for ak,a in mol_i.dihedrals.items():
    print(a,a.param, a.param_index)