예제 #1
0
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()
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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
예제 #6
0
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)
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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)
예제 #10
0
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)