def test_from_files(tmp_path): system, pars = get_system('mil53') configuration = Configuration(system, pars) configuration.write(tmp_path / 'config.yml') system.to_file(str(tmp_path / 'system.chk')) with open(tmp_path / 'pars.txt', 'w+') as f: f.write(pars) path_system = tmp_path / 'system.chk' path_pars = tmp_path / 'pars.txt' path_config = tmp_path / 'config.yml' configuration = Configuration.from_files( chk=path_system, txt=path_pars, yml=path_config, )
def test_update_properties(tmp_path): system, pars = get_system('mil53') configuration = Configuration(system, pars) config = configuration.write() config['yaff']['rcut'] = 15.0 config['yaff']['interaction_radius'] = 15.0 configuration.update_properties(config) assert configuration.rcut == 15.0
def test_initialize_nonperiodic(tmp_path): system, pars = get_system('alanine') configuration = Configuration(system, pars) configuration.log_system() # write defaults path_config = tmp_path / 'config.yml' config = configuration.write(path_config) with open(path_config, 'r') as f: content = f.read() assert content == """yaff: {}\n"""
def test_wrapper_openmm_mic(): system, pars = get_system('mil53') configuration = Configuration(system, pars) kind = 'all' # YAFF and OpenMM use a different switching function. If it is disabled, # the results between both are identical up to 6 decimals configuration.switch_width = 0.0 # disable switching configuration.rcut = 10.0 # request cutoff of 10 angstorm configuration.cell_interaction_radius = 10.0 configuration.supercell = [2, 3, 5] configuration.update_properties(configuration.write()) conversion = ExplicitConversion(pme_error_thres=1e-5) seed_mm = conversion.apply(configuration, seed_kind=kind) wrapper = OpenMMForceFieldWrapper.from_seed(seed_mm, 'Reference') u = molmod.units.angstrom seed_yaff = configuration.create_seed(kind=kind) positions = seed_yaff.system.pos.copy() / u rvecs = seed_yaff.system.cell._get_rvecs().copy() / u e, _ = wrapper.evaluate(positions, rvecs, do_forces=True) # make random periodic displacements for i in range(5): coefficients = np.random.randint(-3, high=3, size=(3, 1)) atom = np.random.randint(0, high=seed_yaff.system.natom, size=(10,)) positions[atom, :] += np.sum(coefficients * rvecs, axis=0) e_ = wrapper.evaluate(positions, rvecs, do_forces=False) assert np.allclose(e, e_) # make random periodic displacements and rewrap coordinates for i in range(5): coefficients = np.random.randint(-3, high=3, size=(3, 1)) atom = np.random.randint(0, high=seed_yaff.system.natom, size=(10,)) positions[atom, :] += np.sum(coefficients * rvecs, axis=0) wrap_coordinates(positions, rvecs, rectangular=True) e_ = wrapper.evaluate(positions, rvecs, do_forces=False) assert np.allclose(e, e_)
def test_periodic(): systems = ['uio66', 'cau13', 'mil53', 'ppycof', 'cof5', 'mof5'] platforms = ['Reference'] seed_kinds = ['covalent', 'dispersion', 'electrostatic'] # systematic constant offset in dispersion energy for COFs, unclear why tolerance = { ('Reference', 'covalent'): 1e-6, # some MM3 terms have error 1e-7 ('Reference', 'dispersion'): 1e-2, # some MM3 terms have error 1e-3 ('Reference', 'electrostatic'): 1e-3, #('CUDA', 'covalent'): 1e-3, #('CUDA', 'dispersion'): 1e-3, #('CUDA', 'electrostatic'): 1e-3, } nstates = 5 disp_ampl = 0.3 box_ampl = 0.3 for name in systems: for platform in platforms: for kind in seed_kinds: system, pars = get_system(name) configuration = Configuration(system, pars) tol = tolerance[(platform, kind)] # YAFF and OpenMM use a different switching function. If it is disabled, # the results between both are identical up to 6 decimals configuration.switch_width = 0.0 # disable switching configuration.rcut = 13.0 # request cutoff of 13 angstorm configuration.interaction_radius = 15.0 configuration.update_properties(configuration.write()) conversion = ExplicitConversion(pme_error_thres=5e-4) seed_mm = conversion.apply(configuration, seed_kind=kind) seed_yaff = configuration.create_seed(kind=kind) wrapper_mm = OpenMMForceFieldWrapper.from_seed( seed_mm, platform) wrapper_yaff = YaffForceFieldWrapper.from_seed(seed_yaff) assert wrapper_yaff.periodic # system should not be considered periodic assert wrapper_mm.periodic # system should not be considered periodic pos = seed_yaff.system.pos.copy() rvecs = seed_yaff.system.cell._get_rvecs().copy() for i in range(nstates): dpos = np.random.uniform(-disp_ampl, disp_ampl, size=pos.shape) drvecs = np.random.uniform(-box_ampl, box_ampl, size=rvecs.shape) drvecs[0, 1] = 0 drvecs[0, 2] = 0 drvecs[1, 2] = 0 tmp = rvecs + drvecs reduce_box_vectors(tmp) energy_mm, forces_mm = wrapper_mm.evaluate( (pos + dpos) / molmod.units.angstrom, rvecs=tmp / molmod.units.angstrom, ) energy, forces = wrapper_yaff.evaluate( (pos + dpos) / molmod.units.angstrom, rvecs=tmp / molmod.units.angstrom, ) assert_tol(energy, energy_mm, tol) assert_tol(forces, forces_mm, 10 * tol)