def run(test=False): frame = system.read_lammps('irmof-14.lmps') frame.forcefield = 'dreiding-lj' gas1 = system.read_lammps('ch4.lmps') gas1.forcefield = 'trappe/amber' mc_props = { 'rigid_type': False, 'max_ins': 2000, 'Chemical_Potential_Info': -22.5037, 'Temperature_Info': 300, 'Rcutoff_Low': 1.0, 'Run_Type': { 'steps': 100 }, 'CBMC_Info': { 'rcut_cbmc': 2.0 }, 'Simulation_Length_Info': { 'run': 10000, 'coord_freq': 10000, 'prop_freq': 500 }, 'VDW_Style': { 'cut_val': 14.0 }, 'Charge_Style': { 'cut_val': 14.0 }, 'Property_Info': { 'prop1': 'energy_total', 'prop2': 'pressure', 'prop3': 'nmols' } } md_props = { 'temp': 300, 'pressure': { 'start': 300, 'iso': 'iso' }, 'timestep': 1, 'cutoff': 14.0, 'length': 10000, 'thermo': 2500, 'dump': 2500, 'np': 6, 'print_to_screen': False } sim_result = mc_md.mc_md(gas1, frame, mcmd_niter=5, sim_folder='results', mc_props=mc_props, md_props=md_props) sim_result.write_lammps('MOFplusME.lmps') sim_result.write_xyz('MOFplusME.xyz')
def test_gas_unwrap(self): # Read molecular system from the file and decorate the frame with fixed property test_sst = system.read_lammps(osp.join(self.data_path, 'wrapped_co2.lmps')) css = cassandra.Cassandra(test_sst) for p in css.system.particles: p.is_fixed = False # Assert that gas molecules are wrapped bnd_lng = [] for p in test_sst.particles: if p.type.name == 'C': for i in [1, 2]: bnd_lng.append( (css.system.particles[p.tag].x - css.system.particles[p.tag + i].x) ** 2 + (css.system.particles[p.tag].y - css.system.particles[p.tag + i].y) ** 2 + (css.system.particles[p.tag].z - css.system.particles[p.tag + i].z) ** 2) self.assertFalse(all([(1.344 < el) and (el < 1.346) for el in bnd_lng])) css.unwrap_gas() # Assert that gas molecules are unwrapped bnd_lng = [] for p in test_sst.particles: if p.type.name == 'C': for i in [1, 2]: bnd_lng.append( (css.system.particles[p.tag].x - css.system.particles[p.tag + i].x) ** 2 + (css.system.particles[p.tag].y - css.system.particles[p.tag + i].y) ** 2 + (css.system.particles[p.tag].z - css.system.particles[p.tag + i].z) ** 2) self.assertTrue(all([(1.344 < el) and (el < 1.346) for el in bnd_lng]))
def run(test=False): # Setup the empty cubic box with bx_size = 60 sst = system.System() sst.dim = system.Dimension(dx=bx_size, dy=bx_size, dz=bx_size, center=[bx_size / 2, bx_size / 2, bx_size / 2]) sst.forcefield = 'trappe/amber' molec = system.read_lammps('c2h4.lmps') molec.forcefield = 'trappe/amber' cs = cassandra.Cassandra(sst) npt_props = cs.read_input('props.inp') npt_props['Pressure_Info'] = 25 # Simulated pressure in bars npt_props['Start_Type'] = {'start_type': 'make_config', 'species': 300} npt_props['Run_Type'] = {'type': 'equilibration', 'steps': [1000, 100]} npt_props['Simulation_Length_Info'] = {'run': 10000} npt_props['Property_Info'] = { 'prop1': 'energy_total', 'prop2': 'volume', 'prop3': 'mass_density' } cs.add_simulation('NPT', species=molec, is_rigid=True, out_folder='results', **npt_props) cs.run() lmps.check_lmps_attr(cs.system) cs.system.write_lammps('final_conf.lmps')
def run(test=False): # Setup the box with acetelene molecules on the regular grid sst = system.System() bx_size = 30 sst.dim = system.Dimension(dx=bx_size, dy=bx_size, dz=bx_size, center=[bx_size / 2, bx_size / 2, bx_size / 2]) sst.forcefield = 'trappe/amber' molec = system.read_lammps('c2h4.lmps') molec.forcefield = 'trappe/amber' cs = cassandra.Cassandra(sst) nvt_props = cs.read_input('props.inp') nvt_props['Temperature_Info'] = 400 nvt_props['Start_Type'] = {'start_type': 'make_config', 'species': 300} nvt_props['Simulation_Length_Info'] = {'run': 300000} nvt_props['Property_Info'] = { 'prop1': 'energy_total', 'prop2': 'pressure', 'prop3': 'mass_density' } cs.add_nvt(species=molec, is_rigid=True, out_folder='results', **nvt_props) cs.run() lmps.check_lmps_attr(cs.system) cs.system.write_lammps('final_conf.lmps')
def test_nonames_mc(self): sst = system.System() sst.dim = system.Dimension(dx=40, dy=40, dz=40, center=[0, 0, 0]) sst.forcefield = 'trappe/amber' css = cassandra.Cassandra(sst) my_gcmc_props = css.read_input(osp.join(self.data_path, 'props.inp')) specie = system.read_lammps(osp.join(self.data_path, 'toluene_nonames.lmps')) specie.forcefield = 'trappe/amber' with pytest.raises(SystemExit) as err_back: css.add_gcmc(species=specie, is_rigid=True, max_ins=200, chem_pot=-30.34, out_folder=self.data_path, **my_gcmc_props) assert err_back.type == SystemExit
def run(test=False): # In order to run CASSANDRA GCMC one need to create the CASSANDRA object sst = system.System() sst.dim = system.Dimension(dx=40, dy=40, dz=45, center=[0, 0, 0]) sst.forcefield = 'trappe/amber' lmps.check_lmps_attr(sst) css = cassandra.Cassandra(sst) # Read the CASSANDRA .inp parameters file -- common way to setup simulations. # Any of the read properties can be modified here afterwards my_gcmc_props = css.read_input('props.inp') # The prefix for the all files that will be created by this run my_gcmc_props['Run_Name'] = 'gas_adsorb' # Set the gas (gas system) to be purged in a box specie1 = system.read_lammps('co2.lmps') specie2 = system.read_lammps('ch4.lmps') specie3 = system.read_lammps('m-xylene.lmps') for s in [specie1, specie2, specie3]: s.forcefield = 'trappe/amber' css.add_gcmc(species=[specie1, specie2, specie3], is_rigid=[True, False, True], max_ins=[2000, 1000, 500], chem_pot=[-27.34, -29.34, -24.59], out_folder='gas_adsorb_results', **my_gcmc_props) css.run() for pt in css.system.particle_types: pt.elem = pt.real_elem css.system.write_lammps('gas_adsorb.lmps') css.system.write_xyz('gas_adsorb.xyz')
def test_read_lammpstrj(self): file_path = os.path.join(self.TEST_DATA_PATH, 'testfile.lammpstrj.$$') test_sst = system.read_lammps(file_path.replace('$$', 'lmps')) # Verifying that the system was read from the lammps file self.assertGreater(len(test_sst.particles), 0) self.assertGreater(len(test_sst.bonds), 0) # Checking that read_lammpstrj actually updates the coordinates of the atoms in the system test_sst.read_lammpstrj(file_path.replace('$$', 'dump'), frame=1) tmp_coords_before = [ test_sst.particles[1].x, test_sst.particles[1].y, test_sst.particles[1].z ] test_sst.read_lammpstrj(file_path.replace('$$', 'dump'), frame=3) tmp_coords_after = [ test_sst.particles[1].x, test_sst.particles[1].y, test_sst.particles[1].z ] self.assertNotEqual(tmp_coords_before[0], tmp_coords_after[0]) and \ self.assertNotEqual(tmp_coords_before[1], tmp_coords_after[1]) and \ self.assertNotEqual(tmp_coords_before[2], tmp_coords_after[2])
def test_read_lammps(self): file_path = os.path.join(self.TEST_DATA_PATH, 'testfile_class2FF.lmps') test_sst = system.read_lammps(file_path) self.assertGreater(len(test_sst.particles), 0) self.assertGreater(len(test_sst.bonds), 0)
from pysimm.apps import mc_md from pysimm import system frame = system.read_lammps('irmof1_drei.lmps') gas1 = system.read_lammps('ch4.lmps') mc_props = { 'rigid_type': False, 'max_ins': 1000, 'Chemical_Potential_Info': -30.09, 'Temperature_Info': 300, 'Run_Type': { 'steps': 250 }, 'CBMC_Info': { 'rcut_cbmc': 2.0 }, 'Simulation_Length_Info': { 'run': 10000, 'coord_freq': 10000, 'prop_freq': 500 }, 'VDW_Style': { 'cut_val': 9.0 }, 'Charge_Style': { 'cut_val': 9.0 }, 'Property_Info': { 'prop1': 'energy_total', 'prop2': 'pressure'
# decorate the system read from a simple .mol file and type it with CHARMM FF parameters and simple gasteiger charges for b in sst.bonds: b.order = 1 ff = forcefield.Charmm() sst.apply_forcefield(ff, charges='gasteiger') sst.set_charge() # also expand the system to a minimal size at which the periodic image convention is held bxSize = 25.0 sst.dim.dx = bxSize sst.dim.dy = bxSize sst.dim.dz = bxSize sst.center('box', [0.0, 0.0, 0.0], True) # read a water molecule from .lmps file that already contains all details solvnt = system.read_lammps('tipS3P.lmps', angle_style='charmm') # knowing volume of the box let's find out how many water molecules are needed to feet at each side of a cubic box: solvnt.set_mass() ngrid = numpy.floor(((bxSize ** 3) * 0.6022 / solvnt.mass) ** (1.0 / 3.0)) # put water molecules in the nodes of a regular grid rng = numpy.linspace(sst.dim.xlo, sst.dim.xhi, int(ngrid) + 1) count = 0 for p in rng[:-1]: for q in rng[:-1]: for t in rng[:-1]: flags = [] for prt in sst.particles: dist = numpy.linalg.norm(numpy.array([prt.x, prt.y, prt.z]) - numpy.array([p, q, t])) flags.append(dist > 1.7)
'(warning) PySIMM:', *a) if pysimm.warning else lambda *a, **k: None pysimm.verbose_print = lambda *a, **k: print( 'PySIMM:', *a) if pysimm.verbose else lambda *a, **k: None pysimm.debug_print = lambda *a, **k: print( '(debug) PySIMM:', *a) if pysimm.debug else lambda *a, **k: None print('\nWelcome to the pySIMM command line interface\n') print( 'This is no more than a python2.7 interactive shell with certain pySIMM modules imported for your convenience' ) print('Importing modules now...') from pysimm import system, amber, lmps, forcefield if args.lammps_data: s = system.read_lammps(args.lammps_data) elif args.molfile: s = system.read_mol(args.molfile) if args.forcefield and args.forcefield in supported_forcefields: if args.forcefield.lower() == 'dreiding': print('typing with %s' % args.forcefield) s.apply_forcefield(forcefield.Dreiding()) elif args.forcefield.lower() == 'pcff': s.apply_forcefield(forcefield.Pcff()) elif args.forcefield: print('forcefield %s is not supported in ' 'command line interface at this time') elif args.cml_file: s = system.read_cml(args.cml_file) elif args.yaml_file: s = system.read_yaml(args.yaml_file)
def run(settings): """pysimm.apps.polymatic.run Runs Polymatic algorithm. Args: settings: object containing Polymatic settings Returns: (True/False, :class:`~pysimm.system.System`) """ if rappture: Rappture.Utils.progress(0, 'Initializing Polymatic...') bonds = 0 os.mkdir('logs') polymatic(os.path.join(settings.polymatic_dir, 'polym_init.pl'), 'data.lmps', 'step_000.lmps') s = system.read_lammps('step_000.lmps', quiet=True) s.read_type_names('types.txt') s.write_lammps('temp.lmps') if rappture: Rappture.Utils.progress( 0, '%s/%s bonds made: ' 'optimizing initial structure...' % (bonds, settings.polym.max_bonds)) if not lmps_min(s, 'initial optimization', settings): s.write_lammps('temp.lmps') polymatic(os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return False, s s.write_lammps('step_000.lmps') s.write_lammps('temp.lmps') while bonds < settings.polym.max_bonds: attempt = 0 while not polymatic(os.path.join(settings.polymatic_dir, 'polym.pl'), 'temp.lmps', 'temp.lmps'): attempt += 1 if rappture: Rappture.Utils.progress( int(float(bonds) / settings.polym.max_bonds * 100), '%s/%s bonds made: attempt #%s to make ' 'new bond' % (bonds, settings.polym.max_bonds, attempt)) s = system.read_lammps('temp.lmps', quiet=True) s.read_type_names('types.txt') if not lmps_step_md(s, bonds, attempt, settings): s.write_lammps('temp.lmps') polymatic( os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return False, s s.write_lammps('temp.lmps') if attempt >= settings.polym.max_md: break if attempt >= settings.polym.max_md: break bonds += 1 if rappture: Rappture.Utils.progress( int(float(bonds) / settings.polym.max_bonds * 100), '%s/%s bonds made: ' 'optimizing newly formed bond' % (bonds, settings.polym.max_bonds)) s = system.read_lammps('temp.lmps', quiet=True) s.read_type_names('types.txt') print('%s: bond %s made successfully' % (strftime('%H:%M:%S'), bonds)) sys.stdout.flush() if not lmps_min(s, 'bond %s optimization' % bonds, settings): s.write_lammps('temp.lmps') polymatic(os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return False, s s.write_lammps('step_%03d.lmps' % bonds) s.write_lammps('temp.lmps') if (bonds % settings.polym.cycle == 0 and (bonds / settings.polym.cycle) % settings.polym.npt_freq == 0): if rappture: Rappture.Utils.progress( int(float(bonds) / settings.polym.max_bonds * 100), '%s/%s bonds made: ' 'performing npt cycle md' % (bonds, settings.polym.max_bonds)) if not lmps_cycle_npt_md(s, bonds, settings): s.write_lammps('temp.lmps') polymatic( os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return False, s s.write_lammps('temp.lmps') elif bonds % settings.polym.cycle == 0: if rappture: Rappture.Utils.progress( int(float(bonds) / settings.polym.max_bonds * 100), '%s/%s bonds made: ' 'performing nvt cycle md' % (bonds, settings.polym.max_bonds)) if not lmps_cycle_nvt_md(s, bonds, settings): s.write_lammps('temp.lmps') polymatic( os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return False, s s.write_lammps('temp.lmps') if rappture: Rappture.Utils.progress(99, 'Finalizing Polymatic') polymatic(os.path.join(settings.polymatic_dir, 'polym_final.pl'), 'temp.lmps', 'final.lmps') return True, s
def run(test=False): # Set to False if you **do not** want to recalculate pure gas adsorption isotherms is_simulate_loadings = False loadings_file = 'loadings.dat' # Option to draw the isotherms: it is either **'ToFile'** or **'ToScreen'** (case insensitive). # Any other value will be interpreted as no graphics graphing = 'none' # Gas names as they will be referred through simulations gas_names = ['ch4', 'co2'] # Corresponding mole fractions of gases that will allow us to calculate their partial pressures through the Dalton's law mol_frac = [0.5, 0.5] # Calibrated previously functional forms of chemical potentials of gases for GCMC simulations as a functions of pressure chem_pots = [ lambda x: 2.4153 * numpy.log(x) - 36.722, lambda x: 2.40 * numpy.log(x) - 40.701 ] # Root directory for some data (For PySIMM examples it is ) data_dir = osp.join('..', '09_cassandra_simulations', 'gcmc') # Setup of adsorbate model gases = [] for gn in gas_names: gases.append(system.read_lammps(osp.join(data_dir, gn + '.lmps'))) gases[-1].forcefield = 'trappe/amber' # Setup of adsorbent model frame = system.read_lammps('pim.lmps') frame.forcefield = 'trappe/amber' # Constant for loadings calculations molec2mmols_g = 1e+3 / frame.mass # Setup of the GCMC simulations css = cassandra.Cassandra(frame) sim_settings = css.read_input('run_props.inp') # This function in given context will calculate the loading from short GCMC simulations def calculate_isotherm_point(gas_name, press): run_fldr = osp.join(gas_name, str(press)) idx = gas_names.index(gas_name) # sim_settings.update({'Run_Name': 'gcmc'}) css.add_gcmc(species=gases[idx], is_new=True, chem_pot=chem_pots[idx](press), out_folder=run_fldr, props_file='gcmc.inp', **sim_settings) css.run() full_prp = css.run_queue[0].get_prp() return molec2mmols_g * numpy.average( full_prp[3][int(len(2 * full_prp[3]) / 3):]) # This function in given context will load the pre-calculated loading value from previously done GCMC simulations def load_isotherm_point(gas_name, press): with open(loadings_file, 'r') as pntr: stream = pntr.read() tmp = stream.split('\n' + gas_name)[1] idx = re.search('[a-zA-Z]|\Z', tmp) value = re.findall('\n{:}\s+\d+\.\d+'.format(press), tmp[:idx.start()])[0] return float(re.split('\s+', value)[-1]) # Calculation of adsorption isotherms for pure CH4 and CO2 gases for further usage in IAST simulations. # This is the **MOST TIME CONSUMING STEP** in this example, if you want to skip it switch the key is_simulated to False # The IAST will be done using PyIAST package, thus isotherms are wrapped into the corresponding object gas_press = [0.1, 1, 5, 10, 25, 50] lk = 'Loading(mmol/g)' pk = 'Pressure(bar)' isotherms = [] loadings = dict.fromkeys(gas_names) for gn in gas_names: loadings[gn] = [] for p in gas_press: if is_simulate_loadings: data = calculate_isotherm_point(gn, p) else: data = load_isotherm_point(gn, p) loadings[gn].append(data) isotherms.append( pyiast.ModelIsotherm(pandas.DataFrame(zip(gas_press, loadings[gn]), columns=[pk, lk]), loading_key=lk, pressure_key=pk, model='BET', optimization_method='Powell')) # The PyIAST run for calculating of mixed adsorption isotherm # Initial guesses of adsorbed mole fractions do span broad range of values, because PyIAST might not find # solution at certain values of mole fractions and through an exception guesses = [[a, 1 - a] for a in numpy.linspace(0.01, 0.99, 50)] for in_g in guesses: mix_loadings = [] try: for p in gas_press: mix_loadings.append( list( pyiast.iast(p * numpy.array(mol_frac), isotherms, verboseflag=False, adsorbed_mole_fraction_guess=in_g))) mix_loadings = numpy.array(mix_loadings) break except: print('Initial guess {:} had failed to converge'.format(in_g)) continue mix_loadings = numpy.sum(mix_loadings, axis=1) mix_isotherm = pyiast.ModelIsotherm(pandas.DataFrame(zip( gas_press, mix_loadings), columns=[pk, lk]), loading_key=lk, pressure_key=pk, model='BET', optimization_method='L-BFGS-B') # Output: Graphing of constructed isotherms def _plot_isotherms(ax, loc_gp, loc_isoth, loc_mix_load, loc_mix_isoth): rng = numpy.linspace(min(loc_gp), max(loc_gp), 100) ax.plot(loc_gp, loadings[gas_names[0]], 'og', lw=2.5, label='{:} loadings'.format(gas_names[0].upper())) ax.plot(rng, [loc_isoth[0].loading(t) for t in rng], '--g', lw=2, label='BET fit of {:} loadings'.format(gas_names[0].upper())) ax.plot(loc_gp, loadings[gas_names[1]], 'or', lw=2.5, label='{:} loadings'.format(gas_names[1].upper())) ax.plot(rng, [loc_isoth[1].loading(t) for t in rng], '--r', lw=2, label='BET fit of {:} loadings'.format(gas_names[1].upper())) ax.plot(loc_gp, loc_mix_load, 'ob', lw=2.5, label='1-to-1 mixture loadings') ax.plot(rng, [loc_mix_isoth.loading(t) for t in rng], '--b', lw=2, label='BET fit of 1-to-1 mixture loadings') ax.set_xlabel('Gas pressure [bar]', fontsize=20) ax.set_ylabel('Loading [mmol / g]', fontsize=20) ax.tick_params(axis='both', labelsize=16) ax.grid(True) ax.legend(fontsize=16) mplp.tight_layout() if graphing.lower() == 'tofile': fig, axs = mplp.subplots(1, 1, figsize=(10, 5)) _plot_isotherms(axs, gas_press, isotherms, mix_loadings, mix_isotherm) mplp.savefig('pim1_mix_adsorption.png', dpi=192) elif graphing.lower() == 'toscreen': mplp.figure() axs = mplp.gca() _plot_isotherms(axs, gas_press, isotherms, mix_loadings, mix_isotherm) mplp.show() with open('iast_loadings.dat', 'w') as pntr: pntr.write('{:}\t\t{:}\n'.format(pk, lk)) pntr.write('{:}-{:} 1-to-1\n'.format(gas_names[0], gas_names[1])) for p, ml in zip(gas_press, mix_loadings): pntr.write('{:}\t\t{:}\n'.format(p, ml))
from collections import OrderedDict # In order to run CASSANDRA GCMC one need to create the CASSANDRA object sst = system.System() sst.dim = system.Dimension(dx=45, dy=45, dz=45, center=[0, 0, 0]) css = cassandra.Cassandra(sst) # Read the CASSANDRA .inp parameters file -- common way to setup simulations. # Any of the read properties can be modified here afterwards my_gcmc_props = css.read_input('props.inp') # The prefix for the all files that will be created by this run my_gcmc_props['Run_Name'] = 'gas_adsorb' # Set the gas (gas system) to be purged in a box specie1 = system.read_lammps('co2.lmps') specie2 = system.read_lammps('ch4.lmps') specie3 = system.read_lammps('m-xylene.lmps') css.add_gcmc(species=[specie1, specie2, specie3], max_ins=[2000, 1000, 500], chem_pot=[-27.34, -29.34, -24.59], out_folder='gas_adsorb_results', **my_gcmc_props) css.run() for pt in css.final_sst.particle_types: pt.elem = pt.real_elem css.final_sst.write_lammps('gas_adsorb.lmps') css.final_sst.write_xyz('gas_adsorb.xyz')
# Corresponding mole fractions of gases that will allow us to calculate their partial pressures through the Dalton's law mol_frac = [0.5, 0.5] # Calibrated previously functional forms of chemical potentials of gases for GCMC simulations as a functions of pressure chem_pots = [ lambda x: 2.4153 * numpy.log(x) - 36.722, lambda x: 2.40 * numpy.log(x) - 40.701 ] # Root directory for some data (For PySIMM examples it is ) data_dir = osp.join('..', '09_cassandra_simulations', 'gcmc') # Setup of adsorbate model gases = [] for gn in gas_names: gases.append(system.read_lammps(osp.join(data_dir, gn + '.lmps'))) gases[-1].forcefield = 'trappe/amber' # Setup of adsorbent model frame = system.read_lammps('pim.lmps') frame.forcefield = 'trappe/amber' # Constant for loadings calculations molec2mmols_g = 1e+3 / frame.mass # Setup of the GCMC simulations css = cassandra.Cassandra(frame) sim_settings = css.read_input('run_props.inp') # This function in given context will calculate the loading from short GCMC simulations
def write_init(l, **kwargs): """pysimm.lmps.write_init Create initialization LAMMPS input based on pysimm.system.System data Args: l: pysimm.system.System object reference kwargs: atom_style: LAMMPS atom_style default=full kspace_style: LAMMPS kspace style default='pppm 1e-4' units: LAMMPS set of units to use default=real special_bonds: LAMMPS special bonds input nonbond_mixing: type of mixing rule for nonbonded interactions default=arithmetic nb_cut: cutoff for nonbonded interactions default=12 """ atom_style = kwargs.get('atom_style') or 'full' kspace_style = kwargs.get('kspace_style') or 'pppm 1e-4' units = kwargs.get('units') or 'real' nb_cut = kwargs.get('nb_cut') or 12.0 special_bonds = kwargs.get('special_bonds') nonbond_mixing = kwargs.get('nonbond_mixing') or 'arithmetic' output = '' if type(l) == str and os.path.isfile(l): l = read_lammps(l, quiet=True) elif type(l) == str: return 'init_system failed to read %s' % l output += 'units %s\n' % units output += 'atom_style %s\n' % atom_style pair_style = None charge = False if l.charge is None: for p in l.particles: if p.charge != 0: charge = True break else: if l.charge != 0: charge = True if not l.pair_style: if l.particle_types[1].sigma and l.particle_types[1].epsilon: if charge: if l.ff_class == '2': pair_style = 'lj/class2/coul/long' else: pair_style = 'lj/cut/coul/long' else: if l.ff_class == '2': pair_style = 'lj/class2' else: pair_style = 'lj/cut' elif (l.particle_types[1].a and l.particle_types[1].rho and l.particle_types[1].c): if charge: pair_style = 'buck/coul/long' else: pair_style = 'buck' else: if l.pair_style.startswith('lj') or l.pair_style.startswith('class2'): if charge: if l.ff_class == '2': pair_style = 'lj/class2/coul/long' else: pair_style = 'lj/cut/coul/long' else: if l.ff_class == '2': pair_style = 'lj/class2' else: pair_style = 'lj/cut' elif l.pair_style.startswith('buck'): if charge: pair_style = 'buck/coul/long' else: pair_style = 'buck' if pair_style: output += 'pair_style %s %s\n' % (pair_style, nb_cut) else: error_print('pair style probably not supported') if charge: output += 'kspace_style %s\n' % kspace_style if not pair_style.startswith('buck'): if nonbond_mixing == 'arithmetic': output += 'pair_modify shift yes mix arithmetic\n' elif nonbond_mixing == 'geometric': output += 'pair_modify shift yes mix geometric\n' else: output += 'pair_modify shift yes mix arithmetic\n' print('%s mixing rule not supported; defaulting to arithmetic' % nonbond_mixing) if l.bond_style: output += 'bond_style %s\n' % l.bond_style else: if l.ff_class == '1': output += 'bond_style harmonic\n' elif l.ff_class == '2': output += 'bond_style class2\n' if l.angles.count > 0: if l.angle_style: output += 'angle_style %s\n' % l.angle_style else: if l.ff_class == '1': output += 'angle_style harmonic\n' elif l.ff_class == '2': output += 'angle_style class2\n' if l.dihedrals.count > 0: if l.dihedral_style: output += 'dihedral_style %s\n' % l.dihedral_style else: if l.ff_class == '1': output += 'dihedral_style harmonic\n' elif l.ff_class == '2': output += 'dihedral_style class2\n' if l.impropers.count > 0: if l.improper_style: output += 'improper_style %s\n' % l.improper_style else: if l.ff_class == '1': output += 'improper_style harmonic\n' elif l.ff_class == '2': output += 'improper_style class2\n' if special_bonds: output += 'special_bonds %s\n' % special_bonds else: output += 'special_bonds amber\n' l.write_lammps('temp.lmps') output += 'read_data temp.lmps\n' if pair_style.startswith('buck'): for pt1 in l.particle_types: for pt2 in l.particle_types: if pt1.tag <= pt2.tag: a = pow(pt1.a*pt2.a, 0.5) c = pow(pt1.c*pt2.c, 0.5) rho = 0.5*(pt1.rho+pt2.rho) output += 'pair_coeff %s %s %s %s %s\n' % (pt1.tag, pt2.tag, a, rho, c) return output
def mc_md(gas_sst, fixed_sst=None, mc_props=None, md_props=None, **kwargs): """pysimm.apps.mc_md Performs the iterative hybrid Monte-Carlo/Molecular Dynamics (MC/MD) simulations using :class:`~pysimm.lmps` for MD and :class:`~pysimm.cassandra` for MC Args: gas_sst (list of :class:`~pysimm.system.System`) : list items describe a different molecule to be inserted by MC fixed_sst (:class:`~pysimm.system.System`) : fixed during th MC steps group of atoms (default: None) Keyword Args: mcmd_niter (int) : number of MC-MD iterations (default: 10) sim_folder (str): relative path to the folder with all simulation files (default: 'results') mc_props (dictionary) : description of all MC properties needed for simulations (see :class:`~pysimm.cassandra.GCMC` and :class:`~pysimm.cassandra.GCMC.props` for details) md_props (dictionary): description of all Molecular Dynamics settings needed for simulations (see :class:`~pysimm.lmps.Simulation` and :class:`~pysimm.lmps.MolecularDynamics` for details) Returns: :class:`~pysimm.system.System`: Final state of the simulated system """ nonrig_group_name = 'nonrigid_b' rig_group_name = 'rigid_b' n_iter = kwargs.get('mcmd_niter', 10) sim_folder = kwargs.get('sim_folder', 'results') xyz_fname = os.path.join(sim_folder, '{:}.md_out.xyz') lmps_fname = os.path.join(sim_folder, '{:}.before_md.lmps') # Define whether the simulations should be continued or start from the scratch l = 1 is_restart = kwargs.get('restart') if is_restart: for f in glob.glob(lmps_fname.format('*')): l = max(l, int(re.match('\A\d+', os.path.split(f)[1]).group())) to_purge = glob.glob(os.path.join(sim_folder, '{:}.*'.format(l + 1))) + \ glob.glob(os.path.join(sim_folder, '{:}.md*'.format(l))) for f in to_purge: os.remove(f) # Creating fixed polymer system fs = None if fixed_sst: if isinstance(fixed_sst, system.System): fs = fixed_sst fs.wrap() else: print('Cannot setup the fixed system for the simulations. Skipping this') # Set the one-molecule gas systems gases = [] if gas_sst: if isinstance(gas_sst, system.System): gases = [gas_sst] elif isinstance(gas_sst, types.ListType): for g in cassandra.make_iterable(gas_sst): if isinstance(g, system.System): gases.append(g) if not gases: print('There are no gas molecules were specified correctely\nThe gas molecules are needed to start the ' 'MC-MD simulations\nExiting...') exit(1) css = cassandra.Cassandra(fixed_sst) # Set the Monte-Carlo properties: mcp = mc_props if mcp: CHEM_POT = cassandra.make_iterable(mcp.get('Chemical_Potential_Info')) if not CHEM_POT: print('Missing chemical potential info\nExiting...') exit(1) else: print('Missing the MC Simulation settings\nExiting...') exit(1) mcp['Start_Type'] = OrderedDict([('species', [1] + [0] * len(CHEM_POT))]) # Set the Molecular-Dynamics properties: sim = None mdp = md_props if not mdp: print('Missing the MD Simulation settings\nExiting...') exit(1) # De-synchronizing type names of the framework and the gases to avoid consolidation of types that PySIMM system does for gi, g in enumerate(gases): for pt in g.particle_types: pt.name += '_g' + str(gi + 1) while l < n_iter + 1: # >>> MC (CASSANDRA) step: mcp['Run_Name'] = str(l) + '.gcmc' css.add_gcmc(species=gases, is_new=True, chem_pot=CHEM_POT, is_rigid=mcp.get('rigid_type') or [False] * len(gases), out_folder=sim_folder, props_file=str(l) + '.gcmc_props.inp', **mcp) if is_restart: # Set gas particles positions from the .chk file, and update some properties css.run_queue[-1].upd_simulation() css.system = css.run_queue[-1].tot_sst.copy() # Set frame particles position and box size dimension from the .lmps file tmp_sst = system.read_lammps(lmps_fname.format(l)) for p in css.system.particles: p.x = tmp_sst.particles[p.tag].x p.y = tmp_sst.particles[p.tag].y p.z = tmp_sst.particles[p.tag].z css.system.dim = tmp_sst.dim is_restart = False else: css.run() css.system.write_lammps(lmps_fname.format(l)) nm_treads = '1' if 'OMP_NUM_THREADS' in os.environ.keys(): nm_treads = os.environ['OMP_NUM_THREADS'] os.environ['OMP_NUM_THREADS'] = '1' # >>> MD (LAMMPS) step: sim_sst = css.system.copy() sim_sst.write_lammps(os.path.join(sim_folder, str(l) + '.before_md.lmps')) sim = lmps.Simulation(sim_sst, print_to_screen=mdp.get('print_to_screen', False), log=os.path.join(sim_folder, str(l) + '.md.log')) sim.add(lmps.Init(cutoff=mdp.get('cutoff'), special_bonds=mdp.get('special_bonds'), pair_modify=mdp.get('pair_modify'))) # custom definitions for the neighbour list updates sim.add_custom('neighbor 1.0 nsq \nneigh_modify once no every 1 delay 0 check yes') # adding group definitions to separate rigid and non-rigid bodies sim.add(lmps.Group('matrix', 'id', css.run_queue[0].group_by_id('matrix')[0])) sim.add(lmps.Group(nonrig_group_name, 'id', css.run_queue[0].group_by_id('nonrigid')[0])) rigid_mols = css.run_queue[0].group_by_id('rigid')[0] if rigid_mols: sim.add(lmps.Group(rig_group_name, 'id', rigid_mols)) # create the description of the molecular dynamics simulation if type(mdp.get('timestep')) == list: sim.add(lmps.OutputSettings(thermo=mdp.get('thermo'), dump={'filename': os.path.join(sim_folder, str(l) + '.md.dump'), 'freq': int(mdp.get('dump'))})) for it, (t, lng) in enumerate(zip(mdp.get('timestep'), mdp.get('length'))): sim.add(lmps.Velocity(style='create')) # adding "run 0" line before velocities rescale for correct temperature init of the # system with rigid molecules if rigid_mols: sim.add_custom('run 0') sim.add(lmps.Velocity(style='scale')) sim.add_md(lmps.MolecularDynamics(name='main_fix_{}'.format(it), group=nonrig_group_name if rigid_mols else 'all', ensemble='npt', timestep=t, temperature=mdp.get('temp'), pressure=mdp.get('pressure'), run=False, extra_keywords={'dilate': 'all'} if rigid_mols else {})) # create the second NVT fix for rigid molecules that cannot be put in NPT fix if rigid_mols: sim.add(lmps.MolecularDynamics(name='rig_fix_{}'.format(it), ensemble='rigid/nvt/small molecule', timestep=t, length=mdp.get('length'), group=rig_group_name, temperature=mdp.get('temp'), pressure=mdp.get('pressure'), run=False)) sim.add_custom('fix tether_fix_{} matrix spring tether 30.0 0.0 0.0 0.0 0.0'.format(it)) sim.add_custom('run {:}\n'.format(lng)) sim.add_custom('unfix main_fix_{:}'.format(it)) sim.add_custom('unfix rig_fix_{:}'.format(it)) sim.add_custom('unfix tether_fix_{:}'.format(it)) else: sim.add_md(lmps.MolecularDynamics(name='main_fix', group=nonrig_group_name if rigid_mols else 'all', ensemble='npt', timestep=mdp.get('timestep'), temperature=mdp.get('temp'), pressure=mdp.get('pressure'), run=False, extra_keywords={'dilate': 'all'} if rigid_mols else {})) # create the second NVT fix for rigid molecules that cannot be put in NPT fix if rigid_mols: sim.add(lmps.MolecularDynamics(name='rig_fix', ensemble='rigid/nvt/small molecule', timestep=mdp.get('timestep'), length=mdp.get('length'), group=rig_group_name, temperature=mdp.get('temp'), pressure=mdp.get('pressure'), run=False)) # add the "spring tether" fix to the geometrical center of the system to avoid system creep sim.add_custom('fix tether_fix matrix spring tether 30.0 0.0 0.0 0.0 0.0') sim.add(lmps.OutputSettings(thermo=mdp.get('thermo'), dump={'filename': os.path.join(sim_folder, str(l) + '.md.dump'), 'freq': int(mdp.get('dump'))})) sim.add_custom('run {:}\n'.format(mdp.get('length'))) # The input for correct simulations is set, starting LAMMPS: sim.run(prefix=['']) os.environ['OMP_NUM_THREADS'] = nm_treads # Updating the size of the fixed system from the MD simulations and saving the coordinates for the next MC # css.system.dim = sim.system.dim css.system = sim.system.copy() css.unwrap_gas() css.system.write_xyz(xyz_fname.format(l)) mcp['Start_Type']['file_name'] = xyz_fname.format(l) mcp['Start_Type']['species'] = [1] + css.run_queue[-1].mc_sst.made_ins l += 1 return sim.system if sim else None
def md(s, template=None, **kwargs): """pysimm.lmps.md Convenience function for performing LAMMPS MD *** WILL BE DEPRECATED - USE QUICK_MD INSTEAD *** """ global LAMMPS_EXEC if template: template.update(kwargs) kwargs = template name = kwargs.get('name') or False log = kwargs.get('log') write = kwargs.get('write') or False print_to_screen = kwargs.get('print_to_screen') if kwargs.get( 'print_to_screen') is not None else False special_bonds = kwargs.get('special_bonds') or 'amber' cutoff = kwargs.get('cutoff') or 12.0 timestep = kwargs.get('timestep') or 1 ensemble = kwargs.get('ensemble') or 'nvt' temp = kwargs.get('temp') pressure = kwargs.get('pressure') or 1. new_v = kwargs.get('new_v') seed = kwargs.get('seed') or randint(10000, 99999) scale_v = kwargs.get('scale_v') length = kwargs.get('length') or 2000 thermo = kwargs.get('thermo') or 1000 thermo_style = kwargs.get('thermo_style') nonbond_mixing = kwargs.get('nonbond_mixing') kspace_style = kwargs.get('kspace_style') or 'pppm 1e-4' nanohub = kwargs.get('nanohub') or {} pbs = kwargs.get('pbs') np = kwargs.get('np') kokkos = kwargs.get('kokkos') dump = kwargs.get('dump') or False dump_name = kwargs.get('dump_name') dump_append = kwargs.get('dump_append') if temp is None: t_start = kwargs.get('t_start') t_stop = kwargs.get('t_stop') if t_start is None: t_start = 1000. if t_stop is None: t_stop = t_start else: t_start = temp t_stop = temp command = write_init(s, nb_cut=cutoff, special_bonds=special_bonds, nonbond_mixing=nonbond_mixing, kspace_style=kspace_style) if log: command += 'log %s append\n' % log elif name: command += 'log %s.log append\n' % '_'.join(name.split()) else: command += 'log log.lammps append\n' if thermo: command += 'thermo %s\n' % int(thermo) if thermo_style: command += 'thermo_style %s\n' % thermo_style command += 'timestep %s\n' % timestep if ensemble == 'nvt': command += 'fix 1 all %s temp %s %s 100\n' % (ensemble, t_start, t_stop) elif ensemble == 'npt': command += ('fix 1 all %s temp %s %s 100 iso %s %s 100\n' % (ensemble, t_start, t_stop, pressure, pressure)) if new_v: command += 'velocity all create %s %s\n' % (t_start, seed) elif scale_v: command += 'velocity all scale %s\n' % t_start if dump: if dump_name: command += ('dump pysimm_dump all atom %s %s.lammpstrj\n' % (dump, dump_name)) elif name: command += ('dump pysimm_dump all atom %s %s.lammpstrj\n' % (dump, '_'.join(name.split()))) else: command += ('dump pysimm_dump all atom %s pysimm_dump.lammpstrj\n' % dump) if dump_append: command += 'dump_modify pysimm_dump append yes\n' command += 'run %s\n' % length command += 'unfix 1\n' if write: command += 'write_data %s\n' % write else: command += 'write_data pysimm_md.lmps\n' with open('temp.in', 'w') as f: f.write(command) if name: print('%s: starting %s simulation using LAMMPS' % (strftime('%H:%M:%S'), name)) else: print('%s: starting molecular dynamics using LAMMPS' % strftime('%H:%M:%S')) if nanohub: if name: print('%s: sending %s simulation to computer cluster' % (strftime('%H:%M:%S'), name)) sys.stdout.flush() cmd = ('submit -n %s -w %s -i temp.lmps -i temp.in ' 'lammps-09Dec14-parallel -e both -l none -i temp.in' % (nanohub.get('cores'), nanohub.get('walltime'))) cmd = shlex.split(cmd) exit_status, stdo, stde = RapptureExec(cmd) elif pbs: call('mpiexec %s -e both -l log' % LAMMPS_EXEC, shell=True, stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) else: if np: p = Popen(['mpiexec', '-np', str(np), LAMMPS_EXEC, '-e', 'both', '-l', 'none'], stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) elif kokkos: p = Popen([LAMMPS_EXEC, '-k', 'on', '-sf', 'kk', '-e', 'both', '-l', 'none'], stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) else: p = Popen([LAMMPS_EXEC, '-e', 'both', '-l', 'none'], stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) while True: out = p.stdout.read(1) if out == '' and p.poll() is not None: break if out != '' and print_to_screen: sys.stdout.write(out) sys.stdout.flush() if write: n = read_lammps(write, quiet=True, pair_style=s.pair_style, bond_style=s.bond_style, angle_style=s.angle_style, dihedral_style=s.dihedral_style, improper_style=s.improper_style) else: n = read_lammps('pysimm_md.lmps', quiet=True, pair_style=s.pair_style, bond_style=s.bond_style, angle_style=s.angle_style, dihedral_style=s.dihedral_style, improper_style=s.improper_style) for p in n.particles: p_ = s.particles[p.tag] p_.x = p.x p_.y = p.y p_.z = p.z p_.vx = p.vx p_.vy = p.vy p_.vz = p.vz s.dim = n.dim os.remove('temp.in') try: os.remove('temp.lmps') except OSError as e: print e if not write: try: os.remove('pysimm_md.lmps') if name: print('%s: %s simulation using LAMMPS successful' % (strftime('%H:%M:%S'), name)) else: print('%s: molecular dynamics using LAMMPS successful' % (strftime('%H:%M:%S'))) return True except OSError: if name: print('%s: %s simulation using LAMMPS UNsuccessful' % (strftime('%H:%M:%S'), name)) else: print('%s: molecular dynamics using LAMMPS UNsuccessful' % strftime('%H:%M:%S')) return False else: if os.path.isfile(write): if name: print('%s: %s simulation using LAMMPS successful' % (strftime('%H:%M:%S'), name)) else: print('%s: molecular dynamics using LAMMPS successful' % (strftime('%H:%M:%S'))) return True else: if name: print('%s: %s simulation using LAMMPS UNsuccessful' % (strftime('%H:%M:%S'), name)) else: print('%s: molecular dynamics using LAMMPS UNsuccessful' % strftime('%H:%M:%S')) return False
def minimize(s, template=None, **kwargs): """pysimm.lmps.minimize Convenience function for performing LAMMPS energy minimization *** WILL BE DEPRECATED - USE QUICK_MIN INSTEAD *** """ global LAMMPS_EXEC if template: template.update(kwargs) kwargs = template name = kwargs.get('name') or False log = kwargs.get('log') or 'log.lammps' write = kwargs.get('write') or False print_to_screen = kwargs.get('print_to_screen') if kwargs.get( 'print_to_screen') is not None else False special_bonds = kwargs.get('special_bonds') or 'amber' cutoff = kwargs.get('cutoff') or 12.0 min_style = kwargs.get('min_style') fire_etol = kwargs.get('sd_etol') or 1.0e-3 fire_ftol = kwargs.get('sd_ftol') or 1.0e-3 fire_maxiter = kwargs.get('sd_maxiter') or 10000 fire_maxeval = kwargs.get('sd_maxeval') or 100000 sd_etol = kwargs.get('sd_etol') or 1.0e-3 sd_ftol = kwargs.get('sd_ftol') or 1.0e-3 sd_maxiter = kwargs.get('sd_maxiter') or 10000 sd_maxeval = kwargs.get('sd_maxeval') or 100000 cg_etol = kwargs.get('cg_etol') or 1.0e-6 cg_ftol = kwargs.get('cg_ftol') or 1.0e-6 cg_maxiter = kwargs.get('cg_maxiter') or 10000 cg_maxeval = kwargs.get('cg_maxeval') or 100000 thermo = kwargs.get('thermo') or 1000 thermo_style = kwargs.get('thermo_style') nonbond_mixing = kwargs.get('nonbond_mixing') kspace_style = kwargs.get('kspace_style') or 'pppm 1e-4' nanohub = kwargs.get('nanohub') or {} pbs = kwargs.get('pbs') np = kwargs.get('np') command = write_init(s, nb_cut=cutoff, special_bonds=special_bonds, nonbond_mixing=nonbond_mixing, kspace_style=kspace_style) if log: command += 'log %s append\n' % log elif name: command += 'log %s.log append\n' % '_'.join(name.split()) else: command += 'log log.lammps append\n' if thermo: command += 'thermo %s\n' % int(thermo) if thermo_style: command += 'thermo_style %s\n' % thermo_style if not min_style or min_style == 'sd': command += 'min_style sd\n' command += ('minimize %s %s %s %s\n' % (sd_etol, sd_ftol, sd_maxiter, sd_maxeval)) command += 'min_style cg\n' command += ('minimize %s %s %s %s\n' % (cg_etol, cg_ftol, cg_maxiter, cg_maxeval)) elif min_style == 'fire': command += 'timestep 1\n' command += 'min_style fire\n' command += ('minimize %s %s %s %s\n' % (fire_etol, fire_ftol, fire_maxiter, fire_maxeval)) if write: command += 'write_data %s\n' % write else: command += 'write_data pysimm_min.lmps\n' with open('temp.in', 'w') as f: f.write(command) if name: print('%s: starting %s simulation using LAMMPS' % (strftime('%H:%M:%S'), name)) else: print('%s: starting minimization using LAMMPS' % strftime('%H:%M:%S')) if nanohub: if name: print('%s: sending %s simulation to computer cluster' % (strftime('%H:%M:%S'), name)) sys.stdout.flush() cmd = ('submit -n %s -w %s -i temp.lmps -i temp.in ' 'lammps-09Dec14-parallel -e both -l none -i temp.in' % (nanohub.get('cores'), nanohub.get('walltime'))) cmd = shlex.split(cmd) exit_status, stdo, stde = RapptureExec(cmd) if pbs: call('mpiexec %s -e both -l log' % LAMMPS_EXEC, shell=True, stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) else: if np: p = Popen(['mpiexec', '-np', str(np), LAMMPS_EXEC, '-e', 'both', '-l', 'none'], stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) else: p = Popen([LAMMPS_EXEC, '-e', 'both', '-l', 'none'], stdin=open('temp.in'), stdout=PIPE, stderr=PIPE) while True: out = p.stdout.read(1) if out == '' and p.poll() is not None: break if out != '' and print_to_screen: sys.stdout.write(out) sys.stdout.flush() if write: n = read_lammps(write, quiet=True, pair_style=s.pair_style, bond_style=s.bond_style, angle_style=s.angle_style, dihedral_style=s.dihedral_style, improper_style=s.improper_style) else: n = read_lammps('pysimm_min.lmps', quiet=True, pair_style=s.pair_style, bond_style=s.bond_style, angle_style=s.angle_style, dihedral_style=s.dihedral_style, improper_style=s.improper_style) for p in n.particles: s.particles[p.tag].x = p.x s.particles[p.tag].y = p.y s.particles[p.tag].z = p.z os.remove('temp.in') try: os.remove('temp.lmps') except OSError as e: print e if not write: try: os.remove('pysimm_min.lmps') if name: print('%s: %s simulation using LAMMPS successful' % (strftime('%H:%M:%S'), name)) else: print('%s: minimization using LAMMPS successful' % (strftime('%H:%M:%S'))) return True except OSError: if name: print('%s: %s simulation using LAMMPS UNsuccessful' % (strftime('%H:%M:%S'), name)) else: print('%s: minimization using LAMMPS UNsuccessful' % strftime('%H:%M:%S')) return False else: if os.path.isfile(write): if name: print('%s: %s simulation using LAMMPS successful' % (strftime('%H:%M:%S'), name)) else: print('%s: minimization using LAMMPS successful' % (strftime('%H:%M:%S'))) return True else: if name: print('%s: %s simulation using LAMMPS UNsuccessful' % (strftime('%H:%M:%S'), name)) else: print('%s: minimization using LAMMPS UNsuccessful' % strftime('%H:%M:%S')) return False
p_ = new.particles[tail_tags[1]] new.rotate(around=p, rot_matrix=my_rotation( np.array([p.x, p.y, p.z]) - np.array([p_.x, p_.y, p_.z]), -np.pi / 2)) return ordr lmps.FF_SETTINGS['trappe/amber']['dihedral_style'] = 'harmonic' lmps.FF_SETTINGS['trappe/amber']['special_bonds'] = 'amber' # Importing initial monomer system mono = system.read_lammps('pim_unit.lmps', pair_style='lj/cut', bond_style='harmonic', angle_style='harmonic', dihedral_style='harmonic') mono.zero_charge() mono.forcefield = 'trappe/amber' # Decorating monomer with linker-type atoms ptitles = [pt.name for pt in mono.particle_types] tails = [24, 26] for t in tails: mono.particles[t].linker = 'tail' mono.particles[t].type = mono.particle_types[ ptitles.index(mono.particles[t].type.name[1:]) + 1] heads = [28, 29] for t in heads:
def mc_md(gas_sst, fixed_sst=None, **kwargs): """pysimm.apps.mc_md Performs the iterative hybrid Monte-Carlo/Molecular Dynamics (MC-MD) simulations using pysimm.lmps for MD and pysimm.cassandra for MD Args: gas_sst: list of pysimm.system.System objects each of which describes a different molecule to be inserted by MC fixed_sst: fixed during th MC steps group of atoms (default: None) mcmd_niter: number of MC-MD iteradions (default: 10) sim_folder: relative path to the folder with all simulation files (default: 'results') mc_props: dictionary describing all MC properties needed for simulations (see pysimm.cassandra.GCMC and pysimm.cassandra.GCMC.props for details) md_props: dictionary containing all Molecular Dynamics settings needed for simulations (see pysimm.lmps.Simulation and pysimm.lmps.MolecularDynamics for details) """ nonrig_group_name = 'nonrigid_b' rig_group_name = 'rigid_b' n_iter = kwargs.get('mcmd_niter') or 10 sim_folder = kwargs.get('sim_folder') or 'results' xyz_fname = os.path.join(sim_folder, 'MD{:}_out.xyz') l = 1 # Creating fixed polymer system fs = None if fixed_sst: if isinstance(fixed_sst, str): fs = system.read_lammps(fixed_sst) fs.wrap() elif isinstance(fixed_sst, system.System): fs = fixed_sst fs.wrap() else: print('Cannot setup the fixed system for the simulations. Skipping this') # Set the one-molecule gas systems gases = [] for g in cassandra.make_iterable(gas_sst): if isinstance(g, str): try: gases.append(system.read_lammps(g)) except IOError: print('Cannot read file: {}\nExiting...'.format(g)) exit(1) if isinstance(g, system.System): gases.append(g) if not gases: print('There are no gas molecules were specified correctely\nThe gas molecules are needed to start the ' 'MC-MD simulations\nExiting...') exit(1) css = cassandra.Cassandra(fixed_sst) # Set the Monte-Carlo properties: mcp = kwargs.get('mc_props') if mcp: CHEM_POT = cassandra.make_iterable(mcp.get('Chemical_Potential_Info')) if not CHEM_POT: print('Missing chemical potential info\nExiting...') exit(1) else: print('Missing the MC Simulation settings\nExiting...') exit(1) mcp['Start_Type'] = OrderedDict([('species', [1] + [0] * len(CHEM_POT))]) # Set the Molecular-Dynamics properties: mdp = kwargs.get('md_props') if not mdp: print('Missing the MD Simulation settings\nExiting...') exit(1) while l < n_iter + 1: mcp['Run_Name'] = str(l) + '.gcmc' css.add_gcmc(species=gases, is_new=True, chem_pot=CHEM_POT, is_rigid=mcp.get('rigid_type') or [False] * len(gases), out_folder=sim_folder, props_file=str(l) + '.gcmc_props.inp', **mcp) css.run() # >>> 2N: MD (LAMMPS) step: sim_sst = css.final_sst sim_sst.write_lammps(os.path.join(sim_folder, str(l) + '.before_md.lmps')) sim = lmps.Simulation(sim_sst, log=os.path.join(sim_folder, str(l) + '.md.log'), print_to_screen=mdp.get('print_to_screen'), cutoff=mdp.get('cutoff')) # custom definitions for the neighbour list updates sim.add_custom('neighbor 1.0 nsq \nneigh_modify once no every 1 delay 0 check yes') # adding group definitions to separate rigid and non-rigid bodies grp_tmpl = 'group {:} id {:}' sim.add_custom(grp_tmpl.format('matrix', css.run_queue[0].group_by_id('matrix')[0])) sim.add_custom(grp_tmpl.format(nonrig_group_name, css.run_queue[0].group_by_id('nonrigid')[0])) rigid_mols = css.run_queue[0].group_by_id('rigid')[0] if rigid_mols: sim.add_custom(grp_tmpl.format(rig_group_name, rigid_mols)) # create the description of the molecular dynamics simulation tmp_md = lmps.MolecularDynamics(ensemble=mdp.get('ensemble'), timestep=mdp.get('timestep'), length=int(mdp.get('length')), thermo=mdp.get('thermo'), temp=mdp.get('temp'), pressure=mdp.get('pressure'), dump=int(mdp.get('dump')), dump_name=os.path.join(sim_folder, str(l) + '.md.dump'), scale_v=True) # obtain the simulation (LAMMPS) input in order to customly modify it later tmp_md.write(sim) # replace single default fix with two separate fixes for rigid and nonrigid bodies separately old_line = re.search('(?<=(\nfix)).*', tmp_md.input).group(0) corr_fix = re.sub('all', nonrig_group_name, old_line) if rigid_mols: corr_fix += ' dilate all\n' else: corr_fix += '\n' if rigid_mols: corr_fix += 'fix' + re.sub('iso\s+\d+[.\d]*\s+\d+[.\d]*\s+\d+[.\d]*', '', old_line).\ replace('1', '2', 1). \ replace('all', rig_group_name). \ replace('npt', 'rigid/nvt/small molecule') + '\n' # adding the spring fix to the geometrical center of the system to avoid system creep corr_fix += 'fix {:} {:} spring tether {:} {:} {:} {:} {:}\n'.format(3, 'matrix', 30.0, 0.0, 0.0, 0.0, 0.0) # saving all fixes to the input tmp_md.input = tmp_md.input.replace(old_line, corr_fix) # adding "run 0" line for correct temperature scaling of the system with rigid molecules tmp_md.input = tmp_md.input.replace('velocity all scale', 'velocity all create {:} {:}\nrun 0\nvelocity all scale' .format(mdp.get('temp'), random.randint(int(1e+5), int(1e+6) - 1))) # The input for correct simulations is set, starting LAMMPS: sim.add_custom(tmp_md.input) sim.run(np=1) # Updating the size of the fixed system from the MD simulations and saving the coordinates for the next MC css.init_sst.dim = sim.system.dim sim.system.write_xyz(xyz_fname.format(l)) mcp['Start_Type']['file_name'] = xyz_fname.format(l) mcp['Start_Type']['species'] = [1] + [0] * len(CHEM_POT) l += 1 return sim.system