def test_opt_calc(): calc = Calculation(name='opt', molecule=test_mol, method=method, keywords=opt_keywords) calc.run() assert os.path.exists('opt_nwchem.nw') assert os.path.exists('opt_nwchem.out') final_atoms = calc.get_final_atoms() assert len(final_atoms) == 5 assert type(final_atoms[0]) is Atom assert -40.4165 < calc.get_energy() < -40.4164 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.get_imaginary_freqs() == [] assert calc.input.filename == 'opt_nwchem.nw' assert calc.output.filename == 'opt_nwchem.out' assert calc.terminated_normally() assert calc.optimisation_converged() assert calc.optimisation_nearly_converged() is False charges = calc.get_atomic_charges() assert len(charges) == 5 assert all(-1.0 < c < 1.0 for c in charges) # Optimisation should result in small gradients gradients = calc.get_gradients() assert len(gradients) == 5 assert all(-0.1 < np.linalg.norm(g) < 0.1 for g in gradients)
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_xtb_calculation(): test_mol = Molecule(name='test_mol', smiles='O=C(C=C1)[C@@](C2NC3C=C2)([H])[C@@]3([H])C1=O') calc = Calculation(name='opt', molecule=test_mol, method=method, keywords=Config.XTB.keywords.opt) calc.run() assert os.path.exists('opt_xtb.xyz') is True assert os.path.exists('opt_xtb.out') is True assert len(calc.get_final_atoms()) == 22 assert calc.get_energy() == -36.990267613593 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.input.filename == 'opt_xtb.xyz' assert calc.output.filename == 'opt_xtb.out' with pytest.raises(NotImplementedError): calc.optimisation_nearly_converged() with pytest.raises(NotImplementedError): calc.get_imaginary_freqs() with pytest.raises(NotImplementedError): calc.get_normal_mode_displacements(4) charges = calc.get_atomic_charges() assert len(charges) == 22 assert all(-1.0 < c < 1.0 for c in charges) const_opt = Calculation(name='const_opt', molecule=test_mol, method=method, distance_constraints={(0, 1): 1.2539792}, cartesian_constraints=[0], keywords=Config.XTB.keywords.opt) const_opt.generate_input() assert os.path.exists('const_opt_xtb.xyz') assert os.path.exists('xcontrol_const_opt_xtb') const_opt.clean_up(force=True) assert not os.path.exists('xcontrol_const_opt_xtb') # Write an empty output file open('tmp.out', 'w').close() const_opt.output.filename = 'tmp.out' const_opt.output.set_lines() # cannot get atoms from an empty file with pytest.raises(AtomsNotFound): _ = const_opt.get_final_atoms()
def run_autode(configuration, max_force=None, method=None, n_cores=1): """ Run an orca or xtb calculation -------------------------------------------------------------------------- :param configuration: (gaptrain.configurations.Configuration) :param max_force: (float) or None :param method: (autode.wrappers.base.ElectronicStructureMethod) """ from autode.species import Species from autode.calculation import Calculation from autode.exceptions import CouldNotGetProperty if method.name == 'orca' and GTConfig.orca_keywords is None: raise ValueError("For ORCA training GTConfig.orca_keywords must be" " set. e.g. " "GradientKeywords(['PBE', 'def2-SVP', 'EnGrad'])") # optimisation is not implemented, needs a method to run assert max_force is None and method is not None species = Species(name=configuration.name, atoms=configuration.atoms, charge=configuration.charge, mult=configuration.mult) # allow for an ORCA calculation to have non-default keywords.. not the # cleanest implementation.. kwds = GTConfig.orca_keywords if method.name == 'orca' else method.keywords.grad calc = Calculation(name='tmp', molecule=species, method=method, keywords=kwds, n_cores=n_cores) calc.run() ha_to_ev = 27.2114 try: configuration.forces = -ha_to_ev * calc.get_gradients() except CouldNotGetProperty: logger.error('Failed to set forces') configuration.energy = ha_to_ev * calc.get_energy() configuration.partial_charges = calc.get_atomic_charges() return configuration
def test_gauss_opt_calc(): os.chdir(os.path.join(here, 'data')) methylchloride = Molecule(name='CH3Cl', smiles='[H]C([H])(Cl)[H]', solvent_name='water') calc = Calculation(name='opt', molecule=methylchloride, method=method, keywords=opt_keywords) calc.run() assert os.path.exists('opt_g09.com') assert os.path.exists('opt_g09.log') assert len(calc.get_final_atoms()) == 5 assert os.path.exists('opt_g09.xyz') assert calc.get_energy() == -499.729222331 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.get_imaginary_freqs() == [] with pytest.raises(NoNormalModesFound): calc.get_normal_mode_displacements(mode_number=1) assert calc.input.filename == 'opt_g09.com' assert calc.output.filename == 'opt_g09.log' assert calc.terminated_normally() assert calc.optimisation_converged() assert calc.optimisation_nearly_converged() is False charges = calc.get_atomic_charges() assert len(charges) == methylchloride.n_atoms # Should be no very large atomic charges in this molecule assert all(-1.0 < c < 1.0 for c in charges) gradients = calc.get_gradients() assert len(gradients) == methylchloride.n_atoms assert len(gradients[0]) == 3 # Should be no large forces for an optimised molecule assert sum(gradients[0]) < 0.1 os.remove('opt_g09.com') os.chdir(here)
def test_orca_opt_calculation(): os.chdir(os.path.join(here, 'data')) methylchloride = Molecule(name='CH3Cl', smiles='[H]C([H])(Cl)[H]', solvent_name='water') calc = Calculation(name='opt', molecule=methylchloride, method=method, keywords=opt_keywords) calc.run() assert os.path.exists('opt_orca.inp') is True assert os.path.exists('opt_orca.out') is True assert len(calc.get_final_atoms()) == 5 assert -499.735 < calc.get_energy() < -499.730 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.get_imaginary_freqs() == [] assert calc.input.filename == 'opt_orca.inp' assert calc.output.filename == 'opt_orca.out' assert calc.terminated_normally() assert calc.optimisation_converged() assert calc.optimisation_nearly_converged() is False with pytest.raises(NoNormalModesFound): calc.get_normal_mode_displacements(mode_number=0) # Should have a partial atomic charge for every atom charges = calc.get_atomic_charges() assert len(charges) == 5 assert type(charges[0]) == float assert -1.0 < charges[0] < 1.0 calc = Calculation(name='opt', molecule=methylchloride, method=method, keywords=opt_keywords) # If the calculation is not run with calc.run() then there should be no # input and the calc should raise that there is no input with pytest.raises(NoInputError): execute_calc(calc) os.remove('opt_orca.inp') os.chdir(here)
def test_xtb_calculation(): os.chdir(os.path.join(here, 'data')) XTB.available = True test_mol = Molecule(name='test_mol', smiles='O=C(C=C1)[C@@](C2NC3C=C2)([H])[C@@]3([H])C1=O') calc = Calculation(name='opt', molecule=test_mol, method=method, keywords=Config.XTB.keywords.opt) calc.run() assert os.path.exists('opt_xtb.xyz') is True assert os.path.exists('opt_xtb.out') is True assert len(calc.get_final_atoms()) == 22 assert calc.get_energy() == -36.990267613593 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.input.filename == 'opt_xtb.xyz' assert calc.output.filename == 'opt_xtb.out' with pytest.raises(NotImplementedError): calc.optimisation_nearly_converged() with pytest.raises(NotImplementedError): calc.get_imaginary_freqs() with pytest.raises(NotImplementedError): calc.get_normal_mode_displacements(4) charges = calc.get_atomic_charges() assert len(charges) == 22 assert all(-1.0 < c < 1.0 for c in charges) const_opt = Calculation(name='const_opt', molecule=test_mol, method=method, distance_constraints={(0, 1): 1.2539792}, cartesian_constraints=[0], keywords=Config.XTB.keywords.opt) const_opt.generate_input() assert os.path.exists('xcontrol_const_opt_xtb') os.remove('const_opt_xtb.xyz') os.remove('xcontrol_const_opt_xtb') os.remove('opt_xtb.xyz') os.chdir(here)
def get_charges(molecule): """ Get the partial atomic charges with XTB (tested with v. 6.2) will generate then trash a temporary directory :return: """ logger.info('Getting charges') try: from autode.calculation import Calculation from autode.wrappers.XTB import xtb from autode.exceptions import MethodUnavailable from autode.wrappers.keywords import SinglePointKeywords except ModuleNotFoundError: logger.error('autode not found. Calculations not available') raise RequiresAutodE # Run the calculation try: xtb_sp = Calculation(name=molecule.name + '_xtb_sp', molecule=molecule, method=xtb, n_cores=1, keywords=xtb.keywords.sp) xtb_sp.run() charges = xtb_sp.get_atomic_charges() except MethodUnavailable: logger.error('Could not calculate without an XTB install') return None if len(charges) == molecule.n_atoms: return charges else: logger.error('XTB failed to generate charges') return None
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)