Пример #1
0
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'))
Пример #2
0
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)
Пример #3
0
    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()