def test_get_ts_guess_neb(): reactant = Reactant(name='inital', charge=-1, mult=0, solvent_name='water', atoms=xyz_file_to_atoms(init_xyz)) product = Reactant(name='final', charge=-1, mult=0, solvent_name='water', atoms=xyz_file_to_atoms(final_xyz)) xtb = XTB() # Don't run the NEB without a working XTB install if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'): return xtb.path = shutil.which('xtb') ts_guess = neb.get_ts_guess_neb(reactant, product, method=xtb, n=10) assert ts_guess is not None # Approximate distances at the TS guess assert 1.8 < ts_guess.get_distance(0, 2) < 2.2 # C-F assert 1.9 < ts_guess.get_distance(2, 1) < 2.3 # C-Cl if os.path.exists('NEB'): shutil.rmtree('NEB') if os.path.exists('neb.xyz'): os.remove('neb.xyz')
def test_full_calc_with_xtb(): sn2_neb = neb.NEB( initial_species=Species(name='inital', charge=-1, mult=0, atoms=xyz_file_to_atoms('sn2_init.xyz')), final_species=Species(name='final', charge=-1, mult=0, atoms=xyz_file_to_atoms('sn2_final.xyz')), num=14) sn2_neb.interpolate_geometries() xtb = XTB() # Don't run the NEB without a working XTB install if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'): return xtb.path = shutil.which('xtb') sn2_neb.calculate(method=xtb, n_cores=2) # There should be a peak in this surface assert len(list(sn2_neb.get_species_saddle_point())) > 0 assert all(image.energy is not None for image in sn2_neb.images) energies = [image.energy for image in sn2_neb.images] path_energy = sum(energy - min(energies) for energy in energies) assert 0.35 < path_energy < 0.45
def test_calc_string(): xtb = XTB() no_const = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp) cart_const = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp, cartesian_constraints=[0]) dist_const = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp, distance_constraints={(0, 1): 1.0}) dist_const2 = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp, distance_constraints={(0, 1): 1.5}) assert str(no_const) == str(no_const) assert str(no_const) != str(cart_const) assert str(no_const) != str(dist_const) assert str(cart_const) != str(dist_const) assert str(dist_const) != str(dist_const2)
def test_input_gen(): xtb = XTB() calc = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp) Config.keep_input_files = True calc.generate_input() assert os.path.exists('tmp_xtb.xyz') calc.clean_up() # Clean-up should do nothing if keep_input_files = True assert os.path.exists('tmp_xtb.xyz') # but should be able to be forced calc.clean_up(force=True) assert not os.path.exists('tmp_xtb.xyz') # Test the keywords parsing unsupported_func = Functional('PBE', orca='PBE') calc_kwds = Calculation(name='tmp', molecule=test_mol, method=xtb, keywords=SinglePointKeywords([unsupported_func])) with pytest.raises(ex.UnsuppportedCalculationInput): calc_kwds.generate_input()
def test_solvent_get(): xtb = XTB() # Can't get the name of a solvent if molecule.solvent is not a string test_mol.solvent = 5 with pytest.raises(ex.SolventUnavailable): _ = get_solvent_name(molecule=test_mol, method=xtb) test_mol.solvent = None assert get_solvent_name(test_mol, method=xtb) is None test_mol.solvent = 'a_solvent_that_doesnt_exist' with pytest.raises(ex.SolventNotFound): _ = get_solvent_name(molecule=test_mol, method=xtb) # Should work fine with a normal solvent test_mol.solvent = get_solvent(solvent_name='water') solv_name_xtb = get_solvent_name(test_mol, method=xtb) assert solv_name_xtb.lower() in ['water', 'h2o'] # Currently iodoethane is not in XTB - might be in the future test_mol.solvent = get_solvent(solvent_name='iodoethane') with pytest.raises(ex.SolventUnavailable): _ = get_solvent_name(test_mol, method=xtb) test_mol.solvent = 0 with pytest.raises(ex.SolventUnavailable): _ = get_solvent_name(test_mol, method=xtb) # return to the gas phase test_mol.solvent = None
def parallel_xtb(self): """Run parallel XTB on these configurations""" from gaptrain.calculators import run_autode from autode.methods import XTB return self._run_parallel_method(run_autode, max_force=None, n_cores=1, method=XTB())
def run_xtb(self, max_force=None, n_cores=None): """Run an XTB calculation on this configuration""" from gaptrain.calculators import run_autode, GTConfig from autode.methods import XTB assert max_force is None n_cores = n_cores if n_cores is not None else GTConfig.n_cores return run_autode(self, method=XTB(), n_cores=n_cores)
def test_adaptive_path(): species_no_atoms = Species(name='tmp', charge=0, mult=1, atoms=[]) path1 = AdaptivePath(init_species=species_no_atoms, bonds=[], method=XTB()) assert len(path1) == 0 assert path1.method.name == 'xtb' assert len(path1.bonds) == 0 assert path1 != 0 assert path1 == path1
def test_get_ts_guess_neb(): reactant = Reactant(name='inital', charge=-1, mult=0, solvent_name='water', atoms=xyz_file_to_atoms('sn2_init.xyz')) product = Reactant(name='final', charge=-1, mult=0, solvent_name='water', atoms=xyz_file_to_atoms('sn2_final.xyz')) xtb = XTB() # Don't run the NEB without a working XTB install if shutil.which('xtb') is None or not shutil.which('xtb').endswith('xtb'): return xtb.path = shutil.which('xtb') ts_guess = get_ts_guess_neb(reactant, product, method=xtb, n=10) assert ts_guess is not None # Approximate distances at the TS guess assert 1.8 < ts_guess.distance(0, 2) < 2.3 # C-F assert 1.9 < ts_guess.distance(2, 1) < 2.5 # C-Cl if os.path.exists('NEB'): shutil.rmtree('NEB') if os.path.exists('neb.xyz'): os.remove('neb.xyz') # Trying to get a TS guess with an unavailable method should return None # as a TS guess orca = ORCA() orca.path = None orca_ts_guess = get_ts_guess_neb(reactant, product, method=orca, n=10) assert orca_ts_guess is None
def set_charges_vdw(species): """Calculate the partial atomic charges to atoms with XTB""" calc = Calculation(name='tmp', molecule=species, method=XTB(), keywords=ade.SinglePointKeywords([])) calc.run() charges = calc.get_atomic_charges() for i, atom in enumerate(species.atoms): atom.charge = charges[i] atom.vdw = get_vdw_radius(atom_label=atom.label) return None
def test_constrained_opt(): mol = Molecule(name='h3', mult=2, charge=0, atoms=[ Atom('H', 0.0, 0.0, 0.0), Atom('H', 0.7, 0.0, 0.0), Atom('H', 1.7, 0.0, 0.0) ]) # Spoof an XTB install Config.XTB.path = here ts_guess = get_ts_guess_constrained_opt( reactant=ReactantComplex(mol), distance_consts={(0, 1): 1.0}, method=XTB(), keywords=Config.XTB.keywords.low_opt, name='template_ts_guess', product=ProductComplex(mol)) assert ts_guess.n_atoms == 3
from autode import Molecule from autode.calculation import Calculation from autode.methods import XTB import matplotlib.pyplot as plt import numpy as np # Initialise the electronic structure method (XTB) xtb = XTB() water = Molecule(name='H2O', smiles='O') rs = np.linspace(0.65, 2.0, num=20) # List of energies to be populated for the single point (unrelaxed) # and constrained optimisations (relaxed) calculations sp_energies, opt_energies = [], [] for r in rs: o_atom, h_atom = water.atoms[:2] curr_r = water.get_distance(0, 1) # current O-H distance # Shift the hydrogen atom to the required distance # vector = (h_atom.coord - o_atom.coord) / curr_r * (r - curr_r) vector = (h_atom.coord - o_atom.coord) * (r / curr_r - 1) h_atom.translate(vector) # Set up and run the single point energy evaluation sp = Calculation(name=f'H2O_scan_unrelaxed_{r:.2f}', molecule=water, method=xtb, keywords=xtb.keywords.sp)
from autode.input_output import xyz_file_to_atoms from autode.conformers import conf_gen, Conformer from autode.methods import XTB # Initialise the complex from a .xyz file containing a square planar structure vaskas = Molecule(name='vaskas', atoms=xyz_file_to_atoms('vaskas.xyz')) # Set up some distance constraints where the keys are the atom indexes and # the value the distance in Å. Fixing the Cl-P, Cl-P and Cl-C(=O) distances # enforces a square planar geometry distance_constraints = { (1, 2): vaskas.get_distance(1, 2), (1, 3): vaskas.get_distance(1, 3), (1, 4): vaskas.get_distance(1, 4) } # Generate 5 conformers for n in range(5): # Apply random displacements to each atom and minimise under a bonded + # repulsive forcefield including the distance constraints atoms = conf_gen.get_simanl_atoms(species=vaskas, dist_consts=distance_constraints, conf_n=n) # Generate a conformer from these atoms then optimise with XTB conformer = Conformer(name=f'vaskas_conf{n}', atoms=atoms) conformer.optimise(method=XTB()) conformer.print_xyz_file()
def test_calc_class(): xtb = XTB() calc = Calculation(name='-tmp', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp) # Should prepend a dash to appease some EST methods assert not calc.name.startswith('-') assert calc.molecule is not None assert calc.method.name == 'xtb' assert calc.get_energy() is None assert calc.get_enthalpy() is None assert calc.get_free_energy() is None assert not calc.optimisation_converged() assert not calc.optimisation_nearly_converged() with pytest.raises(ex.AtomsNotFound): _ = calc.get_final_atoms() with pytest.raises(ex.CouldNotGetProperty): _ = calc.get_gradients() with pytest.raises(ex.CouldNotGetProperty): _ = calc.get_atomic_charges() # Calculation that has not been run shouldn't have an opt converged assert not calc.optimisation_converged() assert not calc.optimisation_nearly_converged() # With a filename that doesn't exist a NoOutput exception should be raised calc.output.filename = '/a/path/that/does/not/exist/tmp' with pytest.raises(ex.NoCalculationOutput): calc.output.set_lines() # With no output should not be able to get properties calc.output.filename = 'tmp' calc.output.file_lines = [] with pytest.raises(ex.CouldNotGetProperty): _ = calc.get_atomic_charges() # or final atoms with pytest.raises(ex.AtomsNotFound): _ = calc.get_final_atoms() # Should default to a single core assert calc.n_cores == 1 calc_str = str(calc) new_calc = Calculation(name='tmp2', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp) new_calc_str = str(new_calc) # Calculation strings need to be unique assert new_calc_str != calc_str new_calc = Calculation(name='tmp2', molecule=test_mol, method=xtb, keywords=xtb.keywords.sp, temp=5000) assert str(new_calc) != new_calc_str mol_no_atoms = Molecule() with pytest.raises(ex.NoInputError): _ = Calculation(name='tmp2', molecule=mol_no_atoms, method=xtb, keywords=xtb.keywords.sp)