def test_CAU13_xylene(): host = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/CAU_13.chk')) guest = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/xylene.chk')) pars_fn = pkg_resources.resource_filename(__name__, '../../data/test/parameters_CAU-13_xylene.txt') complex = host.merge(guest) for tailcorrections in False, True: # Construct force fields ff_complex = ForceField.generate(complex, pars_fn, tailcorrections=tailcorrections) ff_host = ForceField.generate(host, pars_fn, tailcorrections=tailcorrections) ff_exclude = ForceField.generate(complex, pars_fn, nlow=host.natom, tailcorrections=tailcorrections) # The nlow keyword is meant to exclude all pair interactions when both # atomic indices are smaller than nlow # The energy of this force field should be exactly equal to the energy of # the entire complex (featuring framework-framework, framework-guest, and # guest-guest interactions) minus the energy of the framework (featuring # only framework-framework interactions). Note that this is not what is # usually considered an interaction energy, because for instance guest-guest # valence interactions are still included. e_complex = ff_complex.compute() e_host = ff_host.compute() e_exclude = ff_exclude.compute() # Compare energies part by part nparts = len(ff_complex.parts) assert len(ff_host.parts)==nparts assert len(ff_exclude.parts)==nparts for ipart in range(nparts): eref = ff_complex.parts[ipart].energy - ff_host.parts[ipart].energy ecomp = ff_exclude.parts[ipart].energy print("%20s %15.9f %15.9f"% (ff_exclude.parts[ipart].name, eref, ecomp)) assert np.abs(eref-ecomp)<1e-10
def get_data(self, system, ff_file, rcut): pos = system.pos rvecs = system.cell.rvecs ff = ForceField.generate(system, ff_file, rcut=rcut) self.lj = False self.mm3 = False self.ei = False for part in ff.parts: if ('pair_mm3' in part.name or part.name == 'pair_lj'): sigmas = part.pair_pot.sigmas epsilons = part.pair_pot.epsilons if ('pair_mm3' in part.name): self.mm3 = True else: self.lj = True if (part.name == 'pair_ei'): charges = part.pair_pot.charges radii = part.pair_pot.radii self.ei = True if not self.mm3 and not self.lj: print('No vdW loaded') sigmas = np.zeros(len(pos)) epsilons = np.zeros(len(pos)) if not self.ei: print('No EI loaded') charges = np.zeros(len(pos)) radii = np.zeros(len(pos)) return sigmas, epsilons, charges, radii
def __init__(self, latency=1.0, name="", threaded=False, yaffpara=None, yaffsys=None, yafflog='yaff.log', rcut=18.89726133921252, alpha_scale=3.5, gcut_scale=1.1, skin=0, smooth_ei=False, reci_ei='ewald', pars=None, dopbc=False): """Initialises FFYaff and enables a basic Yaff force field. Args: yaffpara: File name of the Yaff parameter file yaffsys: File name of the Yaff system file yafflog: File name to which Yaff will write some information about the system and the force field pars: Optional dictionary, giving the parameters needed by the driver. **kwargs: All keyword arguments that can be provided when generating a Yaff force field; see constructor of FFArgs in Yaff code """ from yaff import System, ForceField, log import codecs import locale import atexit # a socket to the communication library is created or linked super(FFYaff, self).__init__(latency, name, pars, dopbc, threaded=threaded) # A bit weird to use keyword argument for a required argument, but this # is also done in the code above. if yaffpara is None: raise ValueError("Must provide a Yaff parameter file.") if yaffsys is None: raise ValueError("Must provide a Yaff system file.") self.yaffpara = yaffpara self.yaffsys = yaffsys self.rcut = rcut self.alpha_scale = alpha_scale self.gcut_scale = gcut_scale self.skin = skin self.smooth_ei = smooth_ei self.reci_ei = reci_ei self.yafflog = yafflog # Open log file logf = open(yafflog, 'w') # Tell Python to close the file when the script exits atexit.register(logf.close) # Redirect Yaff log to file log._file = codecs.getwriter(locale.getpreferredencoding())(logf) self.system = System.from_file(self.yaffsys) self.ff = ForceField.generate(self.system, self.yaffpara, rcut=self.rcut, alpha_scale=self.alpha_scale, gcut_scale=self.gcut_scale, skin=self.skin, smooth_ei=self.smooth_ei, reci_ei=self.reci_ei) log._active = False
def __init__(self, latency=1.0, name="", yaffpara=None, yaffsys=None, yafflog='yaff.log', rcut=18.89726133921252, alpha_scale=3.5, gcut_scale=1.1, skin=0, smooth_ei=False, reci_ei='ewald', pars=None, dopbc=False, threaded=True): """Initialises FFYaff and enables a basic Yaff force field. Args: yaffpara: File name of the Yaff parameter file yaffsys: File name of the Yaff system file yafflog: File name to which Yaff will write some information about the system and the force field pars: Optional dictionary, giving the parameters needed by the driver. **kwargs: All keyword arguments that can be provided when generating a Yaff force field; see constructor of FFArgs in Yaff code """ from yaff import System, ForceField, log import codecs import locale import atexit # a socket to the communication library is created or linked super(FFYaff, self).__init__(latency, name, pars, dopbc) # A bit weird to use keyword argument for a required argument, but this # is also done in the code above. if yaffpara is None: raise ValueError("Must provide a Yaff parameter file.") if yaffsys is None: raise ValueError("Must provide a Yaff system file.") self.yaffpara = yaffpara self.yaffsys = yaffsys self.rcut = rcut self.alpha_scale = alpha_scale self.gcut_scale = gcut_scale self.skin = skin self.smooth_ei = smooth_ei self.reci_ei = reci_ei self.yafflog = yafflog # Open log file logf = open(yafflog, 'w') # Tell Python to close the file when the script exits atexit.register(logf.close) # Redirect Yaff log to file log._file = codecs.getwriter(locale.getpreferredencoding())(logf) self.system = System.from_file(self.yaffsys) self.ff = ForceField.generate(self.system, self.yaffpara, rcut=self.rcut, alpha_scale=self.alpha_scale, gcut_scale=self.gcut_scale, skin=self.skin, smooth_ei=self.smooth_ei, reci_ei=self.reci_ei) log._active = False
def get_yaff_ff(self, rcut=15*angstrom, alpha_scale=3.2, gcut_scale=1.5, smooth_ei=True): system = self.get_yaff_system() fn_pars = posixpath.join(self.working_directory, self.input['fn_yaff']) if not os.path.isfile(fn_pars): raise IOError('No pars.txt file find in job working directory. Have you already run the job?') ff = ForceField.generate( system, fn_pars, rcut=rcut, alpha_scale=alpha_scale, gcut_scale=gcut_scale, smooth_ei=smooth_ei ) return ff
def get_yaff_ff(self, system=None): if system is None: system = self.get_yaff_system() fn_pars = posixpath.join(self.working_directory, 'pars.txt') if not os.path.isfile(fn_pars): raise IOError('No pars.txt file find in job working directory. Have you already run the job?') ff = ForceField.generate( system, fn_pars, rcut=self.input['rcut'], alpha_scale=self.input['alpha_scale'], gcut_scale=self.input['gcut_scale'], smooth_ei=self.input['smooth_ei'] ) return ff
def main(): rcut = 15.0 * angstrom for nx, ny, nz in [(1, 1, 1), (1, 2, 1), (2, 2, 1), (2, 2, 2), (2, 3, 2), (3, 3, 2), (3, 3, 3), (3, 4, 3), (4, 4, 3), (4, 4, 4)][:]: # Generate supercell system system = System.from_file('system.chk').supercell(nx, ny, nz) dn = 'lammps_%s' % ('.'.join("%d" % n for n in [nx, ny, nz])) if not os.path.isdir(dn): os.makedirs(dn) # Tabulate vdW interactions if not os.path.isfile('lammps.table'): ff = ForceField.generate(system, ['pars.txt'], rcut=rcut) write_lammps_table(ff, fn='lammps.table', rmin=0.50 * angstrom, nrows=2500, unit_style='real') # Write the LAMMPS input files ff2lammps(system, 'pars.txt', dn, rcut=15.0 * angstrom, tailcorrections=False, tabulated=True, unit_style='real') # Adapt the sampling options, which are defined in the last 5 lines # of lammps.in with open(os.path.join(dn, 'lammps.in'), 'r') as f: lines = f.readlines() with open(os.path.join(dn, 'lammps.in'), 'w') as f: for line in lines[:-5]: f.write(line) f.write("timestep 1.0 # in time units\n") f.write( "velocity all create 600.0 5 # initial temperature in Kelvin and random seed\n" ) f.write("fix 1 all nvt temp 300.0 300.0 100.0\n") f.write( "fix_modify 1 energy yes # Add thermo/barostat contributions to energy\n" ) f.write("run 100\n")
# Setup MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() # Set random seed, important to get the same velocities for all processes np.random.seed(5) # Turn off logging for all processes, it can be turned on for one selected process later on log.set_level(log.silent) if rank==0: log.set_level(log.medium) if __name__=='__main__': f_res = h5py.File('restart_8.h5', mode='r') system = System.from_hdf5(f_res) ff = ForceField.generate(system, 'pars.txt', rcut=15*angstrom, alpha_scale=3.2, gcut_scale=1.5, smooth_ei=True) # Replace non-covalent part with LAMMPS for part in ff.parts: if part.name=='valence': part_valence = part elif part.name=='pair_ei': part_ei = part # Write LAMMPS system file write_lammps_data(system) nlist = BondedNeighborList(system) pair_pot = PairPotEI(system.charges, 0.0, part_ei.pair_pot.rcut, tr=Switch3(part_ei.pair_pot.get_truncation().width), radii=system.radii) scalings = Scalings(system, scale1=1.0, scale2=1.0, scale3=0.0) pair_gauss = ForcePartPair(system,nlist,scalings,pair_pot) pair_lammps = ForcePartLammps(system, pppm_accuracy=1e-6,fn_table='lammps_smoothei2.table', comm=comm, scalings=[0.0,0.0,1.0,0.0,0.0,1.0],fn_log='none') ff = ForceField(system,[part_valence,pair_lammps,pair_gauss],nlist)
else: name = '%s-%s' % (ffa1, ffa0) ftab.write("%s\nN %d R %f %f\n\n" % (name, energies.shape[0], distances[0], distances[-1])) for irow, row in enumerate(energies): ftab.write("%05d %+13.8f %+21.12f %+21.12f\n" % (irow + 1, row[0], row[1], row[2])) print name #break if __name__ == '__main__': sys = System.from_file('init.chk') system = sys.supercell(1, 2, 1) log.set_level(log.silent) fns = [] for fn in os.listdir(os.getcwd()): if fn.startswith('pars') and fn.endswith('.txt'): fns.append(fn) ff = ForceField.generate(system, fns, rcut=15.0 * angstrom, alpha_scale=3.2, gcut_scale=1.5, smooth_ei=True) log.set_level(log.low) write_lammps_data(system) write_lammps_table_jelle(ff)
def test_exclusion(): def random_rotation(pos): com = np.average(pos, axis=0) pos -= com while True: V1 = np.random.rand() V2 = np.random.rand() S = V1**2 + V2**2 if S < 1: break theta = np.array([ 2 * np.pi * (2 * V1 * np.sqrt(1 - S) - 0.5), 2 * np.pi * (2 * V2 * np.sqrt(1 - S) - 0.5), np.pi * ((1 - 2 * S) / 2) ]) R_x = np.array([[1, 0, 0], [0, np.cos(theta[0]), -np.sin(theta[0])], [0, np.sin(theta[0]), np.cos(theta[0])]]) R_y = np.array([[np.cos(theta[1]), 0, np.sin(theta[1])], [0, 1, 0], [-np.sin(theta[1]), 0, np.cos(theta[1])]]) R_z = np.array([[np.cos(theta[2]), -np.sin(theta[2]), 0], [np.sin(theta[2]), np.cos(theta[2]), 0], [0, 0, 1]]) R = np.dot(R_z, np.dot(R_y, R_x)) pos_new = np.zeros((len(pos), len(pos[0]))) for i, p in enumerate(pos): pos_new[i] = np.dot(R, np.array(p).T) return pos_new + com def get_adsorbate_pos(adsorbate, rvecs): pos = adsorbate.pos pos = random_rotation(pos) pos -= np.average(pos, axis=0) new_com = np.random.rand() * rvecs[0] + np.random.rand( ) * rvecs[1] + np.random.rand() * rvecs[2] return pos + new_com # Empty framework system = System.from_file( pkg_resources.resource_filename(__name__, '../../data/test/CAU_13.chk')) N_system = len(system.pos) ff_file = pkg_resources.resource_filename( __name__, '../../data/test/parameters_CAU-13_xylene.txt') ff = ForceField.generate(system, ff_file) ff.nlist.update() E_parts = {part.name: part.compute() for part in ff.parts} ff_new = ForceField.generate(system, ff_file, exclude_frame=True, n_frame=N_system) ff_new.nlist.update() E_parts_new = {part.name: part.compute() for part in ff_new.parts} # Add 4 adsorbates adsorbate = System.from_file( pkg_resources.resource_filename(__name__, '../../data/test/xylene.chk')) pos = system.pos ffatypes = np.append(system.ffatypes, adsorbate.ffatypes) bonds = system.bonds numbers = system.numbers ffatype_ids = system.ffatype_ids charges = system.charges masses = system.masses for i in range(4): pos = np.append(pos, get_adsorbate_pos(adsorbate, system.cell.rvecs), axis=0) bonds = np.append(bonds, adsorbate.bonds + N_system + len(adsorbate.pos) * i, axis=0) numbers = np.append(numbers, adsorbate.numbers, axis=0) ffatype_ids = np.append(ffatype_ids, adsorbate.ffatype_ids + max(system.ffatype_ids) + 1, axis=0) charges = np.append(charges, adsorbate.charges, axis=0) masses = np.append(masses, adsorbate.masses, axis=0) # Framework with 4 adsorbates system = System(numbers, pos, ffatypes=ffatypes, ffatype_ids=ffatype_ids, bonds=bonds,\ rvecs = system.cell.rvecs, charges=charges, masses=masses) ff = ForceField.generate(system, ff_file) ff_new = ForceField.generate(system, ff_file, exclude_frame=True, n_frame=N_system) # Test 100 random configurations for i in range(100): new_pos = ff.system.pos for i in range(4): new_pos[N_system + i * len(adsorbate.pos):N_system + (i + 1) * len(adsorbate.pos)] = get_adsorbate_pos( adsorbate, system.cell.rvecs) ff.update_pos(new_pos) ff_new.update_pos(new_pos) ff.nlist.update() ff_new.nlist.update() E_parts_rand = {part.name: part.compute() for part in ff.parts} E_parts_new_rand = {part.name: part.compute() for part in ff_new.parts} for key, _ in E_parts.items(): assert (E_parts[key] - E_parts_rand[key]) - ( E_parts_new[key] - E_parts_new_rand[key]) < 10e-12
# opt.run(500) # system.to_file('opt%d.chk' % p) # # print(system.cell.volume/angstrom**3, ff.part_press.pext/p_unit, ff.energy/e_unit) pressures = np.linspace(-1000, 2000, 31, endpoint=True) print(pressures) results = np.zeros((len(pressures), 12), dtype=np.float32) for i, p in enumerate(pressures): system = System.from_file(chk_file) ff = ForceField.generate(system, ff_file, rcut=20 * angstrom, alpha_scale=4.0, gcut_scale=2.0, smooth_ei=True, reci_ei='ewald') ff.add_part(ForcePartPressure(system, p * p_unit)) opt = CGOptimizer(StrainCellDOF(ff, gpos_rms=1e-6, grvecs_rms=1e-6)) opt.run(2000) system.to_file('results/opt%d.chk' % p) system.to_file('results/opt%d.xyz' % p) print(p, system.cell.rvecs) results[i, :] = [ system.cell.volume / angstrom**3, ff.part_press.pext / p_unit,
def run_GCMC(self, N_iterations, N_sample): A = Acceptance() if rank == 0: if not (os.path.isdir('results')): try: os.mkdir('results') except:pass if self.write_traj: ftraj = open('results/traj_%.8f.xyz'%(self.P/bar), 'w') e = 0 t_it = time() N_samples = [] E_samples = [] pressures = [] traj = [] q0s = [] if rank == 0: print('\n Iteration inst. N inst. E inst. V time [s]') print('--------------------------------------------------------') for iteration in range(N_iterations+1): if self.ads_ei: sfac_init = deepcopy(self.sfac) pos_init = deepcopy(self.pos) rvecs_init = deepcopy(self.rvecs) rvecs_flat_init = deepcopy(self.rvecs_flat) V_init = self.V e_el_real_init = self.e_el_real e_vdw_init = self.e_vdw switch = np.random.rand() acc = 0 # Insertion / deletion if(switch < self.prob[0] and not self.Z_ads == self.fixed_N): if(switch < self.prob[0]/2): new_pos = random_ads(self.pos_ads, self.rvecs) e_new = self.insertion(new_pos) exp_value = self.beta * (-e_new + e) if(exp_value > 100): acc = 1 elif(exp_value < -100): acc = 0 else: acc = min(1, self.V*self.beta*self.fugacity/self.Z_ads * np.exp(exp_value)) # Reject monte carlo move if np.random.rand() > acc: self.pos = pos_init if self.ads_ei: self.sfac = sfac_init self.e_el_real = e_el_real_init self.e_vdw = e_vdw_init self.Z_ads -= 1 else: e = e_new elif(self.Z_ads > 0): deleted_coord, e_new = self.deletion() exp_value = -self.beta * (e_new - e) if(exp_value > 100): acc = 1 else: acc = min(1, (self.Z_ads+1)/self.V/self.beta/self.fugacity * np.exp(exp_value)) # Reject monte carlo move if np.random.rand() > acc: self.pos = pos_init if self.ads_ei: self.sfac = sfac_init self.e_el_real = e_el_real_init self.e_vdw = e_vdw_init self.Z_ads += 1 else: e = e_new elif(switch < self.prob[1]): if self.Z_ads != 0: trial = np.random.randint(self.Z_ads) if((switch < self.prob[0] + (self.prob[1]-self.prob[0])/2) or self.nads == 1): # Calculate translation energy as deletion + insertion of molecule deleted_coord, e_new = self.deletion() deleted_coord += self.step * (np.random.rand(3) - 0.5) e_new = self.insertion(deleted_coord) else: # Calculate rotation energy as deletion + insertion of molecule deleted_coord, e_new = self.deletion() deleted_coord = random_rot(deleted_coord, circlefrac=0.1) e_new = self.insertion(deleted_coord) exp_value = -self.beta * (e_new - e) if(exp_value > 0): exp_value = 0 acc = min(1, np.exp(exp_value)) # Reject monte carlo move if np.random.rand() > acc: self.pos = pos_init if self.ads_ei: self.sfac = sfac_init self.e_el_real = e_el_real_init self.e_vdw = e_vdw_init else: e = e_new else: # Construct system and forcefield class for the MD engine from yaff import System, ForceField, XYZWriter, VerletScreenLog, MTKBarostat, \ NHCThermostat, TBCombination, VerletIntegrator, HDF5Writer, log log.set_level(0) n = np.append(self.data.numbers_MOF, np.tile(self.data.numbers_ads, self.Z_ads)) ffa_MOF = self.data.system.ffatypes[self.data.system.ffatype_ids] ffa_ads = self.data.system_ads.ffatypes[self.data.system_ads.ffatype_ids] ffa = np.append(ffa_MOF, np.tile(ffa_ads, self.Z_ads)) assert len(self.pos) == len(ffa) s = System(n, self.pos, ffatypes = ffa, rvecs=self.rvecs) s.detect_bonds() ff = ForceField.generate(s, self.ff_file, rcut=self.rcut, alpha_scale=self.alpha_scale, gcut_scale=self.gcut_scale, tailcorrections=True) ff_lammps = swap_noncovalent_lammps(ff, fn_system='system_%.8f.dat'%(self.P/bar), fn_table='table.dat', nrows=5000, kspace='pppm', kspace_accuracy=1e-7, scalings_ei = [1.0, 1.0, 1.0], move_central_cell=False, fn_log="none", overwrite_table=False, comm=comm) # Setup and NPT MD run if rank == 0: vsl = VerletScreenLog(step=50) if self.write_h5s: if self.fixed_N: hdf5_writer = HDF5Writer(h5.File('results/temp_%d.h5'%self.fixed_N, mode='w'), step=101) else: hdf5_writer = HDF5Writer(h5.File('results/temp_%.8f.h5'%(self.P/bar), mode='w'), step=101) ensemble_hook = NHCThermostat(temp=self.T, timecon=100*femtosecond, chainlength=3) if self.barostat: mtk = MTKBarostat(ff_lammps, temp=self.T, press=self.P, \ timecon=1000*femtosecond, vol_constraint = self.vol_constraint, anisotropic = True) ensemble_hook = TBCombination(ensemble_hook, mtk) if self.meta: cv = CVVolume(ff_lammps.system) sigma = 1000*angstrom**3 K = 20*kjmol step = 498 # Run MD t = time() if self.write_h5s: if rank == 0: verlet = VerletIntegrator(ff_lammps, self.timestep, hooks=[ensemble_hook, vsl, hdf5_writer], temp0=self.T) else: verlet = VerletIntegrator(ff_lammps, self.timestep, hooks=[ensemble_hook], temp0=self.T) else: if rank == 0: hooks = [ensemble_hook, vsl] if self.meta: meta = MTDHook(ff_lammps, cv, sigma, K, start=step, step=step) for q0 in q0s: meta.hills.add_hill(q0, K) hooks.append(meta) verlet = VerletIntegrator(ff_lammps, self.timestep, hooks=hooks, temp0=self.T) else: hooks = [ensemble_hook] if self.meta: meta = MTDHook(ff_lammps, cv, sigma, K, start=step, step=step) for q0 in q0s: meta.hills.add_hill(q0, K) hooks.append(meta) verlet = VerletIntegrator(ff_lammps, self.timestep, hooks=hooks, temp0=self.T) e0_tot = verlet._compute_ekin() + ff_lammps.compute() verlet.run(600) ef_tot = verlet._compute_ekin() + ff_lammps.compute() if not self.vol_constraint: Vn = np.linalg.det(ff_lammps.system.cell.rvecs) exp_value = -self.beta * (ef_tot - e0_tot + self.P * (Vn - self.V) - len(self.pos)/self.beta * np.log(Vn/self.V)) else: exp_value = -self.beta * (ef_tot - e0_tot) if(exp_value > 0): exp_value = 0 acc = min(1, np.exp(exp_value)) # Accept monte carlo move if np.random.rand() < acc: if self.write_h5s: # Append MD data to previous data self.append_h5() # Rebuild data for MC pos_total = ff_lammps.system.pos self.pos = pos_total[:self.N_frame] pos_molecules = pos_total[self.N_frame:] self.rvecs = ff_lammps.system.cell.rvecs self.rvecs_flat = self.rvecs.reshape(9) self.V = np.linalg.det(self.rvecs) if self.meta: q0s.append(self.V) if self.ads_ei: self.sfac = Sfac(self.pos, self.N_frame, self.rvecs_flat, \ self.charges, self.alpha, self.gcut) self.e_el_real = 0 self.e_vdw = 0 if self.Z_ads > 0: for p in np.split(pos_molecules, self.Z_ads): e_new = self.insertion(p) self.Z_ads -= 1 e = e_new else: e = 0 else: self.pos = pos_init self.rvecs = rvecs_init self.rvecs_flat = rvecs_flat_init self.V = V_init if rank == 0: log.set_level(log.medium) if(iteration % N_sample == 0 and iteration > 0): eprint = e if np.abs(eprint) < 1e-10: eprint = 0 if rank == 0: print(' {:7.7} {:7.7} {:7.7} {:7.7} {:7.4}'.format( str(iteration),str(self.Z_ads),str(eprint/kjmol),str(self.V/angstrom**3),time()-t_it) ) t_it = time() N_samples.append(self.Z_ads) E_samples.append(e) if self.Z_ads == self.fixed_N: traj.append(self.pos) if rank == 0 and self.write_traj: natom = self.N_frame + self.nads * self.Z_ads rv = self.rvecs_flat/angstrom ffa_MOF = self.data.system.ffatypes[self.data.system.ffatype_ids] ffa_ads = self.data.system_ads.ffatypes[self.data.system_ads.ffatype_ids] ffa = np.append(ffa_MOF, np.tile(ffa_ads, self.Z_ads)) ftraj.write('%d\n%f %f %f %f %f %f %f %f %f\n'%(natom, rv[0], rv[1], rv[2], rv[3], rv[4], rv[5], rv[6], rv[7], rv[8])) for s, p in zip(ffa, self.pos/angstrom): ftraj.write('%s %f %f %f\n'%(s, p[0], p[1], p[2])) if rank == 0: print('Average N: %.3f'%np.average(N_samples)) if self.fixed_N: np.save('results/N_%d.npy'%self.fixed_N, np.array(N_samples)) np.save('results/E_%d.npy'%self.fixed_N, np.array(E_samples)) else: np.save('results/N_%.8f.npy'%(self.P/bar), np.array(N_samples)) np.save('results/E_%.8f.npy'%(self.P/bar), np.array(E_samples)) if self.fixed_N: from yaff import System n = np.append(self.data.numbers_MOF, np.tile(self.data.numbers_ads, self.Z_ads)) s = System(n, self.pos, rvecs=self.rvecs) s.to_file('results/end_%d.xyz'%self.fixed_N) mol = Molecule.from_file('results/end_%d.xyz'%self.fixed_N) symbols = mol.symbols self.write_traj(traj, symbols) os.remove('results/end_%d.xyz'%self.fixed_N) if self.write_traj: ftraj.close()
def main(): options, fns = parse() #define logger if options.silent: log.set_level('silent') else: if options.very_verbose: log.set_level('highest') elif options.verbose: log.set_level('high') if options.logfile is not None and isinstance(options.logfile, str): log.write_to_file(options.logfile) with log.section('QFF', 1, timer='Initializing'): log.dump('Initializing system') #read system and ab initio reference system = None energy = 0.0 grad = None hess = None rvecs = None for fn in fns: if fn.endswith('.fchk') or fn.endswith('.xml'): numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio( fn) if system is None: system = System(numbers, coords, rvecs=rvecs, charges=None, radii=None, masses=masses) else: system.pos = coords.copy() system.cell = Cell(rvecs) system.numbers = numbers.copy() if masses is not None: system.masses = masses.copy() system._init_derived() elif fn.endswith('.chk'): sample = load_chk(fn) if 'energy' in sample.keys(): energy = sample['energy'] if 'grad' in sample.keys(): grad = sample['grad'] elif 'gradient' in sample.keys(): grad = sample['gradient'] if 'hess' in sample.keys(): hess = sample['hess'] elif 'hessian' in sample.keys(): hess = sample['hessian'] if system is None: system = System.from_file(fn) else: if 'pos' in sample.keys(): system.pos = sample['pos'] elif 'coords' in sample.keys(): system.pos = sample['coords'] if 'rvecs' in sample.keys(): system.cell = Cell(sample['rvecs']) elif 'cell' in sample.keys(): system.cell = Cell(sample['cell']) if 'bonds' in sample.keys(): system.bonds = sample['bonds'] if 'ffatypes' in sample.keys(): system.ffatypes = sample['ffatypes'] if 'ffatype_ids' in sample.keys(): system.ffatype_ids = sample['ffatype_ids'] system._init_derived() else: raise NotImplementedError('File format for %s not supported' % fn) assert system is not None, 'No system could be defined from input' assert grad is not None, 'No ab initio gradient found in input' assert hess is not None, 'No ab initio hessian found in input' #complete the system information if system.bonds is None: system.detect_bonds() if system.masses is None: system.set_standard_masses() if system.ffatypes is None: if options.ffatypes in ['low', 'medium', 'high', 'highest']: guess_ffatypes(system, options.ffatypes) elif options.ffatypes is not None: raise NotImplementedError( 'Guessing atom types from %s not implemented' % options.ffatypes) else: raise AssertionError('No atom types defined') #construct ab initio reference ai = SecondOrderTaylor('ai', coords=system.pos.copy(), energy=energy, grad=grad, hess=hess, pbc=pbc) #detect a priori defined contributions to the force field refs = [] if options.ei is not None: if rvecs is None: ff = ForceField.generate(system, options.ei, rcut=50 * angstrom) else: ff = ForceField.generate(system, options.ei, rcut=20 * angstrom, alpha_scale=3.2, gcut_scale=1.5, smooth_ei=True) refs.append(YaffForceField('EI', ff)) if options.vdw is not None: ff = ForceField.generate(system, options.vdw, rcut=20 * angstrom) refs.append(YaffForceField('vdW', ff)) if options.covres is not None: ff = ForceField.generate(system, options.covres) refs.append(YaffForceField('Cov res', ff)) #define quickff program assert options.program_mode in allowed_programs, \ 'Given program mode %s not allowed. Choose one of %s' %( options.program_mode, ', '.join([prog for prog in allowed_programs if not prog=='BaseProgram']) ) mode = program_modes[options.program_mode] only_traj = 'PT_ALL' if options.only_traj is not None: only_traj = options.only_traj.split(',') program = mode(system, ai, ffrefs=refs, fn_traj=options.fn_traj, only_traj=only_traj, plot_traj=options.ener_traj, xyz_traj=options.xyz_traj, suffix=options.suffix) #run program program.run()
def qff(args=None): if args is None: args = qff_parse_args() else: args = qff_parse_args(args) #define logger verbosity = None if args.silent: verbosity = 'silent' else: if args.very_verbose: verbosity = 'highest' elif args.verbose: verbosity = 'high' #get settings kwargs = { 'fn_traj': args.fn_traj, 'only_traj': args.only_traj, 'program_mode': args.program_mode, 'plot_traj': args.plot_traj, 'xyz_traj': args.xyz_traj, 'suffix': args.suffix, 'log_level': verbosity, 'log_file': args.logfile, 'ffatypes': args.ffatypes, 'ei': args.ei, 'ei_rcut': args.ei_rcut, 'vdw': args.vdw, 'vdw_rcut': args.vdw_rcut, 'covres': args.covres, } settings = Settings(fn=args.config_file, **kwargs) with log.section('INIT', 1, timer='Initializing'): log.dump('Initializing system') #read system and ab initio reference system = None energy = 0.0 grad = None hess = None pbc = None rvecs = None for fn in args.fn: if fn.endswith('.fchk') or fn.endswith('.xml'): numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio( fn) if system is None: system = System(numbers, coords, rvecs=rvecs, charges=None, radii=None, masses=masses) else: system.pos = coords.copy() system.cell = Cell(rvecs) system.numbers = numbers.copy() if masses is not None: system.masses = masses.copy() system._init_derived() elif fn.endswith('.chk'): sample = load_chk(fn) if 'energy' in list(sample.keys()): energy = sample['energy'] if 'grad' in list(sample.keys()): grad = sample['grad'] elif 'gradient' in list(sample.keys()): grad = sample['gradient'] if 'hess' in list(sample.keys()): hess = sample['hess'] elif 'hessian' in list(sample.keys()): hess = sample['hessian'] if 'rvecs' in list(sample.keys()): pbc = [1, 1, 1] else: pbc = [0, 0, 0] if system is None: system = System.from_file(fn) else: if 'pos' in list(sample.keys()): system.pos = sample['pos'] elif 'coords' in list(sample.keys()): system.pos = sample['coords'] if 'rvecs' in list(sample.keys()): system.cell = Cell(sample['rvecs']) elif 'cell' in list(sample.keys()): system.cell = Cell(sample['cell']) if 'bonds' in list(sample.keys()): system.bonds = sample['bonds'] if 'ffatypes' in list(sample.keys()): system.ffatypes = sample['ffatypes'] if 'ffatype_ids' in list(sample.keys()): system.ffatype_ids = sample['ffatype_ids'] system._init_derived() else: raise NotImplementedError('File format for %s not supported' % fn) assert system is not None, 'No system could be defined from input' assert grad is not None, 'No ab initio gradient found in input' assert hess is not None, 'No ab initio hessian found in input' #complete the system information if system.bonds is None: system.detect_bonds() if system.masses is None: system.set_standard_masses() if system.ffatypes is None: if settings.ffatypes is not None: set_ffatypes(system, settings.ffatypes) else: raise AssertionError('No atom types defined') if settings.do_hess_negfreq_proj: log.dump( 'Projecting negative frequencies out of the mass-weighted hessian.' ) with log.section('SYS', 3, 'Initializing'): hess = project_negative_freqs(hess, system.masses) #construct ab initio reference ai = SecondOrderTaylor('ai', coords=system.pos.copy(), energy=energy, grad=grad, hess=hess, pbc=pbc) #detect a priori defined contributions to the force field refs = [] if settings.ei is not None: if rvecs is None: if settings.ei_rcut is None: rcut = 50 * angstrom else: rcut = settings.ei_rcut ff = ForceField.generate(system, settings.ei, rcut=rcut) else: if settings.ei_rcut is None: rcut = 20 * angstrom else: rcut = settings.ei_rcut ff = ForceField.generate(system, settings.ei, rcut=rcut, alpha_scale=3.2, gcut_scale=1.5, smooth_ei=True) refs.append(YaffForceField('EI', ff)) if settings.vdw is not None: ff = ForceField.generate(system, settings.vdw, rcut=settings.vdw_rcut) refs.append(YaffForceField('vdW', ff)) if settings.covres is not None: ff = ForceField.generate(system, settings.covres) refs.append(YaffForceField('Cov res', ff)) #define quickff program assert settings.program_mode in allowed_programs, \ 'Given program mode %s not allowed. Choose one of %s' %( settings.program_mode, ', '.join([prog for prog in allowed_programs if not prog=='BaseProgram']) ) mode = program_modes[settings.program_mode] program = mode(system, ai, settings, ffrefs=refs) #run program program.run() return program
def test_exclusion(): def random_rotation(pos): com = np.average(pos, axis=0) pos -= com while True: V1 = np.random.rand(); V2 = np.random.rand(); S = V1**2 + V2**2; if S < 1: break; theta = np.array([2*np.pi*(2*V1*np.sqrt(1-S)-0.5), 2*np.pi*(2*V2*np.sqrt(1-S)-0.5), np.pi*((1-2*S)/2)]) R_x = np.array([[1, 0, 0],[0, np.cos(theta[0]), -np.sin(theta[0])],[0, np.sin(theta[0]), np.cos(theta[0])]]) R_y = np.array([[np.cos(theta[1]), 0, np.sin(theta[1])],[0, 1, 0],[-np.sin(theta[1]), 0, np.cos(theta[1])]]) R_z = np.array([[np.cos(theta[2]), -np.sin(theta[2]),0],[np.sin(theta[2]), np.cos(theta[2]),0],[0, 0, 1]]) R = np.dot(R_z, np.dot( R_y, R_x )) pos_new = np.zeros((len(pos), len(pos[0]))) for i, p in enumerate(pos): pos_new[i] = np.dot(R, np.array(p).T) return pos_new + com def get_adsorbate_pos(adsorbate, rvecs): pos = adsorbate.pos pos = random_rotation(pos) pos -= np.average(pos, axis=0) new_com = np.random.rand()*rvecs[0] + np.random.rand()*rvecs[1] + np.random.rand()*rvecs[2] return pos + new_com # Empty framework system = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/CAU_13.chk')) N_system = len(system.pos) ff_file = pkg_resources.resource_filename(__name__, '../../data/test/parameters_CAU-13_xylene.txt') ff = ForceField.generate(system, ff_file) ff.nlist.update() E_parts = {part.name:part.compute() for part in ff.parts} ff_new = ForceField.generate(system, ff_file, exclude_frame=True, n_frame=N_system) ff_new.nlist.update() E_parts_new = {part.name:part.compute() for part in ff_new.parts} # Add 4 adsorbates adsorbate = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/xylene.chk')) pos = system.pos ffatypes = np.append(system.ffatypes, adsorbate.ffatypes) bonds = system.bonds numbers = system.numbers ffatype_ids = system.ffatype_ids charges = system.charges masses = system.masses for i in range(4): pos = np.append(pos, get_adsorbate_pos(adsorbate,system.cell.rvecs), axis=0) bonds = np.append(bonds, adsorbate.bonds + N_system + len(adsorbate.pos) * i,axis=0) numbers = np.append(numbers, adsorbate.numbers, axis=0) ffatype_ids = np.append(ffatype_ids, adsorbate.ffatype_ids + max(system.ffatype_ids) + 1, axis=0) charges = np.append(charges, adsorbate.charges, axis=0) masses = np.append(masses, adsorbate.masses, axis=0) # Framework with 4 adsorbates system = System(numbers, pos, ffatypes=ffatypes, ffatype_ids=ffatype_ids, bonds=bonds,\ rvecs = system.cell.rvecs, charges=charges, masses=masses) ff = ForceField.generate(system, ff_file) ff_new = ForceField.generate(system, ff_file, exclude_frame=True, n_frame=N_system) # Test 100 random configurations for i in range(100): new_pos = ff.system.pos for i in range(4): new_pos[N_system+i*len(adsorbate.pos):N_system+(i+1)*len(adsorbate.pos)] = get_adsorbate_pos(adsorbate,system.cell.rvecs) ff.update_pos(new_pos) ff_new.update_pos(new_pos) ff.nlist.update() ff_new.nlist.update() E_parts_rand = {part.name:part.compute() for part in ff.parts} E_parts_new_rand = {part.name:part.compute() for part in ff_new.parts} for key, _ in E_parts.items(): assert (E_parts[key]-E_parts_rand[key]) - (E_parts_new[key]-E_parts_new_rand[key]) < 10e-12