def run(test=False): # we'll create a pmma monomer from the pysimm.models database pmma = monomer() # we'll instantiate a Dreiding forcefield object for use later f = forcefield.Dreiding() pmma.pair_style = 'lj/cut' # we're going to make 4 chains, each of 5 repeat units # the first system we make will be used as the initial system and then replicated to form 4 chains # in this case the system.replicate function take a system input(polymer), # replicates a defined number of times(4), and inserts the new replication randomly(rand=True) at the specified density(0.022) print('Building polymer chain 1...') polymer = random_walk(pmma, nmon=5, forcefield=f) print('Replicating polymer chain...') uniform_polymer = system.replicate(polymer, 4, density=0.022, rand=True) # next we're going to make 4 chains, with lengths of 2, 4, 6, and 8 monomer units # the first system we make will be used as the initial system for the subsequent random walk calls print('Building polymer chain 1...') nonuniform_polymer = random_walk(pmma, nmon=2, forcefield=f, density=0.3/4) print('Building polymer chain 2...') nonuniform_polymer = random_walk(pmma, nmon=4, s_=nonuniform_polymer, forcefield=f) print('Building polymer chain 3...') nonuniform_polymer = random_walk(pmma, nmon=6, s_=nonuniform_polymer, forcefield=f) print('Building polymer chain 4...') nonuniform_polymer = random_walk(pmma, nmon=8, s_=nonuniform_polymer, forcefield=f) # now that we have our two polymer systems, let's calculate their molecular weight dispersity uniform_polymer.set_mm_dist() nonuniform_polymer.set_mm_dist() print('') print('Uniform polymer') print('---------------') print('Number average molecular weight: {}'.format(uniform_polymer.mn)) print('Weight average molecular weight: {}'.format(uniform_polymer.mw)) print('Dispersity: {}'.format(uniform_polymer.dispersity)) print('') print('Nonuniform polymer') print('------------------') print('Number average molecular weight: {}'.format(nonuniform_polymer.mn)) print('Weight average molecular weight: {}'.format(nonuniform_polymer.mw)) print('Dispersity: {}'.format(nonuniform_polymer.dispersity)) # write a few different file formats uniform_polymer.write_yaml('uniform_polymer.yaml') uniform_polymer.write_xyz('uniform_polymer.xyz') nonuniform_polymer.write_yaml('nonuniform_polymer.yaml') nonuniform_polymer.write_xyz('nonuniform_polymer.xyz')
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')
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 random_walk(m, nmon, s_=None, **kwargs): """pysimm.apps.random_walk.random_walk Builds homopolymer using random walk methodology Args: m: reference monomer :class:`~pysimm.system.System` 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 geometry_rule: a pointer to a method that orients series of atoms of the next repetitive unit in random run 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 capped: True/False if monomers are capped unwrap: True to unwrap final system 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 debug: Boolean; print extra-output Returns: new polymer :class:`~pysimm.system.System` """ m = m.copy() extra_bonds = kwargs.get('extra_bonds', False) displ_next_unit = kwargs.get('geometry_rule', displ_next_unit_default) settings = kwargs.get('settings', {}) density = kwargs.get('density', 0.3) f = kwargs.get('forcefield') capped = kwargs.get('capped') unwrap = kwargs.get('unwrap') traj = kwargs.get('traj', True) limit = kwargs.get('limit', 0.1) sim = kwargs.get('sim') debug = kwargs.get('debug', False) m.add_particle_bonding() 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() 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') # Remove tail-cap if it exists if capped: if __check_tags__(m, req_tags=['tail', 'tail_cap']): 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 m.add_particle_bonding() else: sys.exit("The capped flag is on, however, the 'tail_cap' atom is not defined") for insertion in range(nmon - 1): head = None tail = None info = displ_next_unit(m, s.particles[-1 * m.particles.count:]) n = m.copy() if extra_bonds: heads = [] for p in s.particles[-1*n.particles.count:]: if p.linker == 'head': heads.append(p) else: for p in s.particles[-1*n.particles.count:]: if p.linker == 'head': head = p # Remove head-cap if it exists if capped: if __check_tags__(m, req_tags=['head_cap']): for p_ in s.particles[-m.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 s.add_particle_bonding() else: sys.exit("The capped flag is on, however, the 'head_cap' atom is not defined") s.add(n, change_dim=False) s.add_particle_bonding() if extra_bonds: tails = [] for p in s.particles[-1*n.particles.count:]: if p.linker == 'tail': tails.append(p) else: for p in s.particles[-1*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)): order = [(0, 0), (1, 1)] if len(info) == 2: order = [(0, info[0]), (1, info[1])] for elm in order: s.make_new_bonds(heads[elm[0]], tails[elm[1]], f) ''' for h, t, ord in zip(heads, tails, extra_bonds): s.make_new_bonds(h, tails[ord], f) ''' print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), insertion + 2, nmon)) s.write_lammps('curr_progress.lmps') else: print('cannot find head and tail') if sim is None: sim = lmps.Simulation(s, name='relax_%03d' % (insertion + 2), log='relax.log', **settings) sim.add_md(ensemble='nve', limit=limit, **settings) sim.add_min(**settings) if isinstance(sim, lmps.Simulation): sim.system = s sim.name = 'relax_%03d' % (insertion + 2) sim.run(np=settings.get('np')) if traj: s.unwrap() s.write_xyz('random_walk.xyz', append=True) if unwrap: s.wrap() for p in s.particles: if p not in s.molecules[p.molecule.tag].particles: s.molecules[p.molecule.tag].particles.add(p) if debug: s.write_lammps('polymer.lmps') s.write_xyz('polymer.xyz') s.unwrap() return s
def copolymer(m, nmon, s_=None, **kwargs): """pysimm.apps.random_walk.copolymer Builds copolymer using random walk methodology using pattern Args: m: list of reference monomer :class:`~pysimm.system.System`s nmon: total number of monomers to add to chain s_: :class:`~pysimm.system.System` in which to build polymer chain (None) 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 capped: True/False if monomers are capped unwrap: True to unwrap final system traj: True to build xyz trajectory of polymer growth (True) pattern: list of pattern for monomer repeat units, should match length of m ([1 for _ in range(len(m))]) limit: during MD, limit atomic displacement by this max value (LAMMPS ONLY) sim: :class:`~pysimm.lmps.Simulation` object for relaxation between polymer growth Returns: new copolymer :class:`~pysimm.system.System` """ m = [x.copy() for x in m] settings = kwargs.get('settings', {}) density = kwargs.get('density', 0.3) f = kwargs.get('forcefield') capped = kwargs.get('capped') unwrap = kwargs.get('unwrap') traj = kwargs.get('traj', True) pattern = kwargs.get('pattern', [1 for _ in range(len(m))]) limit = kwargs.get('limit', 0.1) sim = kwargs.get('sim') for m_ in m: m_.add_particle_bonding() 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() if s_ is None: s = system.replicate(m[0], 1, density=density/nmon) else: s = system.replicate(m[0], 1, s_=s_, density=density/nmon) print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), 1, nmon)) for p in s.particles: if p.linker == 'head': last_head = p elif p.linker == 'tail': last_tail = p for m_ in m: if capped: m_.particles.remove(1) m_.remove_spare_bonding() m_.add_particle_bonding() s.add_particle_bonding() if traj: s.write_xyz('random_walk.xyz') temp_nmon = 1 while True: m_ = m.pop(0) m.append(m_) p_ = pattern.pop(0) pattern.append(p_) if temp_nmon == 1 and p_ == 1: m_ = m.pop(0) m.append(m_) p_ = pattern.pop(0) pattern.append(p_) elif temp_nmon == 1: p_ -= 1 for insert in range(p_): head = None tail = None backbone_vector = np.array([last_head.x - last_tail.x, last_head.y - last_tail.y, last_head.z - last_tail.z]) ref_head = None ref_tail = None for p in m_.particles: if p.linker == 'head': ref_head = p elif p.linker == 'tail': ref_tail = p if ref_head and ref_tail: ref_backbone_vector = np.array([ref_head.x - ref_tail.x, ref_head.y - ref_tail.y, ref_head.z - ref_tail.z]) rot_matrix = calc.find_rotation(ref_backbone_vector, backbone_vector) m_.rotate(around=ref_tail, rot_matrix=rot_matrix) translation_vector = [last_tail.x - ref_tail.x, last_tail.y - ref_tail.y, last_tail.z - ref_tail.z] for p in m_.particles: p.x = p.x + translation_vector[0] + 3*backbone_vector[0] p.y = p.y + translation_vector[1] + 3*backbone_vector[1] p.z = p.z + translation_vector[2] + 3*backbone_vector[2] else: print('reference molecule has no head or tail') n = m_.copy() if capped: s.particles.remove(s.particles.count) s.remove_spare_bonding() s.add_particle_bonding() s.add(n, change_dim=False) s.add_particle_bonding() head = last_head for p in s.particles[-1*n.particles.count:]: if p.linker == 'tail': tail = p s.make_new_bonds(head, tail, f) temp_nmon += 1 print('%s: %s/%s monomers added' % (strftime('%H:%M:%S'), temp_nmon, nmon)) if unwrap: s.unwrap() if sim is None: sim = lmps.Simulation(s, name='relax_%03d' % (temp_nmon), log='relax.log', **settings) sim.add_md(ensemble='nve', limit=limit, **settings) sim.add_min(**settings) if isinstance(sim, lmps.Simulation): sim.system = s sim.name = 'relax_%03d' % (temp_nmon) sim.run(np=settings.get('np')) if unwrap: s.unwrap() if unwrap: s.wrap() for p in s.particles[-1*n.particles.count:]: if p.linker == 'head': last_head = p elif p.linker == 'tail': last_tail = p if temp_nmon >= nmon: break if unwrap: if not s.unwrap(): error_print('something went wrong') return s if traj: s.write_xyz('random_walk.xyz', append=True) if unwrap: s.wrap() for p in s.particles: if p not in s.molecules[p.molecule.tag].particles: s.molecules[p.molecule.tag].particles.add(p) s.write_lammps('polymer.lmps') s.unwrap() s.write_xyz('polymer.xyz') 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')
def random_walk(m, nmon, s_=None, **kwargs): """pysimm.apps.random_walk.random_walk Builds homopolymer using random walk methodology Args: m: reference monomer :class:`~pysimm.system.System` 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 capped: True/False if monomers are capped unwrap: True to unwrap final system 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 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') capped = kwargs.get('capped') unwrap = kwargs.get('unwrap') traj = kwargs.get('traj', True) limit = kwargs.get('limit', 0.1) sim = kwargs.get('sim') m.add_particle_bonding() 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() 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') if capped: m.particles.remove(1) m.remove_spare_bonding() m.add_particle_bonding() for insertion in range(nmon - 1): head = None tail = None backbone_vector = np.array(find_last_backbone_vector(s, m)) for p, p_ in zip(s.particles[-1 * m.particles.count:], m.particles): p_.x = p.x + 3 * backbone_vector[0] p_.y = p.y + 3 * backbone_vector[1] p_.z = p.z + 3 * backbone_vector[2] n = m.copy() if capped: s.particles.remove(s.particles.count) s.remove_spare_bonding() s.add_particle_bonding() if extra_bonds: heads = [] for p in s.particles[-1 * n.particles.count:]: if p.linker == 'head': heads.append(p) else: for p in s.particles[-1 * 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[-1 * n.particles.count:]: if p.linker == 'tail': tails.append(p) else: for p in s.particles[-1 * n.particles.count:]: if p.linker == 'tail': tail = p 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) sim.add_md(ensemble='nve', limit=limit, **settings) sim.add_min(**settings) if isinstance(sim, lmps.Simulation): sim.system = s sim.name = 'relax_%03d' % (insertion + 2) sim.run(np=settings.get('np')) s.unwrap() if traj: s.write_xyz('random_walk.xyz', append=True) if unwrap: s.wrap() for p in s.particles: if p not in s.molecules[p.molecule.tag].particles: s.molecules[p.molecule.tag].particles.add(p) s.write_lammps('polymer.lmps') s.unwrap() s.write_xyz('polymer.xyz') return s
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 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): # 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")