Esempio n. 1
0
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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
 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
Esempio n. 6
0
 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
Esempio n. 7
0
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")
Esempio n. 8
0

# 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)
Esempio n. 9
0
def write_lammps_table_jelle(ff):
    from yaff import NeighborList, PairPotEI, Switch3, ForcePartPair, Scalings,\
        PairPotMM3
    nffa = ff.system.ffatypes.shape[0]
    numbers = []
    for i in xrange(nffa):
        index0 = np.where(ff.system.ffatype_ids == i)[0][0]
        if np.sum(ff.system.ffatype_ids == i) > 1:
            index1 = np.where(ff.system.ffatype_ids == i)[0][1]
            numbers.append([index0, index1])
        for j in xrange(i + 1, nffa):
            index1 = np.where(ff.system.ffatype_ids == j)[0][0]
            numbers.append([index0, index1])
    part_names = [part.name for part in ff.parts]
    print part_names
    ftab = open('lammps_smoothei2.table', 'w')
    ftab.write("# LAMMPS tabulated potential generated by Yaff\n")
    ftab.write("# All quantities in atomic units\n")
    ftab.write(
        "# The names of the tables refer to the ffatypes that have to be used in the Yaff system\n"
    )
    ftab.write("#%4s %13s %21s %21s\n" % ("i", "d", "V", "F"))

    for number in numbers:
        pos = np.zeros((2, 3))
        pos[1, 2] = 1.0
        smallsys = System(system.numbers[number],
                          pos,
                          charges=system.charges[number],
                          radii=system.radii[number])
        smallsys_noradii = System(system.numbers[number],
                                  pos,
                                  charges=system.charges[number])
        idx_ei = -1
        idx_mm3 = -1
        for idx, part in enumerate(ff.parts):
            if part.name == 'pair_ei': idx_ei = idx
            elif part.name == 'pair_mm3': idx_mm3 = idx
        tr = ff.parts[idx_ei].pair_pot.get_truncation()
        rcut = ff.parts[idx_ei].pair_pot.rcut
        alpha = ff.parts[idx_ei].pair_pot.alpha
        nlist = NeighborList(smallsys)
        pair_pot = PairPotEI(smallsys.charges,
                             alpha,
                             rcut,
                             tr=Switch3(tr.width),
                             radii=smallsys.radii)
        #        pair_pot = PairPotEI(smallsys.charges, 0.0, rcut, tr=None, radii=smallsys.radii)
        scalings = Scalings(smallsys, scale1=1.0, scale2=1.0, scale3=1.0)
        part0 = ForcePartPair(smallsys, nlist, scalings, pair_pot)
        ff0 = ForceField(smallsys, [part0], nlist)
        ff0.compute()

        nlist1 = NeighborList(smallsys_noradii)
        #        pair_pot = PairPotEI(smallsys_noradii.charges, alpha, rcut, tr=Switch3(tr.width))
        pair_pot = PairPotEI(smallsys_noradii.charges, alpha, rcut, tr=None)
        scalings = Scalings(smallsys_noradii,
                            scale1=1.0,
                            scale2=1.0,
                            scale3=1.0)
        part1 = ForcePartPair(smallsys_noradii, nlist1, scalings, pair_pot)
        ff1 = ForceField(smallsys_noradii, [part1], nlist1)
        ff1.compute()

        tr = ff.parts[idx_mm3].pair_pot.get_truncation()
        rcut = ff.parts[idx_mm3].pair_pot.rcut
        nlist2 = NeighborList(smallsys)
        pair_pot = PairPotMM3(ff.parts[idx_mm3].pair_pot.sigmas[number],
                              ff.parts[idx_mm3].pair_pot.epsilons[number],
                              ff.parts[idx_mm3].pair_pot.onlypaulis[number],
                              rcut, Switch3(tr.width))
        scalings = Scalings(smallsys, scale1=1.0, scale2=1.0, scale3=1.0)
        part2 = ForcePartPair(smallsys, nlist, scalings, pair_pot)
        ff2 = ForceField(smallsys, [part2], nlist)
        ff2.nlist.nneigh = 1
        ff2.compute()

        distances = np.linspace(0.5 * angstrom, rcut, 5000)
        energies = []
        toplot = []
        for d in distances:
            gposnn0 = np.zeros(ff0.system.pos.shape, float)
            ff0.nlist.neighs[0] = (0, 1, d, 0.0, 0.0, d, 0, 0, 0)
            energy0 = ff0.compute(gpos=gposnn0)
            gposnn1 = np.zeros(ff1.system.pos.shape, float)
            ff1.nlist.neighs[0] = (0, 1, d, 0.0, 0.0, d, 0, 0, 0)
            energy1 = ff1.compute(gpos=gposnn1)
            gposnn2 = np.zeros(ff2.system.pos.shape, float)
            ff2.nlist.neighs[0] = (0, 1, d, 0.0, 0.0, d, 0, 0, 0)
            energy2 = ff2.compute(gpos=gposnn2)
            toplot.append([d, energy0, energy1, energy2])
            row = [
                d, energy0 - energy1 + energy2,
                gposnn0[0, 2] - gposnn1[0, 2] + gposnn2[0, 2]
            ]
            #            row = [d, energy2, gposnn2[0,2]]
            energies.append(row)
        energies = np.asarray(energies)
        toplot = np.asarray(toplot)

        ffa0 = ff.system.ffatypes[ff.system.ffatype_ids[number[0]]]
        ffa1 = ff.system.ffatypes[ff.system.ffatype_ids[number[1]]]
        if ffa0 > ffa1:
            name = '%s-%s' % (ffa0, ffa1)
        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
Esempio n. 10
0
        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
Esempio n. 12
0
# 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,
Esempio n. 13
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()
Esempio n. 14
0
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()
Esempio n. 15
0
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
Esempio n. 16
0
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