def write_chk(input_dict,working_directory='.'): # collect data and initialize Yaff system if 'cell' in input_dict.keys() and input_dict['cell'] is not None: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes'], ffatype_ids=input_dict['ffatype_ids'], rvecs=input_dict['cell']*angstrom) else: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes'], ffatype_ids=input_dict['ffatype_ids']) # determine masses, bonds and ffaypes from ffatype_rules system.detect_bonds() system.set_standard_masses() # write dictionary to MolMod CHK file system.to_file(posixpath.join(working_directory,'system.chk'))
def write_chk(input_dict, working_directory='.'): # collect data and initialize Yaff system if 'cell' in input_dict.keys() and input_dict['cell'] is not None: system = System(input_dict['numbers'], input_dict['pos']*angstrom, rvecs=input_dict['cell']*angstrom, ffatypes=input_dict['ffatypes_man'], ffatype_ids=input_dict['ffatype_ids_man']) else: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes_man'], ffatype_ids=input_dict['ffatype_ids_man']) # determine masses, bonds and ffaypes from ffatype_rules system.detect_bonds() system.set_standard_masses() # write dictionnairy to MolMod CHK file system.to_file(posixpath.join(working_directory,'input.chk')) # Reload input.chk as dictionairy and add AI input data d = load_chk(posixpath.join(working_directory,'input.chk')) assert isinstance(input_dict['aiener'], float), "AI energy not defined in input, use job.read_abintio(...)" assert isinstance(input_dict['aigrad'], np.ndarray), "AI gradient not defined in input, use job.read_abintio(...)" assert isinstance(input_dict['aihess'], np.ndarray), "AI hessian not defined in input, use job.read_abintio(...)" d['energy'] = input_dict['aiener'] d['grad'] = input_dict['aigrad'] d['hess'] = input_dict['aihess'] dump_chk(posixpath.join(working_directory,'input.chk'), d)
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()