def test_uio66zrbrick_crossterms(): with log.section('NOSETEST', 2): # Load input data for a ficticious system of an isolated # UiO-66 brick name = 'uio66-zr-brick/system.chk' fn = context.get_fn(os.path.join('systems', name)) 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
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
def test_iter_matches_guaianolide(): system = System.from_file(context.get_fn('test/guaianolide.xyz')) system.detect_bonds() system_ref = System.from_file(context.get_fn('test/guaianolide_framework_ordered.xyz')) system_ref.detect_bonds() order = np.array(system.iter_matches(system_ref).next()) np.testing.assert_equal(order, [8, 9, 4, 7, 14, 12, 11, 10, 5, 6, 13, 16, 15, 2, 0, 1, 3])
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
def test_CAU13_xylene(): host = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/CAU_13.chk')) guest = System.from_file(pkg_resources.resource_filename(__name__, '../../data/test/xylene.chk')) pars_fn = pkg_resources.resource_filename(__name__, '../../data/test/parameters_CAU-13_xylene.txt') complex = host.merge(guest) for tailcorrections in False, True: # Construct force fields ff_complex = ForceField.generate(complex, pars_fn, tailcorrections=tailcorrections) ff_host = ForceField.generate(host, pars_fn, tailcorrections=tailcorrections) ff_exclude = ForceField.generate(complex, pars_fn, nlow=host.natom, tailcorrections=tailcorrections) # The nlow keyword is meant to exclude all pair interactions when both # atomic indices are smaller than nlow # The energy of this force field should be exactly equal to the energy of # the entire complex (featuring framework-framework, framework-guest, and # guest-guest interactions) minus the energy of the framework (featuring # only framework-framework interactions). Note that this is not what is # usually considered an interaction energy, because for instance guest-guest # valence interactions are still included. e_complex = ff_complex.compute() e_host = ff_host.compute() e_exclude = ff_exclude.compute() # Compare energies part by part nparts = len(ff_complex.parts) assert len(ff_host.parts)==nparts assert len(ff_exclude.parts)==nparts for ipart in range(nparts): eref = ff_complex.parts[ipart].energy - ff_host.parts[ipart].energy ecomp = ff_exclude.parts[ipart].energy print("%20s %15.9f %15.9f"% (ff_exclude.parts[ipart].name, eref, ecomp)) assert np.abs(eref-ecomp)<1e-10
def 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
def test_iter_matches_nobornane_rhodium(): rules = [ ('H', '1'), ('C_H1', '6&=1%1'), ('C_H2', '6&=2%1'), ('C_H3', '6&=3%1'), ('C', '6'), # all remaining carbons ('P', '15'), ('Rh', '45'), ] system = System.from_file( pkg_resources.resource_filename( __name__, '../data/test/rhodium_complex_nobornane.xyz')) system.detect_bonds() system.detect_ffatypes(rules) system_ref = System.from_file( pkg_resources.resource_filename(__name__, '../data/test/nobornane.xyz')) system_ref.detect_bonds() system_ref.detect_ffatypes(rules) selected = set(next(system.iter_matches(system_ref))) reference = set([ 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95 ]) np.testing.assert_equal(selected, reference)
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
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
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')
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)
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)
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)
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)
def write_chk(input_dict,working_directory='.'): # collect data and initialize Yaff system if 'cell' in input_dict.keys() and input_dict['cell'] is not None: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes'], ffatype_ids=input_dict['ffatype_ids'], rvecs=input_dict['cell']*angstrom) else: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes'], ffatype_ids=input_dict['ffatype_ids']) # determine masses, bonds and ffaypes from ffatype_rules system.detect_bonds() system.set_standard_masses() # write dictionary to MolMod CHK file system.to_file(posixpath.join(working_directory,'system.chk'))
def test_iter_matches_guaianolide(): system = System.from_file( pkg_resources.resource_filename(__name__, '../data/test/guaianolide.xyz')) system.detect_bonds() system_ref = System.from_file( pkg_resources.resource_filename( __name__, '../data/test/guaianolide_framework_ordered.xyz')) system_ref.detect_bonds() order = np.array(next(system.iter_matches(system_ref))) np.testing.assert_equal( order, [8, 9, 4, 7, 14, 12, 11, 10, 5, 6, 13, 16, 15, 2, 0, 1, 3])
def test_supercell_dipoles(): 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'], 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, ) sys333 = sys111.supercell(3,3,3) assert (sys333.dipoles == np.tile(np.array([[0.1,1.0,2.0],[0.5,0.7,0.9]]), (27,1))).all() assert (sys333.radii2 == np.tile(np.array([0.0,2.0]), 27)).all()
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()
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
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'
def load_system_xyz(fn): '''Load atomic numbers, coordinates and cell parameters from fn''' # Load the cell vectors from the second line. print 'Loading atomic structure from XYZ file.' with open(fn) as f: # Skip one line. f.next() # Read rvecs (real-space cell vectors). real_numbers = [] for word in f.next().split(): try: real_numbers.append(float(word)) except ValueError: pass print 'Detected %i real numbers in title line.' % len(real_numbers) if len(real_numbers) >= 9: rvecs = np.array(real_numbers[:9]).reshape(3, 3)*angstrom print 'Treating system as periodic with the following cell vectors' print 'in Angstrom. (Cell vectors are displayed as rows.)' print rvecs/angstrom else: print 'I\'m assuming the system is aperiodic because there are less' print 'than nine real numbers in the title line.' rvecs = None # Let Yaff read the rest of the file. print return System.from_file(fn, rvecs=rvecs)
def load_chk(self, fn): """ Load the atom types, atom type ids and structure by reading a .chk file. **Arguments** fn the path to the chk file """ system = System.from_file(fn) system.set_standard_masses() if len(system.pos.shape) != 2: raise IOError( "Something went wrong, positions in CHK file %s should have Nx3 dimensions" % fn) if system.cell.rvecs is not None and len(system.cell.rvecs) > 0: self.structure = Atoms( positions=system.pos.copy() / angstrom, numbers=system.numbers, masses=system.masses, cell=system.cell.rvecs / angstrom, pbc=True, ) else: self.structure = Atoms( positions=system.pos.copy() / angstrom, numbers=system.numbers, masses=system.masses, ) if system.ffatypes is not None: self.ffatypes = system.ffatypes if system.ffatype_ids is not None: self.ffatype_ids = system.ffatype_ids
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)
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)
def load_system_xyz(fn): '''Load atomic numbers, coordinates and cell parameters from fn''' # Load the cell vectors from the second line. print 'Loading atomic structure from XYZ file.' with open(fn) as f: # Skip one line. f.next() # Read rvecs (real-space cell vectors). real_numbers = [] for word in f.next().split(): try: real_numbers.append(float(word)) except ValueError: pass print 'Detected %i real numbers in title line.' % len(real_numbers) if len(real_numbers) >= 9: rvecs = np.array(real_numbers[:9]).reshape(3, 3) * angstrom print 'Treating system as periodic with the following cell vectors' print 'in Angstrom. (Cell vectors are displayed as rows.)' print rvecs / angstrom else: print 'I\'m assuming the system is aperiodic because there are less' print 'than nine real numbers in the title line.' rvecs = None # Let Yaff read the rest of the file. print return System.from_file(fn, rvecs=rvecs)
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
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] )
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])
def test_xyz(): system0 = get_system_water32() with tmpdir(__name__, 'test_xyz') as dirname: system0.to_file('%s/tmp.xyz' % dirname) system1 = System.from_file('%s/tmp.xyz' % dirname, rvecs=system0.cell.rvecs, ffatypes=system0.ffatypes, ffatype_ids=system0.ffatype_ids) compare_water32(system0, system1, 1e-10, xyz=True)
def test_hdf5(): system0 = get_system_water32() with tmpdir(__name__, 'test_hdf5') as dirname: fn = '%s/tmp.h5' % dirname system0.to_file(fn) with h5.File(fn) as f: assert 'system' in f system1 = System.from_file(fn) compare_water32(system0, system1)
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'
def test_chk(): system0 = get_system_water32() dirname = tempfile.mkdtemp('yaff', 'test_chk') try: system0.to_file('%s/tmp.chk' % dirname) system1 = System.from_file('%s/tmp.chk' % dirname) compare_water32(system0, system1, 1e-10) finally: shutil.rmtree(dirname)
def test_xyz(): system0 = get_system_water32() dirname = tempfile.mkdtemp('yaff', 'test_xyz') try: system0.to_file('%s/tmp.xyz' % dirname) system1 = System.from_file('%s/tmp.xyz' % dirname, rvecs=system0.cell.rvecs, ffatypes=system0.ffatypes, ffatype_ids=system0.ffatype_ids) compare_water32(system0, system1, 1e-10, xyz=True) finally: shutil.rmtree(dirname)
def __init__(self, latency=1.0, name="", yaffpara=None, yaffsys=None, yafflog='yaff.log', rcut=18.89726133921252, alpha_scale=3.5, gcut_scale=1.1, skin=0, smooth_ei=False, reci_ei='ewald', pars=None, dopbc=False, threaded=True): """Initialises FFYaff and enables a basic Yaff force field. Args: yaffpara: File name of the Yaff parameter file yaffsys: File name of the Yaff system file yafflog: File name to which Yaff will write some information about the system and the force field pars: Optional dictionary, giving the parameters needed by the driver. **kwargs: All keyword arguments that can be provided when generating a Yaff force field; see constructor of FFArgs in Yaff code """ from yaff import System, ForceField, log import codecs import locale import atexit # a socket to the communication library is created or linked super(FFYaff, self).__init__(latency, name, pars, dopbc) # A bit weird to use keyword argument for a required argument, but this # is also done in the code above. if yaffpara is None: raise ValueError("Must provide a Yaff parameter file.") if yaffsys is None: raise ValueError("Must provide a Yaff system file.") self.yaffpara = yaffpara self.yaffsys = yaffsys self.rcut = rcut self.alpha_scale = alpha_scale self.gcut_scale = gcut_scale self.skin = skin self.smooth_ei = smooth_ei self.reci_ei = reci_ei self.yafflog = yafflog # Open log file logf = open(yafflog, 'w') # Tell Python to close the file when the script exits atexit.register(logf.close) # Redirect Yaff log to file log._file = codecs.getwriter(locale.getpreferredencoding())(logf) self.system = System.from_file(self.yaffsys) self.ff = ForceField.generate(self.system, self.yaffpara, rcut=self.rcut, alpha_scale=self.alpha_scale, gcut_scale=self.gcut_scale, skin=self.skin, smooth_ei=self.smooth_ei, reci_ei=self.reci_ei) log._active = False
def __init__(self, latency=1.0, name="", threaded=False, yaffpara=None, yaffsys=None, yafflog='yaff.log', rcut=18.89726133921252, alpha_scale=3.5, gcut_scale=1.1, skin=0, smooth_ei=False, reci_ei='ewald', pars=None, dopbc=False): """Initialises FFYaff and enables a basic Yaff force field. Args: yaffpara: File name of the Yaff parameter file yaffsys: File name of the Yaff system file yafflog: File name to which Yaff will write some information about the system and the force field pars: Optional dictionary, giving the parameters needed by the driver. **kwargs: All keyword arguments that can be provided when generating a Yaff force field; see constructor of FFArgs in Yaff code """ from yaff import System, ForceField, log import codecs import locale import atexit # a socket to the communication library is created or linked super(FFYaff, self).__init__(latency, name, pars, dopbc, threaded=threaded) # A bit weird to use keyword argument for a required argument, but this # is also done in the code above. if yaffpara is None: raise ValueError("Must provide a Yaff parameter file.") if yaffsys is None: raise ValueError("Must provide a Yaff system file.") self.yaffpara = yaffpara self.yaffsys = yaffsys self.rcut = rcut self.alpha_scale = alpha_scale self.gcut_scale = gcut_scale self.skin = skin self.smooth_ei = smooth_ei self.reci_ei = reci_ei self.yafflog = yafflog # Open log file logf = open(yafflog, 'w') # Tell Python to close the file when the script exits atexit.register(logf.close) # Redirect Yaff log to file log._file = codecs.getwriter(locale.getpreferredencoding())(logf) self.system = System.from_file(self.yaffsys) self.ff = ForceField.generate(self.system, self.yaffpara, rcut=self.rcut, alpha_scale=self.alpha_scale, gcut_scale=self.gcut_scale, skin=self.skin, smooth_ei=self.smooth_ei, reci_ei=self.reci_ei) log._active = False
def test_hdf5_assign_ffatypes(): system0 = get_system_water32() with tmpdir(__name__, 'test_hdf5_assign_ffatypes') as dirname: system0.ffatypes = ['O', 'H'] system0.ffatype_ids = np.array([0, 1, 1] * 32) fn = '%s/tmp.h5' % dirname system0.to_file(fn) with h5.File(fn) as f: assert 'system' in f system1 = System.from_file(fn) compare_water32(system0, system1)
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()
def test_lammps_ffconversion_mil53(): fn_system = pkg_resources.resource_filename( __name__, '../../data/test/system_mil53.chk') fn_pars = pkg_resources.resource_filename( __name__, '../../data/test/parameters_mil53.txt') system = System.from_file(fn_system) with tmpdir(__name__, 'test_lammps_ffconversion_mil53') as dirname: ff2lammps(system, fn_pars, dirname) # No test for correctness, just check that output files are present assert os.path.isfile(os.path.join(dirname, 'lammps.in')) assert os.path.isfile(os.path.join(dirname, 'lammps.data'))
def test_hdf5(): system0 = get_system_water32() dirname = tempfile.mkdtemp('yaff', 'test_hdf5') try: fn = '%s/tmp.h5' % dirname system0.to_file(fn) with h5.File(fn) as f: assert 'system' in f system1 = System.from_file(fn) compare_water32(system0, system1) finally: shutil.rmtree(dirname)
def write_chk(input_dict, working_directory='.'): # collect data and initialize Yaff system if 'cell' in input_dict.keys() and input_dict['cell'] is not None: system = System(input_dict['numbers'], input_dict['pos']*angstrom, rvecs=input_dict['cell']*angstrom, ffatypes=input_dict['ffatypes_man'], ffatype_ids=input_dict['ffatype_ids_man']) else: system = System(input_dict['numbers'], input_dict['pos']*angstrom, ffatypes=input_dict['ffatypes_man'], ffatype_ids=input_dict['ffatype_ids_man']) # determine masses, bonds and ffaypes from ffatype_rules system.detect_bonds() system.set_standard_masses() # write dictionnairy to MolMod CHK file system.to_file(posixpath.join(working_directory,'input.chk')) # Reload input.chk as dictionairy and add AI input data d = load_chk(posixpath.join(working_directory,'input.chk')) assert isinstance(input_dict['aiener'], float), "AI energy not defined in input, use job.read_abintio(...)" assert isinstance(input_dict['aigrad'], np.ndarray), "AI gradient not defined in input, use job.read_abintio(...)" assert isinstance(input_dict['aihess'], np.ndarray), "AI hessian not defined in input, use job.read_abintio(...)" d['energy'] = input_dict['aiener'] d['grad'] = input_dict['aigrad'] d['hess'] = input_dict['aihess'] dump_chk(posixpath.join(working_directory,'input.chk'), d)
def 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
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