def monomer(): try: s = system.read_pubchem_smiles('CC') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC.mol')) f = forcefield.Gaff() s.apply_forcefield(f) c1 = s.particles[1] c2 = s.particles[2] c1.linker = 'head' c2.linker = 'tail' for b in c1.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c1 else b.b s.particles.remove(pb.tag, update=False) break for b in c2.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c2 else b.b s.particles.remove(pb.tag, update=False) break s.remove_spare_bonding() lmps.quick_min(s, min_style='fire') s.add_particle_bonding() return s
def run(test=False): # use a smiles string to query the pubchem search database and read the mol file returned from the http request # if cannot get to internet, read local cached response from pubchem try: s = system.read_pubchem_smiles('c1=cc=cc=c1') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'c1=cc=cc=c1.mol')) # the resulting system (benzene) has alternating double bonds # we want pysimm to recognize the ring as aromatic, so we define each bond in the ring to be bond order 'A' for b in s.bonds: if b.a.elem == 'C' and b.b.elem == 'C': b.order = 'A' # the resulting system has sufficient information to type with a forcefield, here we will use the Dreiding force field # we will also determine partial charges using the gasteiger algorithm s.apply_forcefield(forcefield.Dreiding(), charges='gasteiger') # we'll perform a 2 step energy minimization using the steepest decent and conjugate gradient algorithms in LAMMPS lmps.quick_min(s, min_style='sd', name='min_sd') lmps.quick_min(s, min_style='cg', name='min_cg') # write a few different file formats s.write_xyz('benzene.xyz') s.write_yaml('benzene.yaml') s.write_lammps('benzene.lmps') s.write_chemdoodle_json('benzene.json')
def monomer(): try: s = system.read_pubchem_smiles('CC(C)C(=O)OC') except: import os s = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC(C)C(=O)OC.mol')) f = forcefield.Dreiding() s.apply_forcefield(f) c3 = s.particles[3] c4 = s.particles[4] for b in c3.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c3 else b.b s.particles.remove(pb.tag, update=False) break for b in c4.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c4 else b.b s.particles.remove(pb.tag, update=False) break s.remove_spare_bonding() c3.linker = 'head' c4.linker = 'tail' lmps.quick_min(s, min_style='fire') s.add_particle_bonding() return s
def equilibrate(self): lmps.quick_min(self.polymer) equil(self.polymer, tfinal=self.equil_temp, np=self.nproc, output_settings=self.equil_output, log='log.equil', length_list=[self.equil_step_length for _ in range(7)])
def Cl(): s = system.System() m = s.molecules.add(system.Molecule()) f = forcefield.Dreiding() dreiding_Na_ = s.particle_types.add(f.particle_types.get('Cl')[0].copy()) s.particles.add(system.Particle(type=dreiding_Na_, x=0, y=0, z=0, charge=-1, molecule=m)) s.apply_forcefield(f) s.pair_style = 'lj/cut' lmps.quick_min(s, min_style='fire') return s
def monomer(): try: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'disGde.mol')) # s = system.read_pubchem_smiles('O=C(OCCSSCCC(O)=O)CC') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC(C)C(=O)OC.mol')) f = forcefield.Gaff() s.apply_forcefield(f) c3 = s.particles[1] c4 = s.particles[2] for b in c3.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c3 else b.b s.particles.remove(pb.tag, update=False) break for b in c4.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c4 else b.b s.particles.remove(pb.tag, update=False) break s.remove_spare_bonding() c3.linker = 'head' c4.linker = 'tail' lmps.quick_min(s, min_style='cg') s.add_particle_bonding() s.apply_charges(f, charges='gasteiger') signal = 0 for pb in s.particles: if pb.elem == 'O' and 1 in pb.bond_orders and len(set( pb.bond_orders)) == 1: signal += 1 if signal == 2 and pb.elem == 'O' and 1 in pb.bond_orders and len( set(pb.bond_orders)) == 1: pb.charge = pb.charge - 1 return s
def monomer(): try: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'disIpro.mol')) # s = system.read_pubchem_smiles('CCC(OCCSSCCN)=O') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC(C)C(=O)OC.mol')) f = forcefield.Dreiding() s.apply_forcefield(f) c3 = s.particles[1] c4 = s.particles[2] for b in c3.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c3 else b.b s.particles.remove(pb.tag, update=False) break for b in c4.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c4 else b.b s.particles.remove(pb.tag, update=False) break s.remove_spare_bonding() c3.linker = 'head' c4.linker = 'tail' lmps.quick_min(s, min_style='cg') s.add_particle_bonding() s.apply_charges(f, charges='gasteiger') for pb in s.particles: if pb.elem == 'N': pb.charge = pb.charge + 1.0 return s
def monomer(): try: s = system.read_pubchem_smiles('CCc1=cc=cc=c1') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CCc1=cc=cc=c1.mol')) m = s.molecules[1] f = forcefield.Gaff() for b in s.bonds: if b.a.bonds.count == 3 and b.b.bonds.count == 3: b.order = 4 s.apply_forcefield(f) c1 = s.particles[1] c5 = s.particles[5] for b in c1.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c1 else b.b s.particles.remove(pb.tag, update=False) break for b in c5.bonds: if b.a.elem == 'H' or b.b.elem == 'H': pb = b.a if b.b is c5 else b.b s.particles.remove(pb.tag, update=False) break s.remove_spare_bonding() s.set_box(padding=10) c1.linker = 'head' c5.linker = 'tail' lmps.quick_min(s, min_style='fire') s.add_particle_bonding() return s
def run(test=False): # use a smiles string to query the pubchem search database and read the mol file returned from the http request try: s = system.read_pubchem_smiles('CO') except: import os s = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CO.mol')) # the resulting system has sufficient information to type with a forcefield, here we will use the GAFF2 force field s.apply_forcefield(forcefield.Gaff2()) # we'll perform energy minimization using the fire algorithm in LAMMPS lmps.quick_min(s, min_style='fire') # write a few different file formats s.write_xyz('methanol.xyz') s.write_yaml('methanol.yaml') s.write_lammps('methanol.lmps') s.write_chemdoodle_json('methanol.json')
def SPC(): try: s = system.read_pubchem_smiles('[H]O[H]') except: import os s = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir, 'CC.mol')) f = forcefield.Dreiding() s.apply_forcefield(f) for pb in s.particles: if pb.elem == 'H': pb.charge = 0.4238 elif pb.elem == 'O': pb.charge = -0.8476 lmps.quick_min(s, min_style='fire') return s
def run(test=False): # we'll make a polystyrene monomer from the pysimm models database A = NbTMS(isomer="exoexo") # we'll instantiate a Dreiding forcefield object for use later f = forcefield.Dreiding() # the monomers do not have any charges, so we will derive partial charges using the gasteiger algorithm A.apply_charges(f, charges='gasteiger') # the buckingham potential isn't great at small distances, and therefore we use the LJ potential while growing the polymer A.pair_style = 'lj/cut' # run the polymer random walk tacticity method with 10 total repeat units polymer = random_walk_tacticity(A, 20, forcefield=f, capped=True, tacticity='syndiotactic', rotation=180, errorCheck=False, sim=0) writeFileFormats(polymer, "polymer", unwrap=True) #quick opt of polymer lmps.quick_min(polymer, min_style='fire', etol=1.0e-4, maxiter=100000) # write a few different file formats polymer.unwrap() writeFileFormats(polymer, "polymer_fired") #pack multiple copies of polymer polymers = system.replicate(polymer, 8, density=0.005) #polymers = polymer writeFileFormats(polymers, "polymers") lmps.quick_min(polymers, min_style='fire', etol=1.0e-4, maxiter=100000) writeFileFormats(polymers, "polymers_fired") #quickmd nvt_settings = { 'name': 'nvt_md', 'print_to_screen': True, 'ensemble': 'nvt', 'temperature': { 'start': 100, 'stop': 300 }, 'new_v': True, 'length': 10000 } npt_settings = { 'name': 'npt_md', 'print_to_screen': True, 'ensemble': 'npt', 'temperature': 300, 'new_v': True, 'pressure': { 'start': 1000, 'stop': 1 }, 'length': 100000, 'thermo_style': 'custom step temp press density' } #nvt runs okay, but npt fails...need to add neigh_modify command to reneighbor more often during compression of npt step #lmps.quick_md(polymers, debug=True, **nvt_settings) #writeFileFormats(polymers,"polymers_nvt") #lmps.quick_md(polymers, debug=True, **npt_settings) #lmps.quick_md(polymers) #writeFileFormats(polymers,"polymers_npt") sim = lmps.Simulation(polymers, name='nptAndReneighbor', debug=True) sim.add_custom('neigh_modify delay 0') sim.add(lmps.Velocity(temperature=1000)) sim.add_md(length=10000, ensemble='npt', temperature=1000, pressure=5000) sim.run() writeFileFormats(polymers, "polymers_npt") writeFileFormats(polymers, "polymers_npt_unwrapped", unwrap=True) #21-step equilibration equil(polymers, np=1, pmax=50000) writeFileFormats(polymers, "polymers_equil") polymers.unwrap() writeFileFormats(polymers, "polymers_equil_unwrap")
system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h2 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h3 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h4 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) # let's add gasteiger charges s.apply_charges(f, charges='gasteiger') # right now there is no simulation box defined # we'll define a box surrounding our methane molecule with a 10 angstrom padding s.set_box(padding=10) # before we optimize our structure, LAMMPS needs to know what type of # pair, bond, and angle interactions we are using # these are determined by the forcefield being used s.pair_style = 'lj' s.bond_style = 'harmonic' s.angle_style = 'harmonic' # we'll perform energy minimization using the fire algorithm in LAMMPS lmps.quick_min(s, min_style='fire') # write xyz, YAML, LAMMPS data, and chemdoodle json files s.write_xyz('methane.xyz') s.write_yaml('methane.yaml') s.write_lammps('methane.lmps') s.write_chemdoodle_json('methane.json')
def run(test=False): try: ethanol = system.read_pubchem_smiles('CCO') except: import os ethanol = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CCO.mol')) try: acetone = system.read_pubchem_smiles('CC(=O)C') except: import os acetone = system.read_mol(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CC(=O)C.mol')) f = forcefield.Gaff2() ethanol.apply_forcefield(f, charges='gasteiger') acetone.apply_forcefield(f, charges='gasteiger') # amber.calc_charges(ethanol) # amber.calc_charges(acetone) lmps.quick_min(ethanol, min_style='fire') lmps.quick_min(acetone, min_style='fire') molecule_list = [ethanol, acetone] if test: n_molecules = [20, 20] else: n_molecules = [200, 200] s = system.replicate(molecule_list, n_molecules, density=0.3) min_settings = { 'name': 'cg_min', 'min_style': 'cg', 'maxiter': int(5e+5), 'maxeval': int(5e+6), } nvt_settings = { 'name': 'nvt_md', 'print_to_screen': True, 'ensemble': 'nvt', 'temperature': { 'start': 100, 'stop': 300 }, 'new_v': True, 'length': 2500 } npt_settings = { 'name': 'npt_md', 'print_to_screen': True, 'ensemble': 'npt', 'temperature': 300, 'new_v': True, 'pressure': { 'start': 1000, 'stop': 1 }, 'length': 5000, } npt_settings_add = { 'name': 'npt_md', 'print_to_screen': True, 'ensemble': 'npt', 'temperature': 300, 'new_v': True, 'pressure': { 'start': 1, 'stop': 1 }, 'length': 5000, } if test: nvt_settings['length'] = 2000 npt_settings['length'] = 2000 sim = lmps.Simulation(s) sim.add_min(**min_settings) sim.add(lmps.OutputSettings(thermo={'freq': 500, 'style': 'custom', 'args': ['step', 'temp', 'etotal', 'press', 'density']})) sim.add_md(**nvt_settings) sim.add_md(**npt_settings) sim.add_md(**npt_settings_add) sim.run() s.write_yaml('mixture.yaml') s.write_lammps('mixture.lmps')
# use a smiles string to query the pubchem search database and read the mol file returned from the http request pmma = system.read_pubchem_smiles('cc(C)(C(=O)OC)') # we'll instantiate a GAFF2 forcefield object for use later f = forcefield.Gaff2() # particles 3 and 6 in the monomer are going to be the head and tail linkers pmma.particles[3].linker = 'head' pmma.particles[6].linker = 'tail' # the resulting system has sufficient information to type with the forcefield object we made earlier # we will also determine partial charges using the gasteiger algorithm pmma.apply_forcefield(f, charges='gasteiger') # do a quick minimization of the monomer lmps.quick_min(pmma, min_style='fire') # write a yaml file for the pmma monomer pmma.write_yaml('pmma_monomer.yaml') # we're going to make 4 chains, each of 5 repeat units # the first system we make will be used as the initial system for the subsequent random walk calls polymer = random_walk(pmma, nmon=5, forcefield=f, density=0.3 / 4) polymer = random_walk(pmma, nmon=5, s_=polymer, forcefield=f) polymer = random_walk(pmma, nmon=5, s_=polymer, forcefield=f) polymer = random_walk(pmma, nmon=5, s_=polymer, forcefield=f) # write a few different file formats polymer.write_xyz('polymer.xyz') polymer.write_yaml('polymer.yaml') polymer.write_lammps('polymer.lmps')
def random_walk_tacticity(m, nmon, s_=None, **kwargs): """pysimm.apps.random_walk.random_walk_tacticity Builds homopolymer with controllable tacticity from capped monomer structure Args: m: reference monomer :class:`~pysimm.system.System`. Must be a capped monomer, with headCap and tail_cap as the first and last atoms in the .mol file. nmon: total number of monomers to add to chain s_: :class:`~pysimm.system.System` in which to build polymer chain (None) extra_bonds: EXPERMINTAL, True if making ladder backbone polymer settings: dictionary of simulation settings density: density at which to build polymer (0.3) forcefield: :class:`~pysimm.forcefield.Forcefield` object to acquire new force field parameters unwrap: True to unwrap final system debug: Boolean; print extra-output (False) traj: True to build xyz trajectory of polymer growth (True) limit: during MD, limit atomic displacement by this max value (LAMMPS ONLY) sim: :class:`~pysimm.lmps.Simulation` object for relaxation between polymer growth tacticity: float between 0 and 1. 1 = 100% isotactic insertions 0 = 100% syndiotactic insertions 0.5 = equal changes of isotactic or syndiotactic insertions (i.e. atactic) rotation: degrees to rotate monomer per insertion md_spacing: how many monomer insertion steps to perform between MD relaxation steps (1) error_check: True/False for if monomers should be checked for hardcore overlaps after insertion Returns: new polymer :class:`~pysimm.system.System` """ m = m.copy() extra_bonds = kwargs.get('extra_bonds', False) settings = kwargs.get('settings', {}) density = kwargs.get('density', 0.3) f = kwargs.get('forcefield') unwrap = kwargs.get('unwrap') traj = kwargs.get('traj', True) debug = kwargs.get('debug', False) limit = kwargs.get('limit', 0.1) sim = kwargs.get('sim') tacticity = kwargs.get('tacticity', 0.5) if tacticity == 'atactic': tacticity = 0.5 elif tacticity == 'isotactic': tacticity = 1 elif tacticity == 'syndiotactic': tacticity = 0 elif not (0 <= tacticity <= 1): sys.exit("tacticity must be a number between 0 and 1, or 'atactic' (0.5), " "'isotactic' (1), or 'syndiotactic' (0)") tact_seq = [False] * round((nmon - 1) * tacticity) + [True] * ((nmon - 1) - round((nmon - 1) * tacticity)) random.shuffle(tact_seq) rotation = kwargs.get('rotation', 0) md_spacing = kwargs.get('md_spacing', 1) error_check = kwargs.get('error_check', False) m.add_particle_bonding() if error_check: lmps.quick_min(m, min_style='fire') # Automatically redefine linkers if they have specially defined names for p in m.particles: if p.type.name.find('@') >= 0 and p.type.name.split('@')[0].find('H'): p.linker = 'head' elif p.type.name.find('@') >= 0 and p.type.name.split('@')[0].find('T'): p.linker = 'tail' m.remove_linker_types() # Check whether the monomer is decorated correctly if not __check_tags__(m.particles): sys.exit("random_walk:random_walk_tacticity() requires a **monomer capped with a single atom** as an input" " (i.e. to model polyethylene, ethane as a monomer is required). \n" "\tIn addition to 'head' and 'tail', 3 other tags should be defined: \n" "\t\t(i) p.linker = 'mirror' for a particle that defines plane for iso- syndio- tactic reflection \n" "\t\t(ii) p.rnd_wlk_tag = 'head_cap' and p.rnd_wlk_tag = 'tail_cap' for particles that capping head " "and tail linkers correspondingly \n \t\t(see the example #13 of this distribution for details)") # Remove tail-cap if it exists for p in m.particles: if p.linker == 'tail': for p_ in p.bonded_to: if p_.rnd_wlk_tag == 'tail_cap': p.charge += p_.charge # unite charge of tailcap into head m.particles.remove(p_.tag) # remove tailcap of monomer m.remove_spare_bonding() break # Add first monomer to the output system if s_ is None: s = system.replicate(m, 1, density=density / nmon) else: s = system.replicate(m, 1, s_=s_, density=None) print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), 1, nmon)) if traj: s.write_xyz('random_walk.xyz') s.add_particle_bonding() # Main polymerisation loop for insertion in range(nmon - 1): n = m.copy() head = None tail = None mirror_atom = None for p in n.particles: if p.linker == 'head': head = p elif p.linker == 'tail': tail = p elif p.linker == 'mirror': mirror_atom = p backbone_vector = np.array(find_last_backbone_vector(s, m)) tail_vector = np.array(find_last_tail_vector(s.particles[-n.particles.count:])) for p, p_ in zip(s.particles[-1 * n.particles.count:], n.particles): # translate monomer a = 1.1 # coefficient of displacement of a new monomer along the head--tail direction b = 2.4 # coefficient of displacement of a new monomer along the head--headcap direction p_.x = p.x + a * backbone_vector[0] + b * tail_vector[0] p_.y = p.y + a * backbone_vector[1] + b * tail_vector[1] p_.z = p.z + a * backbone_vector[2] + b * tail_vector[2] if tact_seq[insertion]: # if syndiotactic insertion, reflect monomer print("syndiotactic insertion...") mirrorPlane = define_plane(head, tail, mirror_atom) for p in n.particles: p.x, p.y, p.z = reflect_coords_thru_plane([p.x, p.y, p.z], mirrorPlane) else: # else isotatic insertion, rotate monomer if necessary print("isotatic insertion...") if rotation != 0: # rotate monomer, if necessary rot_mat = rot_mat_about_axis(backbone_vector, rotation) n.rotate(around=head, rot_matrix=rot_mat) for p_ in s.particles[-n.particles.count:]: if p_.rnd_wlk_tag == 'head_cap': head.charge += p_.charge # unite charge of head_cap into tail atom s.particles.remove(p_.tag) # Removing head_cap atom from growing chain s.remove_spare_bonding() break if extra_bonds: heads = [] for p in s.particles[-n.particles.count:]: if p.linker == 'head': heads.append(p) else: for p in s.particles[-n.particles.count:]: if p.linker == 'head': head = p s.add(n, change_dim=False) s.add_particle_bonding() if extra_bonds: tails = [] for p in s.particles[-n.particles.count:]: if p.linker == 'tail': tails.append(p) else: for p in s.particles[-n.particles.count:]: if p.linker == 'tail': tail = p if debug: for p in s.particles: if not p.bonded_to: print(p.tag) if head and tail: s.make_new_bonds(head, tail, f) print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), insertion + 2, nmon)) elif extra_bonds and len(heads) == len(tails): for h, t in zip(heads, tails): s.make_new_bonds(h, t, f) print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), insertion + 2, nmon)) else: print('cannot find head and tail') if sim is None: sim = lmps.Simulation(s, name='relax_%03d' % (insertion + 2), log='relax.log', **settings) if (insertion + 2) % md_spacing == 0: sim.add_md(ensemble='nve', limit=limit, **settings) # sim.add_min(**settings) if isinstance(sim, lmps.Simulation): s_ = s.copy() sim.system = s sim.name = 'relax_%03d' % (insertion + 2) sim.run(np=settings.get('np')) energy = lmps.energy(s) print("LAMMPS Energy = " + str(energy)) print("LAMMPS Energy/#ofAtoms = " + str(energy / s.particles.count)) if error_check == True: # check for hardcore overlap print("checking for hardcore overlap") if s.quality(tolerance=0.3) > 0: print("Found bad quality monomer insertion. Redoing last insertion...") s.unwrap() s.write_xyz('bad_insertion_' + str(insertion + 2) + '.xyz') s.wrap() redo_monomer_insertion(s_, n, insertion + 2) s = s_.copy() if traj: s.unwrap() s.write_xyz('random_walk.xyz', append=True) # Removing the very last 'head_cap' at the end of the chain for p_ in s.particles[-n.particles.count:]: if p_.rnd_wlk_tag == 'head_cap': head.charge += p_.charge # unite charge of head_cap into tail atom s.particles.remove(p_.tag) # Removing head_cap atom from growing chain s.remove_spare_bonding() # Syncronizing molecule representation with particles ItemContainer representation for the chain s.objectify() if debug: s.write_lammps('polymer.lmps') s.write_xyz('polymer.xyz') s.unwrap() return s
def run(test=False): # we'll make a polyethylene monomer and a polystyrene monomer from the pysimm models database pe = pe_monomer() ps = ps_monomer() ba = ba_monomer() H20 = water_water() dise = dise_monomer() disg = disg_monomer() disi = disi_monomer() amide = amide_monomer() peg = peg_monomer() Na = pos_salt() Cl = neg_salt() # we'll instantiate a Dreiding forcefield object for use later f = forcefield.gaff2() # the monomers do not have any charges, so we will derive partial charges using the gasteiger algorithm pe.apply_charges(f, charges='gasteiger') ps.apply_charges(f, charges='gasteiger') #H20.apply_charges(f,charges = 'gasteiger') ba.apply_charges(f, charges='gasteiger') peg.apply_charges(f, charges='gasteiger') amide.apply_charges(f, charges='gasteiger') dise.apply_charges(f, charges='gasteiger') # the buckingham potential isn't great at small distances, and therefore we use the LJ potential while growing the polymer pe.pair_style = 'lj/cut' ps.pair_style = 'lj/cut' H20.pair_style = 'lj/cut' ba.pair_style = 'lj/cut' dise.pair_style = 'lj/cut' disg.pair_style = 'lj/cut' peg.pair_style = 'lj/cut' amide.pair_style = 'lj/cut' disi.pair_style = 'lj/cut' Na.pair_style = 'lj/cut' Cl.pair_style = 'lj/cut' ######## Heres the Paramaters you can edit ########## ##### Specifiy What Monomer that you are going to use and the frequency of each Monomer polist = [ba, amide, disg, disi, dise] monlist = [10, 80, 5, 4, 1] n_molecules = 50000 # Number of Water Molecules Try to keep it at 10,000 ##Current Monomers available # PEG5 : peg # Butyl Acrylate : ba # amide monomer: amide # Ethelyne: pa # Polystyrene: ps # MethylAcrylate: pmma # disulfideG: disg # disulfideI: disi # disulfideE: dise #################################################################################### pattern = shuffle(monlist, polist) # run the copolymer random walk method with 10 total repeat units, using an alternating pattern z = np.ones(len(pattern)) setter = [] for elem in range(0, len(z)): setter.append(int(z[elem])) print(setter) polymer = copolymer(pattern, len(pattern), pattern=setter, forcefield=f) polymer.write_xyz('polymernonsolvated.xyz') charge = 0 for pb in polymer.particles: charge = charge + pb.charge print("The System has: " + str(charge) + " charge") numSa = round(charge) if charge < 0: salt = 'Na' charg = +1 else: salt = 'Cl' charg = -1 partition = n_molecules / (abs(numSa) + 1) if round(charge) == 0: system.replicate([H20], n_molecules, s_=polymer, density=0.6) else: for iters in range(0, abs(numSa) + 1): system.replicate([H20], abs(int(partition)), s_=polymer, density=0.6) if iters == abs(numSa): lmps.quick_min(polymer, min_style='sd') break m = polymer.molecules.add(system.Molecule()) dreiding_salt_ = polymer.particle_types.add( f.particle_types.get(salt)[0].copy()) polymer.particles.add( system.Particle(type=dreiding_salt_, x=polymer.dim.dx / 2, y=polymer.dim.dy / 2, z=polymer.dim.dz / 2, charge=charg, molecule=m)) lmps.quick_min(polymer, min_style='sd') charge = 0 for pb in polymer.particles: charge = charge + pb.charge print("The System has: " + str(charge) + " charge") if charge < 0: salt = 'Na' charg = +1 else: salt = 'Cl' charg = -1 m = polymer.molecules.add(system.Molecule()) dreiding_salt_ = polymer.particle_types.add( f.particle_types.get(salt)[0].copy()) polymer.particles.add( system.Particle(type=dreiding_salt_, x=polymer.dim.dx / 2, y=polymer.dim.dy / 2, z=polymer.dim.dz / 2, charge=-charge, molecule=m)) lmps.quick_min(polymer, min_style='sd') charge = 0 for pb in polymer.particles: charge = charge + pb.charge print("The System has: " + str(charge) + " charge") # write a few different file formats polymer.write_xyz('polymersolvated.xyz') # polymer.write_yaml('polymer.yaml') polymer.write_lammps('polymer.lmps')
# use a smiles string to query the pubchem search database and read the mol file returned from the http request pe = system.read_pubchem_smiles('cc') # we'll instantiate a GAFF2 forcefield object for use later f = forcefield.Gaff2() # particles 1 and 2 in the monomer are going to be the head and tail linkers pe.particles[1].linker = 'head' pe.particles[2].linker = 'tail' # the resulting system has sufficient information to type with the forcefield object we made earlier # we will also determine partial charges using the gasteiger algorithm pe.apply_forcefield(f, charges='gasteiger') # do a quick minimization of the monomer lmps.quick_min(pe, min_style='fire') # write a yaml file for the pe monomer pe.write_yaml('pe_monomer.yaml') # use a smiles string to query the pubchem search database and read the mol file returned from the http request ps = system.read_pubchem_smiles('cc(C1=CC=CC=C1)') # particles 8 and 7 in the monomer are going to be the head and tail linkers ps.particles[8].linker = 'head' ps.particles[7].linker = 'tail' # like in example 3, we need to identify the bonds in the ring as aromatic for b in ps.bonds: if (not b.a.linker and not b.b.linker) and b.a.elem == 'C' and b.b.elem == 'C':
def pack_and_equil(A, n, x, f, prefix): # A: monomer # n: number of monomers # x: number of chains # f: forcefield # prefix: prefix for output files # run the polymer random walk tacticity method with n total repeat units polymer = random_walk_tacticity(A, n, forcefield=f, capped=True, tacticity='syndiotactic', rotation=180, error_check=False, sim=0) write_file_formats(polymer, prefix + "_1", unwrap=True) # quick opt of polymer lmps.quick_min(polymer, min_style='fire', etol=1.0e-4, maxiter=100000) # write a few different file formats polymer.unwrap() write_file_formats(polymer, prefix + "_1_fire") # pack x copies of polymer polymers = system.replicate(polymer, x, density=0.005) # polymers = polymer write_file_formats(polymers, prefix + "_" + str(x)) lmps.quick_min(polymers, min_style='fire', etol=1.0e-4, maxiter=100000) write_file_formats(polymers, prefix + "_" + str(x) + "_fire") # quickmd nvt_settings = { 'name': 'nvt_md', 'print_to_screen': True, 'ensemble': 'nvt', 'temperature': { 'start': 100, 'stop': 300 }, 'new_v': True, 'length': 10000 } npt_settings = { 'name': 'npt_md', 'print_to_screen': True, 'ensemble': 'npt', 'temperature': 300, 'new_v': True, 'pressure': { 'start': 1000, 'stop': 1 }, 'length': 100000, 'thermo_style': 'custom step temp press density' } # npt calcs need "add neigh_modify" command to reneighbor more often during compression of npt step sim = lmps.Simulation(polymers, name='npt_reneighbor', debug=True) sim.add_custom('neigh_modify delay 0') sim.add(lmps.Velocity(temperature=1000)) sim.add_md(length=10000, ensemble='npt', temperature=1000, pressure=5000) sim.run() write_file_formats(polymers, prefix + "_" + str(x) + "_npt") write_file_formats(polymers, prefix + "_" + str(x) + "_npt_unwrapped", unwrap=True) # 21-step equilibration equil(polymers, np=1, pmax=50000) write_file_formats(polymers, prefix + "_" + str(x) + "_equil") write_file_formats(polymers, prefix + "_" + str(x) + "_equil_unwrapped", unwrap=True)
def run(test=False): try: ethanol = system.read_pubchem_smiles('CCO') except: import os ethanol = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CCO.mol')) try: acetone = system.read_pubchem_smiles('CC(=O)C') except: import os acetone = system.read_mol( os.path.join(os.path.dirname(os.path.realpath(__file__)), 'CC(=O)C.mol')) f = forcefield.Gaff2() ethanol.apply_forcefield(f, charges='gasteiger') acetone.apply_forcefield(f, charges='gasteiger') # amber.calc_charges(ethanol) # amber.calc_charges(acetone) lmps.quick_min(ethanol, min_style='fire') lmps.quick_min(acetone, min_style='fire') molecule_list = [ethanol, acetone] if test: n_molecules = [30, 20] else: n_molecules = [300, 200] s = system.replicate(molecule_list, n_molecules, density=0.3) min_settings = { 'name': 'fire_min', 'min_style': 'fire', 'print_to_screen': True } nvt_settings = { 'name': 'nvt_md', 'print_to_screen': True, 'ensemble': 'nvt', 'temperature': { 'start': 100, 'stop': 300 }, 'new_v': True, 'length': 10000 } npt_settings = { 'name': 'npt_md', 'print_to_screen': True, 'ensemble': 'npt', 'temperature': 300, 'new_v': True, 'pressure': { 'start': 1000, 'stop': 1 }, 'length': 100000, 'thermo_style': 'custom step temp press density' } if test: nvt_settings['length'] = 2000 npt_settings['length'] = 2000 lmps.quick_min(s, **min_settings) lmps.quick_md(s, **nvt_settings) lmps.quick_md(s, **npt_settings) s.write_xyz('mixture.xyz') s.write_yaml('mixture.yaml') s.write_lammps('mixture.lmps') s.write_chemdoodle_json('mixture.json')
def run(test=False): # create empty system print('Example progress: Creating an empty system...') s = system.System() # create new molecule in our system print( 'Example progress: Adding an empty molecule container to our system...' ) m = s.molecules.add(system.Molecule()) # retrieve GAFF2 parameters print('Example progress: Retrieving Dreiding force field parameters...') f = forcefield.Gaff2() s.forcefield = f.name # get a copy of the c3 particle type object from GAFF # get method returns a list, we need the first element gaff_c3 = s.particle_types.add(f.particle_types.get('c3')[0].copy()) # get hc particle type object from GAFF gaff_hc = s.particle_types.add(f.particle_types.get('hc')[0].copy()) # we'll first make the carbon atom at the origin # we'll include gasteiger charges later print('Example progress: Adding carbon atom at origin...') c1 = s.particles.add( system.Particle(type=gaff_c3, x=0, y=0, z=0, charge=0, molecule=m)) # now we'll add 4 hydrogen atoms bonded to our carbon atom # these atoms will be placed randomly 1.5 angstroms from the carbon atom # we'll optimize the structure using LAMMPS afterwords # we supply the GAFF forcefield object so that bond and angle types can be added as well print( 'Example progress: Adding 4 hydrogen atoms at random positions bonded to the carbon atom...' ) h1 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h2 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h3 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) h4 = s.add_particle_bonded_to( system.Particle(type=gaff_hc, charge=0, molecule=m), c1, f) # let's add gasteiger charges print('Example progress: Deriving Gasteiger charges...') s.apply_charges(f, charges='gasteiger') # right now there is no simulation box defined # we'll define a box surrounding our methane molecule with a 10 angstrom padding print( 'Example progress: Constructing Simulation box surrounding our new molecule...' ) s.set_box(padding=10) # before we optimize our structure, LAMMPS needs to know what type of # pair, bond, and angle interactions we are using # these are determined by the forcefield being used s.pair_style = 'lj' s.bond_style = 'harmonic' s.angle_style = 'harmonic' # we'll perform energy minimization using the fire algorithm in LAMMPS print('Example progress: Optimizing structure using LAMMPS...') lmps.quick_min(s, min_style='fire', name='fire_min', etol=1e-10, ftol=1e-10) # write xyz, YAML, LAMMPS data, and chemdoodle json files print('Example progress: Saving structure to files...') s.write_xyz('methane.xyz') s.write_yaml('methane.yaml') s.write_lammps('methane.lmps') s.write_chemdoodle_json('methane.json') print('Example progress: Complete!')