def test_process_rb_torsions(): """Test that the GROMACS driver reports Ryckaert-Bellemans torsions""" import foyer oplsaa = foyer.Forcefield(name="oplsaa") ethanol = Molecule.from_smiles("CCO") ethanol.generate_conformers(n_conformers=1) ethanol.generate_unique_atom_names() # Run this OFFMol through MoSDeF infrastructure and OPLS-AA from openff.system.tests.energy_tests.utils import offmol_to_compound my_compound = offmol_to_compound(ethanol) my_compound.box = mb.Box(lengths=[4, 4, 4]) oplsaa = foyer.Forcefield(name="oplsaa") struct = oplsaa.apply(my_compound) struct.save("eth.top", overwrite=True) struct.save("eth.gro", overwrite=True) # Get single-point energies using GROMACS oplsaa_energies = run_gmx_energy( top_file="eth.top", gro_file="eth.gro", mdp_file=get_mdp_file("default") ) assert oplsaa_energies.energies["Torsion"]._value != 0.0
def test_smiles(self, smiles): import foyer import mbuild as mb # These tests are smiles strings cmpd = mb.load(smiles, smiles=True) ff = foyer.Forcefield(name='oplsaa') structure = ff.apply(cmpd) # Enlarge box to avoid cutoff issues bbox = cmpd.boundingbox bbox.lengths *= 10 if any(bbox.lengths < 10): bbox.lengths = [100, 100, 100] structure.box = [ bbox.lengths[0], bbox.lengths[1], bbox.lengths[2], 90, 90, 90 ] energies = commpare.spawn_engine_simulations(structure, hoomd_kwargs={ 'ref_distance': 10, 'ref_energy': 1 / 4.184 }) print(smiles) print(energies) print('=' * 20)
def _apply_ff(self, untyped_system): if self.system.forcefield == "gaff": ff_path = f"{FF_DIR}/gaff.xml" forcefield = foyer.Forcefield(forcefield_files=ff_path) elif self.system.forcefield == "opls": forcefield = foyer.Forcefield(name="oplsaa") typed_system = forcefield.apply( untyped_system, assert_dihedral_params=self.system.assert_dihedrals ) if self.system.remove_hydrogens: typed_system.strip( [a.atomic_number == 1 for a in typed_system.atoms] ) return typed_system
def initialize(job): water = create_spce_water() water.name = 'SOL' pore = mb.recipes.GraphenePoreSolvent( pore_width=1.0, pore_length=1.0, pore_depth=1.1, n_sheets=1, slit_pore_dim=2, solvent=water, n_solvent=24, x_bulk=0, ) ff = foyer.Forcefield(get_ff("pore-spce.xml")) water = mb.Compound() gph = mb.Compound() for child in pore.children: if child.name == 'SOL': water.add(mb.clone(child)) else: gph.add(mb.clone(child)) typed_water = ff.apply(water, residues='SOL', combining_rule='lorentz') typed_gph = ff.apply(gph, combining_rule='lorentz') typed_pore = typed_gph + typed_water typed_pore.box[1] = 20 with job: write_lammpsdata(typed_pore, 'data.spce') typed_pore.save('init.mol2', overwrite=True) typed_pore.save('init.gro', combine='all', overwrite=True)
def test_unreasonable_coul14(self,ethane): import foyer oplsaa = foyer.Forcefield(name='oplsaa') ethane = oplsaa.apply(ethane) with pytest.raises(ValueError,match=r'Unreasonable value'): mb.formats.cassandramcf.write_mcf(ethane,'ethane.mcf', angle_style='harmonic',dihedral_style='opls',coul14=-1.0)
def test_rb_torsions_vs_foyer(self, ethanol_with_rb_torsions): # Given that these force constants are copied from Foyer's OPLS-AA file, # compare to processing through the current MoSDeF pipeline import foyer import mbuild comp = mbuild.load("CC", smiles=True) comp.xyz = ethanol_with_rb_torsions.positions.m_as(unit.nanometer) ff = foyer.Forcefield(name="oplsaa") from_foyer = ff.apply(comp) from_foyer.box = [40, 40, 40, 90, 90, 90] from_foyer.save("from_foyer.top") from_foyer.save("from_foyer.gro") rb_torsion_energy_from_foyer = _run_gmx_energy( top_file="from_foyer.top", gro_file="from_foyer.gro", mdp_file=_get_mdp_file("default"), ).energies["Torsion"] # GROMACS vs. OpenMM was already compared, so just use one omm = get_gromacs_energies(ethanol_with_rb_torsions, decimal=3).energies[ "Torsion" ] assert (omm - rb_torsion_energy_from_foyer).m_as(kj_mol) < 1e-6
def Compare_Standard_Mol(test_molecule_path,test_forcefield_path): molecule=mb.load(test_molecule_path) parmed_structure = molecule.to_parmed() opls = foyer.Forcefield(forcefield_files=[test_forcefield_path]) typed_molecule = opls.apply(parmed_structure) filepath=os.path.join("./test_molecules/test_molecule_comp.top") typed_molecule.save(filepath,overwrite=True) originalfilepath=os.path.join(test_molecule_path[:-4]+'top') count=0 total=0 halt=0 with open(filepath,'r') as openfile: with open(originalfilepath,'r') as compfile: comp_lines=compfile.readlines()[17:] lines=openfile.readlines()[17:] #print(len(comp_lines),len(lines)) for i,line in enumerate(lines): #print(line) if line == '[ bonds ]\n': halt = 1 if line == '[ pairs ]\n': halt = 0 if not(halt): total+=1 if line == comp_lines[i]: count+=1 if count/total==1.0: print(test_molecule_path[:-5] +' Passed') else: print(test_molecule_path[:-5] +' Failed')
def parmed_hexane_box(self): compound = mb.recipes.Alkane(6) compound.name = "HEX" compound_box = mb.fill_box(compound, n_compounds=6, box=[6, 6, 6]) oplsaa = foyer.Forcefield(name='oplsaa') pmd_structure = oplsaa.apply(compound_box, residues="HEX") return pmd_structure
def parmed_ethane(self): from mbuild.lib.molecules import Ethane compound = Ethane() oplsaa = foyer.Forcefield(name="oplsaa") pmd_structure = oplsaa.apply(compound) return pmd_structure
def typed_ethane(): from mbuild.lib.molecules import Ethane mb_ethane = Ethane() oplsaa = foyer.Forcefield(name='oplsaa') pmd_ethane = oplsaa.apply(mb_ethane) top = from_parmed(pmd_ethane) top.name = 'ethane' return top
def main(): if len(sys.argv) != 3: print('usage: python test_atomtypes.py [path_to_xml] [test_dir]') exit(1) else: ffxml_path = sys.argv[1] test_dir = sys.argv[2] # Define the forcefield ff = foyer.Forcefield(forcefield_files=ffxml_path) # Find the test files load_path = test_dir + '/ante_types/' log_path = test_dir + '/compare_antechamber-foyer.log' files = glob.glob(load_path + '/*.mol2') with open(log_path, 'w') as log: for filen in files: molname = re.sub('.mol2', '', re.sub('^.*/', '', filen)) log.write('{}\n'.format(molname)) print('Starting {} ... \n\n'.format(molname)) # Load a molecule and extract antechamber types molecule = pmd.load_file(filen) types_ante = [atom.type for atom in molecule] # Convert to parmed structure, run foyer atomtyping untyped = molecule.to_structure() # Manually fix parmed issue reading 'Br' and 'Cl' as 'B' and 'C' for atom in untyped.atoms: if len(atom.name) > 1: aname = atom.name[0].upper() + atom.name[1].lower() if aname == 'Br': atom.element = 35 elif aname == 'Cl': atom.element = 17 # For now -- just check atom typing -- not the existence of parameters foyer_typed = ff.apply(untyped, assert_bond_params=False, assert_angle_params=False, assert_dihedral_params=False) # Regex to remove extra _ tags for 'extra' atomtypes types_foyer = [ re.sub('_.*$', '', atom.type) for atom in foyer_typed ] # Compare assert len(types_foyer) == len( types_ante), 'Different numbers of atoms!' idxs = range(len(types_foyer)) for idx, type_a, type_f in zip(idxs, types_ante, types_foyer): if type_a != type_f: log.write('idx: {:5d} Ante: {:2s} Foyer: {:2s}\n'.format( idx, type_a, type_f))
def typed_ethane(self): from mbuild.lib.molecules import Ethane mb_ethane = Ethane() oplsaa = foyer.Forcefield(name='oplsaa') # At this point, we still need to go through # parmed Structure, until foyer can perform # atomtyping on gmso Topology pmd_ethane = oplsaa.apply(mb_ethane) top = from_parmed(pmd_ethane) return top
def test_opls(self): eth = Alkane(n=10) cmpd = mb.fill_box(eth, n_compounds=10, box=[10, 10, 10]) ff = foyer.Forcefield(name='oplsaa') structure = ff.apply(cmpd) df = commpare.openmm.build_run_measure_openmm(structure) assert 'bond' in df assert 'angle' in df assert 'dihedral' in df assert 'nonbond' in df
def test_opls(self): eth = Alkane(n=10) cmpd = mb.fill_box(eth, n_compounds=10, box=[10, 10, 10]) ff = foyer.Forcefield(name='oplsaa') structure = ff.apply(cmpd) df = commpare.hoomd.build_run_measure_hoomd(structure, ref_energy=1 / 4.184, ref_distance=10) assert 'bond' in df assert 'angle' in df assert 'dihedral' in df assert 'nonbond' in df
def run_gcmc_adsorption(**custom_args): # Use mbuild to create a zeolite supercell from CIF lattice = mbuild.lattice.load_cif(get_example_cif_path("TON")) compound_dict = { "Si": mbuild.Compound(name="Si"), "O": mbuild.Compound(name="O"), } ton = lattice.populate(compound_dict, 3, 3, 6) # Create a coarse-grained methane methane = mbuild.Compound(name="_CH4") # Load forcefields trappe_zeo = foyer.Forcefield(get_example_ff_path("trappe_zeo")) trappe = foyer.forcefields.load_TRAPPE_UA() # Use foyer to apply forcefields ton_ff = trappe_zeo.apply(ton) methane_ff = trappe.apply(methane) # Create box and species list box_list = [ton] species_list = [ton_ff, methane_ff] # Since we have an occupied box we need to specify # the number of each species present in the intial config mols_in_boxes = [[1, 0]] system = mc.System(box_list, species_list, mols_in_boxes=mols_in_boxes) moveset = mc.MoveSet("gcmc", species_list) default_args = { "chemical_potentials": ["none", -30.0 * (u.kJ / u.mol)], "rcut_min": 0.5 * u.angstrom, "vdw_cutoff": 14.0 * u.angstrom, "charge_cutoff": 14.0 * u.angstrom, "coord_freq": 100, "prop_freq": 10, } # Combine default/custom args and override default custom_args = {**default_args, **custom_args} mc.run( system=system, moveset=moveset, run_type="equilibration", run_length=10000, temperature=300.0 * u.K, **custom_args, )
def test_unreasonable_coul14(self, ethane): import foyer oplsaa = foyer.Forcefield(name="oplsaa") ethane = oplsaa.apply(ethane) with pytest.raises(ValueError, match=r"Unreasonable value"): mb.formats.cassandramcf.write_mcf( ethane, "ethane.mcf", angle_style="harmonic", dihedral_style="opls", coul14=-1.0, )
def test_conversions(self): # Check to see if we can correctly spawn engine simulations eth = Alkane(n=10) cmpd = mb.fill_box(eth, n_compounds=10, box=[10, 10, 10]) ff = foyer.Forcefield(name='oplsaa') structure = ff.apply(cmpd) df = commpare.spawn_engine_simulations(structure, hoomd_kwargs={ 'ref_distance': 10, 'ref_energy': 1 / 4.184 }) assert df is not None
def oplsaa_interchange_ethanol(self, oplsaa): molecule = Molecule.from_file( get_test_files_dir_path("foyer_test_molecules") + "/ethanol.sdf" ) molecule.name = "ETH" top = OFFBioTop.from_molecules(molecule) top.mdtop = md.Topology.from_openmm(top.to_openmm()) oplsaa = foyer.Forcefield(name="oplsaa") interchange = Interchange.from_foyer(topology=top, force_field=oplsaa) interchange.positions = molecule.conformers[0].value_in_unit(omm_unit.nanometer) interchange.box = [4, 4, 4] return interchange
def run_nvt_spce(**custom_args): # If no custom args are passed, assign empty dictionary #if custom_args is None: # custom_args = {} # Load water with SPC/E geometry from mol2 file molecule = mbuild.load(get_example_mol2_path("spce")) # Create an empty mbuild.Box box = mbuild.Box(lengths=[3.0, 3.0, 3.0]) # Load forcefields spce = foyer.Forcefield(get_example_ff_path("spce")) # Use foyer to apply forcefields molecule_ff = spce.apply(molecule) # Create box and species list box_list = [box] species_list = [molecule_ff] # Use Cassandra to insert some initial number of species mols_to_add = [[50]] # Define the system object system = mc.System(box_list, species_list, mols_to_add=mols_to_add) # Get the move probabilities moveset = mc.MoveSet("nvt", species_list) default_args = { "angle_style": ["fixed"], } # Combine default/custom args and override default custom_args = {**default_args, **custom_args} # Run a simulation with at 300 K with 10000 MC moveset mc.run( system=system, moveset=moveset, run_type="equilibration", run_length=10000, temperature=300.0 * u.K, **custom_args, )
def create_system(job): """Construct the system in mbuild and apply the forcefield""" import mbuild import foyer import shutil r125 = mbuild.load("C(F)(F)C(F)(F)F", smiles=True) system = mbuild.fill_box(r125, n_compounds=150, density=1000) ff = foyer.Forcefield(job.fn("ff.xml")) system_ff = ff.apply(system) system_ff.combining_rule = "lorentz" system_ff.save(job.fn("unedited.top")) # Get pre-minimized gro file shutil.copy("data/initial_config/system_em.gro", job.fn("system.gro"))
def main(): content = _generate_r125_xml() with open('ff.xml','w') as inp: inp.write(content) r125 = mbuild.load('C(F)(F)C(F)(F)F',smiles=True) system = mbuild.fill_box(r125,n_compounds=150,density=1000) ff = foyer.Forcefield('ff.xml') system_ff = ff.apply(system) system_ff.combining_rule = 'lorentz' system_ff.save('system.gro') system_ff.save('system.top') content = _generate_em_mdp() with open('em.mdp','w') as inp: inp.write(content)
def main(): content = _generate_r32_xml() with open("ff.xml", "w") as inp: inp.write(content) r32 = mbuild.load("C(F)(F)", smiles=True) system = mbuild.fill_box(r32, n_compounds=150, density=1000) ff = foyer.Forcefield("ff.xml") system_ff = ff.apply(system) system_ff.combining_rule = "lorentz" system_ff.save("system.gro") system_ff.save("system.top") content = _generate_em_mdp() with open("em.mdp", "w") as inp: inp.write(content)
def __init__( self, slabs, ref_distance=None, gap=0.1 ): self.type = "interface" self.ref_distance = ref_distance if not isinstance(slabs, list): slabs = [slabs] if len(slabs) == 2: slab_files = slabs else: slab_files = slabs * 2 interface = mb.Compound() slab_1 = self._gsd_to_mbuild(slab_files[0], self.ref_distance) slab_2 = self._gsd_to_mbuild(slab_files[1], self.ref_distance) interface.add(new_child=slab_1, label="left") interface.add(new_child=slab_2, label="right") x_len = interface.get_boundingbox().Lx interface["left"].translate((-x_len - gap, 0, 0)) system_box = mb.box.Box.from_mins_maxs_angles( mins=(0, 0, 0), maxs = interface.get_boundingbox().lengths, angles = (90, 90, 90) ) system_box._Lx += 2 * self.ref_distance * 1.1225 interface.box = system_box # Center in the adjusted box interface.translate_to( [interface.box.Lx / 2, interface.box.Ly / 2, interface.box.Lz / 2,] ) ff_path = f"{FF_DIR}/gaff-nosmarts.xml" forcefield = foyer.Forcefield(forcefield_files=ff_path) self.system = forcefield.apply(interface)
def initialize(job): water = create_spce_water() water.name = 'SOL' pore = mb.recipes.GraphenePoreSolvent( pore_width=2.0, pore_length=3.0, pore_depth=3.0, n_sheets=3, slit_pore_dim=2, solvent=water, n_solvent=job.sp.nwater, x_bulk=0, ) pore.periodicity[1] = 6.0 ff = foyer.Forcefield(get_ff("pore-spce.xml")) water = mb.Compound() gph = mb.Compound() for child in pore.children: if child.name == 'SOL': water.add(mb.clone(child)) else: gph.add(mb.clone(child)) typed_water = ff.apply(water, residues='SOL', combining_rule='lorentz') typed_gph = ff.apply(gph, combining_rule='lorentz') typed_pore = typed_gph + typed_water typed_pore.box[1] = 60 with job: typed_pore.save('init.gro', combine='all', overwrite=True) typed_pore.save('init.top', combine='all', overwrite=True) typed_pore.save('init.mol2', overwrite=True) #add_settles('init.top') write_ndx(path='.')
def build(cmpd, density=0.5*u.gram/(u.cm**3), n_compounds=1000, ff='ff/TraPPE_UA_3_fully_flexible_propane.xml'): """ Build and parametrize a TraPPE system at a given state Parameters ---------- cmpd : mb.Compound This compound should also have the path to its XML as `cmpd.xml` density : unyt.Quantity Desired density for packing and siulation n_compounds : int """ density.convert_to_units(u.kilogram/u.m**3) # Pack a box box = mb.fill_box(cmpd, n_compounds=n_compounds, density=density.value) # Wrap coordinates new_xyz = box.xyz - 1 * np.floor_divide(box.xyz, box.periodicity) * box.periodicity box.xyz = new_xyz # Apply non-atomistic, custom element naming convention for part in box.particles(): part.name = "_" + part.name # Utilize foyer to parametrize our box ff = foyer.Forcefield(forcefield_files=ff) box = box.to_parmed(infer_residues=True) parametrized_structure = ff.apply(box, combining_rule='lorentz') # Dump initial coordinates parametrized_structure.save('compound.pdb', overwrite=True) parametrized_structure.save('compound.mol2', overwrite=True) parametrized_structure.save('compound.gro', overwrite=True) return parametrized_structure
def Check_Forcefield(mbuild_structure, forcefield_path,list_types=False,verbose=False): parmed_structure = mbuild_structure.to_parmed() opls = foyer.Forcefield(forcefield_files=[forcefield_path]) typed_surface = opls.apply(parmed_structure,verbose=verbose,assert_bond_params=False,assert_angle_params=False, assert_improper_params=False,assert_dihedral_params=False) if list_types: for i,atom in enumerate(list(typed_surface.atoms)): print(i,atom.type) #typed_surface.save("test_molecules/building_blocks/molecule.mol2",overwrite=True) #typed_surface.save("test_molecules/building_blocks/molecule.top",overwrite=True) failed_atoms=[] for i,atom in enumerate(list(typed_surface.atoms)): #print(atom.type) if atom.type== 'opls_1010': failed_atoms.append(i) tested_molecule = mb.compound.Compound() tested_molecule.from_parmed(structure=typed_surface) for molecule in failed_atoms: list(tested_molecule.particles())[molecule].name='Z' #print(list(tested_molecule.particles())[molecule].name) return(tested_molecule.visualize())
def run_gromacs( filled_pore, pve_ion=mbuild.Compound(name="Na"), nve_ion=mbuild.Compound(name="Cl"), ): """Run MD simulation in GROMACS at the specified temperature Parameters ---------- filled_pore : porebuilder.GraphenePoreSolvent pore filled with water and (optional) ions pve_ion : mbuild.Compound, optional, default=Na positive ion nve_ion : mbuild.Compound, optional, default=Cl negative ion Returns ------- None: runs simulation """ if not os.path.isfile("slitpore.gro"): # Create mb.Compound of water and ions in slitpore # Load foyer ff ff = foyer.Forcefield(get_ff("pore-spce-jc.xml")) # Extract just the pore and apply ff empty_pore = filled_pore.children[0] typed_pore = ff.apply(empty_pore) # Extract the electrolyte molecules electrolyte = filled_pore.children[1:] # Extract water and apply ff water = mbuild.Compound([ mbuild.clone(child) for child in electrolyte if child.name == "SOL" ]) typed_electrolyte = ff.apply(water, residues="SOL") # Extract ions if there are any cations = mbuild.Compound([ mbuild.clone(child) for child in electrolyte if child.name == pve_ion.name ]) anions = mbuild.Compound([ mbuild.clone(child) for child in electrolyte if child.name == nve_ion.name ]) if len(cations.children) > 0: typed_cations = ff.apply(cations, residues=pve_ion.name) typed_anions = ff.apply(anions, residues=nve_ion.name) typed_electrolyte += typed_cations + typed_anions # Combine ParmEd structures typed_slitpore = typed_pore + typed_electrolyte typed_slitpore.combining_rule = 'lorentz' # Save ParmEd structure to GROMACS files typed_slitpore.save("slitpore.gro", combine="all", overwrite=True) typed_slitpore.save("slitpore.top", combine="all", overwrite=True) # Create idx file cmd = f'printf "! r RES\nq\n" | gmx make_ndx -f slitpore.gro -o index.ndx' os.system(cmd) # Run energy minimization _gromacs_str("em", "slitpore") # Run NVT simulation _gromacs_str("nvt", "em")
def typed_chloroethanol(self): compound = mb.load('C(CCl)O', smiles=True) oplsaa = foyer.Forcefield(name='oplsaa') pmd_structure = oplsaa.apply(compound) top = from_parmed(pmd_structure) return top
def typed_methylnitroaniline(self): compound = mb.load('CC1=C(C=CC(=C1)[N+](=O)[O-])N', smiles=True) oplsaa = foyer.Forcefield(name='oplsaa') pmd_structure = oplsaa.apply(compound) top = from_parmed(pmd_structure) return top
def md_files(job): import mbuild as mb import foyer water = create_spce_water() water.name = "SOL" pore = mb.recipes.GraphenePoreSolvent( pore_width=1.0, pore_length=1.0, pore_depth=1.1, n_sheets=1, slit_pore_dim=2, solvent=water, n_solvent=job.sp.nwater, x_bulk=0, ) ff = foyer.Forcefield(get_ff("pore-spce.xml")) pore.translate([0, 0.3325, 0]) water = mb.Compound() gph = mb.Compound() for child in pore.children: if child.name == "SOL": water.add(mb.clone(child)) else: gph.add(mb.clone(child)) typed_water = ff.apply(water, residues="SOL", combining_rule="lorentz") typed_gph = ff.apply(gph, combining_rule="lorentz") typed_pore = typed_gph + typed_water typed_pore.box[1] = 20 with job: import os import glob import numpy as np import unyt as u import mbuild as mb from cp2kmdpy.molecule_optimization import ( Molecule_optimization, ) # for single molecule optimization from cp2kmdpy.md import MD # for running MD from cp2kmdpy import runners import setter typed_pore.save("init.mol2", overwrite=True) temperature = job.sp.T * u.K # Defining the molecule we want to simulate graphene_water = mb.load("init.mol2") molecule = graphene_water box = mb.box.Box(lengths=[0.9824, 2, 1.0635]) q = MD( molecules=[molecule], box=box, cutoff=650, functional="BLYP", basis_set={ "C": "DZVP-MOLOPT-SR-GTH", "H": "DZVP-MOLOPT-SR-GTH", "O": "DZVP-MOLOPT-SR-GTH", }, periodicity="XYZ", n_molecules=[1], traj_type="PDB", seed=1, project_name="carbon_water", initial_coordinate_filename="init.mol2", fixed_list="1..80", ) q.temperature = temperature q.ensemble = "NVT" q.simulation_time = 1000 * u.ps # Initializing q q.md_initialization() # generating input files setter.md_files(q) job.doc.input_filename = q.input_filename job.doc.output_filename = q.output_filename job.doc.restart_filename = q.project_name + "-1.restart"