Project_alkyls¶
In this example, we will create alkyl chains of various lengths, run quantum chemical analysis on each and then replicate them into a simulation cell for an MD simulation¶
import os
from pprint import pprint
Check that output from other examples has been generated
from pathlib2 import Path
need_files = ['methane.xyz']
for f in need_files:
path = Path(f)
if not path.is_file():
print("Need to run structures_example.ipynb")
os.system("jupyter nbconvert --to python structures_example.ipynb")
os.system("python structures_example.py")
need_files = ['ethane.xyz']
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")
need_files = ['oplsaa_param.json']
for f in need_files:
path = Path(f)
if not path.is_file():
print("Need to run forcefields_example.ipynb")
os.system("jupyter nbconvert --to python forcefields_example.ipynb")
os.system("python forcefields_example.py")
import streamm
Now let’s create project and resource to keep track of our work
alkyl_example = streamm.Project('alkyl_example')
res_local = streamm.Resource('local')
Update relative location of templates directory
res_local.dir['templates'] = os.path.join(res_local.dir['home'],'..','templates','')
Make sure this is the location of the templates directory that comes with the streamm git repository https://github.com/NREL/streamm-tools
print(res_local.dir['templates'])
Create the local directories that will store our files
res_local.make_dir()
Tell the project about our directories
alkyl_example.set_resource(res_local)
Read in the methane.xyz file created in the structure_example.ipynb example
methane = streamm.Buildingblock('methane')
methane.read_xyz()
Create the neighbor list
methane.bonded_nblist = methane.guess_nblist(0,radii_buffer=1.25)
and the bonded interactions
methane.bonded_bonds()
methane.bonded_angles()
methane.bonded_dih()
print(methane.n_particles)
print(methane.print_properties())
Set the paramkeys
so we can identify force field parameters later on
for pkey,p in methane.particles.items():
if( p.symbol == 'C' ):
p.paramkey = 'CT'
elif( p.symbol == 'H' ):
p.paramkey = 'HC'
for pk,p in methane.particles.items():
p.residue = 1
p.resname = 'METH'
Set some rsites
to be able to join molecules together
methane.particles[1].rsite = 'RH'
methane.particles[2].rsite = 'RH'
methane.find_rsites()
print(methane.show_rsites())
Read in ethane.xyz from the buildinblock_example.ipynb example
ethane = streamm.Buildingblock('ethane')
ethane.read_xyz()
Guess bonded neighbor list based on bonded_radii
ethane.bonded_nblist = ethane.guess_nblist(0,radii_buffer=1.25)
ethane.bonded_bonds()
ethane.bonded_angles()
ethane.bonded_dih()
print(ethane.print_properties())
Set the paramkey
’s as described in the force field example
for pkey,p in ethane.particles.items():
if( p.symbol == 'C' ):
p.paramkey = 'CT'
elif( p.symbol == 'H' ):
p.paramkey = 'HC'
Set the resname
of each particle to ETH
for pk,p in ethane.particles.items():
p.residue = 1
p.resname = 'ETH'
Set rsite
’s to hydrogens to be replaced during join
ethane.particles[1].rsite = 'RH'
ethane.particles[5].rsite = 'RH'
Run find_rsites()
to populate func
list
ethane.find_rsites()
print(ethane.show_rsites())
import copy
Create octane from ethane
Copy ethane to a new Buildingblock octane
octane = copy.deepcopy(ethane)
from streamm.structures.buildingblock import attach
Then attach 3 more ethanes to make an octane
for i in range(3):
octane = attach(octane,ethane,'RH',1,'RH',0)
Update the tag
octane.tag = 'octane'
Rename the residue and resname for octane
for pk,p in octane.particles.items():
p.residue = 2
p.resname = "OCT"
octane.write_xyz()
Print new rsite
’s
print(octane.show_rsites())
Find the 4th carbon to attach an ethane
print(octane.particles[14].symbol)
octane.particles[14].rsite = 'R2'
octane.find_rsites()
Attach the ethane to the fourth carbon to make 4-ethyloctane
ethyl_octane = attach(octane,ethane,'R2',0,'RH',0)
ethyl_octane.tag = '4-ethyloctane'
ethyl_octane.write_xyz()
Read in oplsaa parameters from forcefield example
oplsaa = streamm.forcefields.parameters.Parameters('oplsaa')
oplsaa.import_json()
print(oplsaa)
for pk,ptypes in oplsaa.particletypes.items():
print(ptypes.fftype1)
Create NWChem Calculation object
nwchem_i = streamm.NWChem('nw_ethane_HF')
Add calculation to project
alkyl_example.add_calc(nwchem_i)
Set the structure of the calculation to ethane
nwchem_i.strucC = ethane
Set the resource to be local
nwchem_i.set_resource(res_local)
Make the local directories
nwchem_i.make_dir()
Change to the scratch
directory
os.chdir(nwchem_i.dir['scratch'])
Copy the template files to the scratch directory
file_type = 'templates'
file_key = 'run'
file_name = "nwchem.sh"
from_dirkey = 'templates'
to_dirkey = 'scratch'
nwchem_i.cp_file(file_type,file_key,file_name,from_dirkey,to_dirkey)
file_type = 'templates'
file_key = 'nw'
file_name = "nwchem.nw"
from_dirkey = 'templates'
to_dirkey = 'scratch'
nwchem_i.cp_file(file_type,file_key,file_name,from_dirkey,to_dirkey)
Read in the template files and add them to the str
dictionary
nwchem_i.load_str('templates','nw')
nwchem_i.load_str('templates','run')
Set the properties dictionary to desired calculation details
nwchem_i.properties['basis'] = '6-31g'
nwchem_i.properties['method'] = 'UHF'
nwchem_i.properties['charge'] = 0
nwchem_i.properties['spin_mult'] = 1
nwchem_i.properties['task'] = 'SCF '
nwchem_i.properties['coord'] = nwchem_i.strucC.write_coord()
pprint(nwchem_i.properties)
Replace the keys in the template strings and write the input files
nwchem_i.replacewrite_prop('nw','input','nw','%s.nw'%(nwchem_i.tag))
Add the input file to the properties to be written into the run file
nwchem_i.properties['input_nw'] = nwchem_i.files['input']['nw']
nwchem_i.replacewrite_prop('run','scripts','run','%s.sh'%(nwchem_i.tag))
Add the log file to the files dictionary
file_type = 'output'
file_key = 'log'
file_name = "%s.log"%(nwchem_i.tag)
nwchem_i.add_file(file_type,file_key,file_name)
Change back to the root directory and write a json file
os.chdir(nwchem_i.dir['home'])
alkyl_example.export_json()
Change back to scratch
os.chdir(nwchem_i.dir['scratch'])
Run the bash script for the calculation or submit the job to the cluster
nwchem_i.run()
Check the status of all the calculations in the project
alkyl_example.check()
Run the analysis
nwchem_i.analysis()
Tar and zip the results and copy them to a storage location
nwchem_i.store()
Save json in home directory
os.chdir(nwchem_i.dir['home'])
alkyl_example.export_json()
Create a Gaussian Calculation object
gaussian_i = streamm.Gaussian('gaus_ethane_HF')
Add the calculation to the project
alkyl_example.add_calc(gaussian_i)
Set the structure of the calculation to ethane
gaussian_i.strucC = ethane
Set the resource to be local
gaussian_i.set_resource(res_local)
Make the local directories
gaussian_i.make_dir()
Copy the template files to the scratch directory
os.chdir(gaussian_i.dir['scratch'])
Copy the template files to the scratch directory
file_type = 'templates'
file_key = 'run'
file_name = "gaussian.sh"
from_dirkey = 'templates'
to_dirkey = 'scratch'
gaussian_i.cp_file(file_type,file_key,file_name,from_dirkey,to_dirkey)
file_type = 'templates'
file_key = 'com'
file_name = "gaussian.com"
from_dirkey = 'templates'
to_dirkey = 'scratch'
gaussian_i.cp_file(file_type,file_key,file_name,from_dirkey,to_dirkey)
Read in the template files and add them to the str
dictionary
gaussian_i.load_str('templates','com')
gaussian_i.load_str('templates','run')
Set the properties dictionary to desired calculation details
gaussian_i.properties['commands'] = 'HF/3-21G SP'
gaussian_i.properties['method'] = 'UHF'
gaussian_i.properties['charge'] = 0
gaussian_i.properties['spin_mult'] = 1
gaussian_i.properties['coord'] = gaussian_i.strucC.write_coord()
pprint(gaussian_i.properties)
Replace the keys in the template strings and write the input files
gaussian_i.replacewrite_prop('com','input','com','%s.com'%(gaussian_i.tag))
Add the input file to the properties to be written into the run file
gaussian_i.properties['input_com'] = gaussian_i.files['input']['com']
gaussian_i.replacewrite_prop('run','scripts','run','%s.sh'%(gaussian_i.tag))
Add the log file to the files dictionary
file_type = 'output'
file_key = 'log'
file_name = "%s.log"%(gaussian_i.tag)
gaussian_i.add_file(file_type,file_key,file_name)
Change back to the root directory and write a json file
os.chdir(gaussian_i.dir['home'])
alkyl_example.export_json()
Change back to scratch
os.chdir(gaussian_i.dir['scratch'])
Run the bash script for the calculation or submit the job to the cluster
gaussian_i.run()
Check the status of all the calculations in the project
alkyl_example.check()
Run the analysis
os.chdir(alkyl_example.dir['home'])
alkyl_example.export_json()
Create a LAMMPS Calculation object
lmp_alkyl = streamm.LAMMPS('lmp_alkyl')
Turn periodic boundaries on in all three directions
lmp_alkyl.strucC.lat.pbcs = [True,True,True]
Run the add_struc()
function to create 10 randomly placed
4-ethyloctane molecules
seed = 92734
lmp_alkyl.strucC = streamm.add_struc(lmp_alkyl.strucC,ethyl_octane,10,seed)
The add_struc()
function randomly places each molecule in a space
defined by the lattice of the lmp_alkyl.strucC, then randomly rotates
it.
Then the function checks to make sure it does not overlap any other particles that are already in the lmp_alkyl.strucC.
If an overlap is found a new position and rotation is chosen until the max placements are exceeded, then the entire system is cleared, and the placement starts again. If the maximum restarts are exceeded, then the size of the lattice is increased, until all the molecules have been added.
Check the lattice to see if it expanded
print(lmp_alkyl.strucC.lat)
Find the maximum molecule index
print(lmp_alkyl.strucC.n_molecules())
print(ethyl_octane.tag)
Update the structure tag
lmp_alkyl.strucC.tag = ethyl_octane.tag + '_x10'
Write the structure to an xyz file
lmp_alkyl.strucC.write_xyz()
Add 10 ethanes to the structure container
seed = 283674
lmp_alkyl.strucC = streamm.add_struc(lmp_alkyl.strucC,ethane,10,seed)
print(lmp_alkyl.strucC.n_molecules())
Update tag
lmp_alkyl.strucC.tag += '_ethane_x10'
Add 50 methane to structure container using the add_struc_grid()
,
which places solvent on grid
lmp_alkyl.strucC = streamm.add_struc_grid(lmp_alkyl.strucC,methane,50)
Check to see if the lattice was expanded
print(lmp_alkyl.strucC.lat)
Update tag
lmp_alkyl.strucC.tag += '_methane_x50'
lmp_alkyl.strucC.write_xyz()
Print all the particles in the structure container
for pk,p in lmp_alkyl.strucC.particles.items():
print(p,p.paramkey,p.mol,p.residue,p.resname)
Set ff parameters for all the bonds, bond angles and dihedrals in the structure container
lmp_alkyl.paramC = oplsaa
lmp_alkyl.set_ffparam()
Add template files to calculations
file_type = 'templates'
file_key = 'in'
file_name = "lammps_spneut.in"
from_dirkey = 'templates'
to_dirkey = 'scratch'
lmp_alkyl.cp_file(file_type,file_key,file_name,from_dirkey,to_dirkey)
pprint("Calculation:{} has status:{}".format(lmp_alkyl.tag,lmp_alkyl.meta['status']))
Calculate the center mass of structure
lmp_alkyl.strucC.calc_center_mass()
Create groups out of the molecules
groupset_i = streamm.Groups('mol',lmp_alkyl.strucC)
groupset_i.group_prop('mol','group_mol')
Calculate the center of mass, radius and asphericity of each group
groupset_i.calc_cent_mass()
groupset_i.calc_radius_asphericity()
groupset_i.calc_dl()
Write the center of mass of each group to an .xyz file for visualization
groupset_i.write_cm_xyz()
import numpy as np
print(np.mean(groupset_i.radius),groupset_i.strucC.unit_conf['length'])
print(groupset_i.strucC.lat.pbcs)
Create a neighbor list of groups
groupset_i.group_nblist.radii_nblist(groupset_i.strucC.lat,groupset_i.cent_mass,groupset_i.radius,radii_buffer=5.25)
Apply periodic boundaries to all the groups, so the molecules are not split across pbc’s
groupset_i.group_pbcs()
Loop over each group, shift the group to the center of the simulation cell and write an .xyz file that includes the neighbors of the group.
for gk_i,g_i in groupset_i.groups.items():
if( len(g_i.pkeys) == 32 ):
print(g_i.tag,groupset_i.group_nblist.calc_nnab(gk_i),g_i.mol)
print(g_i.cent_mass)
list_i = []
for g_j in groupset_i.group_nblist.getnbs(gk_i):
list_i += groupset_i.groups[g_j].pkeys
groupset_i.strucC.shift_pos(-1.0*g_i.cent_mass) # Place center of mass at origin
groupset_i.strucC.write_xyz_list(list_i,xyz_file='{}_blob.xyz'.format(g_i.tag))
groupset_i.strucC.shift_pos(g_i.cent_mass) # Return center of mass
Fancy aye!