Пример #1
0
 def get_yaff_system(self, snapshot=0):
     numbers = np.array([
         pt[symbol].number
         for symbol in self.structure.get_chemical_symbols()
     ])
     if snapshot == 0:
         struct = self.structure
     else:
         struct = self.get_structure(iteration_step=snapshot,
                                     wrap_atoms=False)
     pos = struct.positions.reshape(-1, 3) * angstrom
     cell = struct.cell
     if cell is None:
         system = System(numbers,
                         pos,
                         ffatypes=self.ffatypes,
                         ffatype_ids=self.ffatype_ids)
     else:
         system = System(numbers,
                         pos,
                         rvecs=cell * angstrom,
                         ffatypes=self.ffatypes,
                         ffatype_ids=self.ffatype_ids)
     system.detect_bonds()
     system.set_standard_masses()
     return system
Пример #2
0
    def detect_ffatypes(self, ffatypes=None, ffatype_rules=None, ffatype_level=None):
        '''
            Define atom types by explicitely giving them through the
            ffatypes keyword, defining atype rules using the ATSELECT
            language implemented in Yaff (see the Yaff documentation at
            http://molmod.github.io/yaff/ug_atselect.html) or by specifying
            the ffatype_level employing the built-in routine in QuickFF.
        '''
        numbers = np.array([pt[symbol].number for symbol in self.structure.get_chemical_symbols()])
        if self.structure.cell is None:
            system = System(numbers, self.structure.positions.copy()*angstrom)
        else:
            system = System(numbers, self.structure.positions.copy()*angstrom, rvecs=self.structure.cell*angstrom)
        system.detect_bonds()

        if not sum([ffatypes is None, ffatype_rules is None, ffatype_level is None]) == 2:
            raise IOError('Exactly one of ffatypes, ffatype_rules and ffatype_level should be defined')

        if ffatypes is not None:
            assert ffatype_rules is None, 'ffatypes and ffatype_rules cannot be defined both'
            system.ffatypes = ffatypes
            system.ffatype_ids = None
            system._init_derived_ffatypes()
        if ffatype_rules is not None:
            system.detect_ffatypes(ffatype_rules)
        if ffatype_level is not None:
            set_ffatypes(system, ffatype_level)

        self.ffatypes = system.ffatypes.copy()
        self.ffatype_ids = system.ffatype_ids.copy()
Пример #3
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'))
Пример #4
0
    def __init__(self, system, rules=None, cases=None):
        self.system = system
        self.cases = cases

        # Compile the rules if they are present
        if cases is None:
            if rules is None:
                rules = ['!0'] * self.natom
            compiled_rules = []
            for rule in rules:
                if isinstance(rule, str):
                    rule = atsel_compile(rule)
                compiled_rules.append(rule)
            self.rules = compiled_rules
            self.cases = list(self._iter_cases())
        elif rules is not None:
            raise ValueError(
                'Either rules are cases must be provided, not both.')

        # Construct a fake system, a dlist and an iclist for just one ic
        self.fake_system = System(numbers=np.zeros(self.natom, int),
                                  pos=np.zeros((self.natom, 3), float),
                                  rvecs=self.system.cell.rvecs)
        self.dlist = DeltaList(self.fake_system)
        self.iclist = InternalCoordinateList(self.dlist)
        self.tangent = np.zeros((self.natom, 3), float)
Пример #5
0
def test_uio66zrbrick_crossterms():
    with log.section('NOSETEST', 2):
        # Load input data for a ficticious system of an isolated
        # UiO-66 brick
        with path('quickff.data.systems.uio66-zr-brick', 'system.chk') as fn:
            data = load_chk(fn)
        system = System(data['numbers'],data['pos'],charges=data['charges'],
            ffatypes=data['ffatypes'],bonds=data['bonds'],radii=data['radii'])
        system.set_standard_masses()
        ai = SecondOrderTaylor('ai', coords=system.pos.copy(),
             grad=data['gradient'], hess=data['hessian'])
        # Run QuickFF
        with tmpdir('test_uio66') as dn:
            fn_yaff = os.path.join(dn, 'pars_cov.txt')
            fn_sys = os.path.join(dn, 'system.chk')
            fn_log = os.path.join(dn, 'quickff.log')
            program = DeriveFF(system, ai, Settings(consistent_cross_rvs=True,
                remove_dysfunctional_cross=True,fn_yaff=fn_yaff,fn_sys=fn_sys,log_file=fn_log))
            program.run()
        # Check force constants of cross terms and corresponding diagonal terms
        print("%50s %15s %15s"%("Basename","Cross FC","Diag FC"))
        for term in program.valence.terms:
            if not term.is_master(): continue
            if term.basename.startswith('Cross'):
                fc = program.valence.get_params(term.index, only='fc')
                for i in [0,1]:
                    fc_diag = program.valence.get_params(term.diag_term_indexes[i], only='fc')
                    print("%50s %15.6f %15.6f %50s" % (term.basename,fc,fc_diag,program.valence.terms[term.diag_term_indexes[i]].basename))
                    if fc_diag==0.0: assert fc==0.0
Пример #6
0
def test_detect_bonds_cyclopropene_exceptions():
    system = get_system_cyclopropene()
    # create system without bonds
    system = System(system.numbers, system.pos)
    # Add bonds between all hydrogen and carbon atoms (unrealistic but useful for testing)
    system.detect_bonds({(1, 6): 8.0 * angstrom})
    assert system.nbond == 3 + 4 * 3
Пример #7
0
def test_detect_bonds_water_exceptions():
    system = get_system_water32()
    # create system without bonds
    system = System(system.numbers, system.pos)
    # Add bonds between hydrogen atoms (unrealistic but useful for testing)
    system.detect_bonds({(1, 1): 2.0 * angstrom})
    assert system.nbond >= 96
Пример #8
0
def read_system(name):
    # Load system data
    dn = 'quickff.data.systems'
    if '/' in name:
        words = name.split('/')
        dn += '.%s' % ('.'.join(words[:-1]))
        name = words[-1]
    with path(dn, name) as fn:
        numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio(
            fn)
        fns_wpart = glob(os.path.join(os.path.dirname(fn), 'gaussian_mbis.h5'))
    # Try to load charges.
    charges = None
    if len(fns_wpart) > 0:
        with h5.File(fns_wpart[0], 'r') as f:
            charges = f['charges'][:]
    # Create system object.
    system = System(numbers, coords, charges=charges)
    system.detect_bonds()
    system.set_standard_masses()
    # Load ab initio data.
    ai = SecondOrderTaylor('ai',
                           coords=system.pos.copy(),
                           energy=energy,
                           grad=grad,
                           hess=hess,
                           pbc=pbc)
    return system, ai
Пример #9
0
def load_system_cube(fn):
    '''Load system from fn in cube format'''
    # TODO: this should be moved into Yaff/MolMod
    print 'Loading atomic structure from CUBE file.'
    with open(fn) as f:
        # Skip two header lines.
        f.next()
        f.next()
        # Read number of atoms.
        natom = int(f.next().split()[0])
        assert natom > 0
        # Read real-space vectors
        rvecs = np.zeros((3, 3), float)
        for irow in xrange(3):
            words = f.next().split()
            nrep = int(words[0])
            rvecs[irow, 0] = nrep * float(words[1])
            rvecs[irow, 1] = nrep * float(words[2])
            rvecs[irow, 2] = nrep * float(words[3])
        print 'Treating system as periodic with the following cell vectors'
        print 'in Angstrom. (Cell vectors are displayed as rows.)'
        print rvecs / angstrom
        # Read atomic numbers and coordinates
        numbers = np.zeros(natom, int)
        coordinates = np.zeros((natom, 3), float)
        for iatom in xrange(natom):
            words = f.next().split()
            numbers[iatom] = int(words[0])
            coordinates[iatom, 0] = float(words[2])
            coordinates[iatom, 1] = float(words[3])
            coordinates[iatom, 2] = float(words[4])
    print
    return System(numbers=numbers, pos=coordinates, rvecs=rvecs)
Пример #10
0
def test_detect_bonds_glycine():
    system = get_system_glycine()
    check_detect_bonds(system)
    system = System(system.numbers, system.pos)
    system.detect_bonds()
    assert hasattr(system, 'neighs1')
    assert hasattr(system, 'neighs2')
    assert hasattr(system, 'neighs3')
Пример #11
0
def read_system(name):
    fn = context.get_fn('systems/%s' %name)
    numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio(fn)
    system = System(numbers, coords)
    system.detect_bonds()
    system.set_standard_masses()
    ai = SecondOrderTaylor('ai', coords=system.pos.copy(), energy=energy, grad=grad, hess=hess, pbc=pbc)
    return system, ai
Пример #12
0
def test_iter_matches_single_atom():
    system = System.from_file(context.get_fn('test/rhodium_complex_nobornane.xyz'))
    system.detect_bonds()
    system_ref = System(pos=np.zeros((1, 3), float), numbers = np.array([45]))
    system_ref.detect_bonds()
    selected = set(system.iter_matches(system_ref).next())
    reference = set([28])
    np.testing.assert_equal(selected, reference)
Пример #13
0
def test_supercell_nobonds():
    cellpar = 2.867 * angstrom
    sys111 = System(
        numbers=np.array([26, 26]),
        pos=np.array([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]) * cellpar,
        ffatypes=['Fe', 'Fe'],
        rvecs=np.identity(3) * cellpar,
    )
    sys333 = sys111.supercell(3, 3, 3)
Пример #14
0
def test_iter_matches_single_atom():
    system = System.from_file(
        pkg_resources.resource_filename(
            __name__, '../data/test/rhodium_complex_nobornane.xyz'))
    system.detect_bonds()
    system_ref = System(pos=np.zeros((1, 3), float), numbers=np.array([45]))
    system_ref.detect_bonds()
    selected = set(next(system.iter_matches(system_ref)))
    reference = set([28])
    np.testing.assert_equal(selected, reference)
Пример #15
0
def test_scopes2():
    system = System(numbers=np.array([8, 1, 1, 6, 1, 1, 1, 8, 1]),
                    pos=np.zeros((9, 3), float),
                    scopes=['WAT', 'METH'],
                    scope_ids=np.array([0, 0, 0, 1, 1, 1, 1, 1, 1]),
                    ffatypes=['O', 'H', 'C', 'H_C', 'O', 'H_O'],
                    ffatype_ids=np.array([0, 1, 1, 2, 3, 3, 3, 4, 5]))
    assert (system.scopes == ['WAT', 'METH']).all()
    assert (system.scope_ids == np.array([0, 0, 0, 1, 1, 1, 1, 1, 1])).all()
    assert (system.ffatypes == ['O', 'H', 'C', 'H_C', 'O', 'H_O']).all()
    assert (system.ffatype_ids == np.array([0, 1, 1, 2, 3, 3, 3, 4, 5])).all()
Пример #16
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)
Пример #17
0
def test_supercell_charges():
    cellpar = 2.867 * angstrom
    sys111 = System(
        numbers=np.array([26, 26]),
        pos=np.array([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]) * cellpar,
        ffatypes=['Fe', 'Fe'],
        charges=np.array([0.1, 1.0]),
        radii=np.array([0.0, 2.0]),
        rvecs=np.identity(3) * cellpar,
    )
    sys333 = sys111.supercell(3, 3, 3)
    assert (sys333.charges == np.tile(np.array([0.1, 1.0]), 27)).all()
    assert (sys333.radii == np.tile(np.array([0.0, 2.0]), 27)).all()
Пример #18
0
def test_scopes3():
    system = System(numbers=np.array([8, 1, 1, 6, 1, 1, 1, 8, 1]),
                    pos=np.zeros((9, 3), float),
                    scopes=['WAT', 'METH'],
                    scope_ids=np.array([0, 0, 0, 1, 1, 1, 1, 1, 1]),
                    ffatypes=['O', 'H', 'C', 'H_C', 'H_O'],
                    ffatype_ids=np.array([0, 1, 1, 2, 3, 3, 3, 0, 4]))
    assert (system.scopes == ['WAT', 'METH']).all()
    assert (system.scope_ids == np.array([0, 0, 0, 1, 1, 1, 1, 1, 1])).all()
    assert (system.ffatypes == ['O', 'H', 'C', 'H_C', 'H_O', 'O']).all()
    assert (system.ffatype_ids == np.array([0, 1, 1, 2, 3, 3, 3, 5, 4])).all()
    assert system.get_scope(0) == 'WAT'
    assert system.get_scope(3) == 'METH'
    assert system.get_ffatype(0) == 'O'
    assert system.get_ffatype(7) == 'O'
    assert system.get_ffatype(8) == 'H_O'
Пример #19
0
def read_system(name):
    # Load system data.
    fn = context.get_fn(os.path.join('systems', name))
    numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio(fn)
    # Try to load charges.
    charges = None
    fns_wpart = glob(os.path.join(os.path.dirname(fn), 'gaussian_mbis.h5'))
    if len(fns_wpart) > 0:
        with h5.File(fns_wpart[0], 'r') as f:
            charges = f['charges'][:]
    # Create system object.
    system = System(numbers, coords, charges=charges)
    system.detect_bonds()
    system.set_standard_masses()
    # Load ab initio data.
    ai = SecondOrderTaylor('ai', coords=system.pos.copy(), energy=energy, grad=grad, hess=hess, pbc=pbc)
    return system, ai
Пример #20
0
def test_remove_duplicate_dipoles():
    cellpar = 2.867 * angstrom
    system1 = System(
        numbers=np.array([26, 27]),
        pos=np.array([[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]) * cellpar,
        ffatypes=['A', 'B'],
        dipoles=np.array([[0.1, 1.0, 2.0], [0.5, 0.7, 0.9]]),
        radii2=np.array([0.0, 2.0]),
        rvecs=np.identity(3) * cellpar,
    )
    system2 = system1.supercell(1, 2, 1)
    system2.cell = system1.cell
    system3 = system2.remove_duplicate()
    for j, number in enumerate([26, 27]):
        #By removing duplicates, atoms might be reordered
        i = np.where(system3.numbers == number)[0]
        assert system1.radii2[j] == system3.radii2[i]
        assert np.all(system1.dipoles[j] == system3.dipoles[i])
Пример #21
0
            self.make_output()

#settings
with log.section('INIT', 2, timer='Initialization'):
    settings = Settings(fn_yaff='pars_cov.txt', plot_traj='All', xyz_traj=True)

#load Gaussian Formatted Checkpoint file
fchk = FCHKFile('gaussian.fchk')
numbers = fchk.fields.get('Atomic numbers')
energy = fchk.fields.get('Total Energy')
coords = fchk.fields.get('Current cartesian coordinates').reshape([len(numbers), 3])
grad = fchk.fields.get('Cartesian Gradient').reshape([len(numbers), 3])
hess = fchk.get_hessian().reshape([len(numbers), 3, len(numbers), 3])

#Construct Yaff System file
system = System(numbers, coords)
system.detect_bonds()
system.set_standard_masses()

#Construct a QuickFF SecondOrderTaylor object containing the AI reference
with log.section('INIT', 2, timer='Initialization'):
    ai = SecondOrderTaylor('ai', coords=coords, energy=energy, grad=grad, hess=hess)

#define atom types
rules = [
    ('H', '1 & =1%8'), #hydrogen atom with one oxygen neighbor
    ('O', '8 & =2%1'), #oxygen atom with two hydrogen neighbors
]
system.detect_ffatypes(rules)

#construct electrostatic force field from HE charges in gaussian_wpart.h5
Пример #22
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
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
Пример #24
0
def main():
    args = parse_args()

    # Load system file
    if args.fn_sys.endswith('.fchk'):
        numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio(
            args.fn_sys, do_hess=False)
        system = System(numbers,
                        coords,
                        rvecs=None,
                        charges=None,
                        radii=None,
                        masses=masses)
        system.detect_bonds()
    else:
        system = System.from_file(args.fn_sys)

    # Guess atom types if needed
    if args.ffatypes is not None:
        guess_ffatypes(system, args.ffatypes)
    ffatypes = [system.ffatypes[i] for i in system.ffatype_ids]

    # Load atomic charges
    fn_charges, _, path = args.charges.partition(':')
    if fn_charges.endswith('.h5'):
        with h5.File(fn_charges, 'r') as f:
            if not path in f:
                raise IOError(
                    'Given HDF5 file %s does not contain a dataset %s' %
                    (fn_charges, path))
            charges = f[path][:]
            radii = None
            if args.gaussian:
                path_radii = os.path.join(os.path.dirname(path), 'radii')
                if 'radii' in f[path]:
                    radii = average(f['%s/radii' % path][:],
                                    ffatypes,
                                    fmt='dict')
                else:
                    radii = average(get_ei_radii(system.numbers),
                                    ffatypes,
                                    fmt='dict')
    elif fn_charges.endswith('.chk'):
        sample = load_chk(fn_charges)
        if path in sample.keys():
            charges = sample[path]
        else:
            raise IOError(
                'Given CHK file %s does not contain a dataset with label %s' %
                (fn_charges, path))
        radii = None
        if args.gaussian:
            if 'radii' in sample.keys():
                radii = average(sample['radii'], ffatypes, fmt='dict')
    else:
        raise IOError(
            'Invalid extension, fn_charges should be a HDF5 or a CHK file.')

    # Derive charge parameters
    if args.bci:
        constraints = {}
        if args.bci_constraints is not None:
            constraints = read_bci_constraints(args.bci_constraints)
        bcis = charges_to_bcis(charges,
                               ffatypes,
                               system.bonds,
                               constraints=constraints,
                               verbose=args.verbose)
        make_yaff_ei(args.fn_out, None, bcis=bcis, radii=radii)
    else:
        charges = average(charges, ffatypes, fmt='dict', verbose=args.verbose)
        make_yaff_ei(args.fn_out, charges, radii=radii)
Пример #25
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
Пример #26
0
def main():
    options, args = parse()
    fn_sys, fn_in, path = args
    if fn_sys.endswith('.fchk'):
        numbers, coords, energy, grad, hess, masses, rvecs, pbc = read_abinitio(
            fn_sys, do_hess=False)
        system = System(numbers,
                        coords,
                        rvecs=None,
                        charges=None,
                        radii=None,
                        masses=masses)
        system.detect_bonds()
    else:
        system = System.from_file(fn_sys)
    if options.ffatypes is not None:
        guess_ffatypes(system, options.ffatypes)
    ffatypes = [system.ffatypes[i] for i in system.ffatype_ids]
    if fn_in.endswith('.h5'):
        h5 = h5py.File(fn_in)
        if not path in h5 or 'charges' not in h5[path]:
            raise IOError(
                'Given HDF5 file %s does not contain dataset %s/charges' %
                (fn_in, path))
        charges = h5['%s/charges' % path][:]
        radii = None
        if options.gaussian:
            if 'radii' in h5[path]:
                radii = average(h5['%s/radii' % path][:], ffatypes, fmt='dict')
            else:
                radii = average(get_ei_radii(system.numbers),
                                ffatypes,
                                fmt='dict')
    elif fn_in.endswith('.chk'):
        sample = load_chk(fn_in)
        if path in sample.keys():
            charges = sample[path]
        else:
            raise IOError(
                'Given CHK file %s does not contain dataset with label %s' %
                (fn_in, path))
        radii = None
        if options.gaussian:
            if 'radii' in sample.keys():
                radii = average(sample['radii'], ffatypes, fmt='dict')
    else:
        raise IOError(
            'Invalid extension, fn_in should be a HDF5 or a CHK file.')
    if options.output is None:
        if path == '.':
            fn_out = 'pars_ei.txt'
        else:
            fn_out = 'pars_ei_%s.txt' % path.replace('/', '_')
    else:
        fn_out = options.output
    if options.bci:
        constraints = {}
        if options.bci_constraints is not None:
            constraints = read_bci_constraints(options.bci_constraints)
        bcis = charges_to_bcis(charges,
                               ffatypes,
                               system.bonds,
                               constraints=constraints,
                               verbose=options.verbose)
        make_yaff_ei(fn_out, None, bcis=bcis, radii=radii)
    else:
        charges = average(charges,
                          ffatypes,
                          fmt='dict',
                          verbose=options.verbose)
        make_yaff_ei(fn_out, charges, radii=radii)
Пример #27
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()
Пример #28
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()