def test_grad(): h2 = Molecule(name='h2', atoms=[Atom('H'), Atom('H', x=0.5)]) grad_calc = Calculation(name='h2_grad', molecule=h2, method=method, keywords=Config.MOPAC.keywords.grad) grad_calc.run() energy = grad_calc.get_energy() assert energy is not None gradients = grad_calc.get_gradients() assert gradients.shape == (2, 3) delta_r = 1E-5 h2_disp = Molecule(name='h2_disp', atoms=[Atom('H'), Atom('H', x=0.5 + delta_r)]) h2_disp.single_point(method) delta_energy = h2_disp.energy - energy # Ha] grad = delta_energy / delta_r # Ha A^-1 # Difference between the absolute and finite difference approximation assert np.abs(gradients[1, 0] - grad) < 1E-1 # Broken gradient file grad_calc.output.filename = 'h2_grad_broken.out' grad_calc.output.file_lines = open('h2_grad_broken.out', 'r').readlines() with pytest.raises(CouldNotGetProperty): _ = grad_calc.get_gradients()
def test_orca_optts_calculation(): methane = SolvatedMolecule(name='methane', smiles='C') methane.qm_solvent_atoms = [] calc = Calculation(name='test_ts_reopt_optts', molecule=methane, method=method, bond_ids_to_add=[(0, 1)], keywords=opt_keywords, other_input_block='%geom\n' 'Calc_Hess true\n' 'Recalc_Hess 40\n' 'Trust 0.2\n' 'MaxIter 100\nend') calc.run() assert os.path.exists('test_ts_reopt_optts_orca.inp') assert calc.get_normal_mode_displacements(mode_number=6) is not None assert calc.terminated_normally() assert calc.optimisation_converged() assert calc.optimisation_nearly_converged() is False assert len(calc.get_imaginary_freqs()) == 1 # Gradients should be an n_atom x 3 array gradients = calc.get_gradients() assert len(gradients) == 5 assert len(gradients[0]) == 3 assert -599.437 < calc.get_enthalpy() < -599.436 assert -599.469 < calc.get_free_energy() < -599.468
def test_mopac_opt_calculation(): calc = Calculation(name='opt', molecule=methylchloride, method=method, keywords=Config.MOPAC.keywords.opt) calc.run() assert os.path.exists('opt_mopac.mop') is True assert os.path.exists('opt_mopac.out') is True assert len(calc.get_final_atoms()) == 5 # Actual energy in Hartrees energy = Constants.eV2ha * -430.43191 assert energy - 0.0001 < calc.get_energy() < energy + 0.0001 assert calc.output.exists() assert calc.output.file_lines is not None assert calc.input.filename == 'opt_mopac.mop' assert calc.output.filename == 'opt_mopac.out' assert calc.terminated_normally() assert calc.optimisation_converged() is True with pytest.raises(CouldNotGetProperty): _ = calc.get_gradients() 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)
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 test_gradients(): h2 = Molecule(name='h2', atoms=[Atom('H'), Atom('H', x=1.0)]) calc = Calculation(name='h2_grad', molecule=h2, method=method, keywords=method.keywords.grad()) calc.run() h2.energy = calc.get_energy() delta_r = 1E-8 # Energy of a finite difference approximation h2_disp = Molecule(name='h2_disp', atoms=[Atom('H'), Atom('H', x=1.0 + delta_r)]) calc = Calculation(name='h2_disp', molecule=h2_disp, method=method, keywords=method.keywords.grad) calc.run() h2_disp.energy = calc.get_energy() delta_energy = h2_disp.energy - h2.energy # Ha grad = delta_energy / delta_r # Ha A^-1 calc = Calculation(name='h2_grad', molecule=h2, method=method, keywords=method.keywords.grad) calc.run() diff = calc.get_gradients()[1, 0] - grad # Ha A^-1 # Difference between the absolute and finite difference approximation assert np.abs(diff) < 1E-3
def test_gradients(): os.chdir(os.path.join(here, 'data', 'xtb')) h2 = Molecule(name='h2', atoms=[Atom('H'), Atom('H', x=1.0)]) h2.single_point(method) delta_r = 1E-5 h2_disp = Molecule(name='h2_disp', atoms=[Atom('H'), Atom('H', x=1.0 + delta_r)]) h2_disp.single_point(method) delta_energy = h2_disp.energy - h2.energy # Ha grad = delta_energy / delta_r # Ha A^-1 calc = Calculation(name='h2_grad', molecule=h2, method=method, keywords=method.keywords.grad) calc.run() diff = calc.get_gradients()[1, 0] - grad # Ha A^-1 # Difference between the absolute and finite difference approximation assert np.abs(diff) < 1E-5 # Older xtb version with open('gradient', 'w') as gradient_file: print( '$gradient\n' 'cycle = 1 SCF energy = -4.17404780397 |dE/dxyz| = 0.027866\n' '3.63797523123375 -1.13138130908142 -0.00032759661848 C \n' '5.72449332438353 -1.13197561185651 0.00028950521969 H \n' ' 2.94133258016711 0.22776472016180 -1.42078243039077 H \n' ' 2.94175598539510 -0.58111835182372 1.88747566982948 H \n' '2.94180792167968 -3.04156357656436 -0.46665514803992 H \n' '-1.7221823521705E-05 7.9930724499610E-05 -1.1737079840097E-04\n' ' 1.4116296505865E-02 -4.0359524399270E-05 3.9719638516747E-05\n' '-4.7199424681741E-03 9.0086220034949E-03 -9.4114548523723E-03\n' '-4.6956970257351E-03 3.6356853660431E-03 1.2558467871909E-02\n' ' -4.6834351884340E-03 -1.2683878569638E-02 -3.0693618596526E-03\n' '$end', file=gradient_file) calc = Calculation(name='methane', molecule=Molecule(name='methane', smiles='C'), method=method, keywords=method.keywords.grad) gradients = method.get_gradients(calc) assert gradients.shape == (5, 3) assert np.abs(gradients[0, 0]) < 1E-3 os.chdir(here)
def test_mp2_numerical_gradients(): calc = Calculation( name='tmp', molecule=Molecule(atoms=xyz_file_to_atoms('tmp_orca.xyz')), method=method, keywords=method.keywords.grad) calc.output.filename = 'tmp_orca.out' calc.output.file_lines = open(calc.output.filename, 'r').readlines() gradients = calc.get_gradients() assert len(gradients) == 6 expected = np.array([-0.00971201, -0.00773534, -0.02473580 ]) / Constants.a02ang assert np.linalg.norm(expected - gradients[0]) < 1e-6 # Test for different printing with numerical.. calc.output.filename = 'numerical_orca.out' calc.output.file_lines = open(calc.output.filename, 'r').readlines() gradients = calc.get_gradients() assert len(gradients) == 6 expected = np.array([0.012397372, 0.071726232, -0.070942743 ]) / Constants.a02ang assert np.linalg.norm(expected - gradients[0]) < 1e-6
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_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)