Ejemplo n.º 1
0
def test_get_ts_guess_1dscan():
    os.chdir(os.path.join(here, 'data'))

    fbond = FormingBond(atom_indexes=(1, 2), species=reac)
    fbond.final_dist = 0.7

    ts_guess = get_ts_guess_1d(name='H+H2_H2+H',
                               reactant=reac,
                               product=prod,
                               bond=fbond,
                               method=orca,
                               keywords=opt_keywords,
                               dr=0.06)

    assert ts_guess.n_atoms == 3

    # Peak in the PES is at r = 0.85 Å
    assert 0.84 < ts_guess.get_distance(1, 2) < 0.86

    assert os.path.exists('H+H2_H2+H.png')

    for filename in os.listdir(os.getcwd()):
        if filename.endswith(('.inp', '.png')):
            os.remove(filename)

    os.chdir(here)
Ejemplo n.º 2
0
def test_get_ts_guess_1dscan():

    fbond = FormingBond(atom_indexes=(1, 2), species=reac)
    fbond.final_dist = 0.7

    ts_guess = get_ts_guess_1d(name='H+H2_H2+H',
                               reactant=reac,
                               product=prod,
                               bond=fbond,
                               method=orca,
                               keywords=opt_keywords,
                               dr=0.06)

    assert ts_guess.n_atoms == 3

    # Peak in the PES is at r = 0.85 Å
    assert 0.84 < ts_guess.get_distance(1, 2) < 0.86
    assert os.path.exists('H+H2_H2+H.png')
    os.remove('H+H2_H2+H.png')
Ejemplo n.º 3
0
def test_removing_active_bonds():

    filepath = os.path.join(here, 'data', 'neb', 'co_complex.xyz')

    mol = Molecule(name='co_complex', atoms=xyz_file_to_atoms(filepath))

    bbond = BreakingBond(atom_indexes=(1, 2), species=mol)
    fbond = FormingBond(atom_indexes=(3, 1), species=mol)

    bonds = neb.active_bonds_no_rings(mol, fbonds=[fbond], bbonds=[bbond])

    # Should remove the breaking bond as it forms a ring with an already
    # present atom pair
    assert len(bonds) == 1
    assert isinstance(bonds[0], FormingBond)

    # Also check that the number of images to generate are somewhat reasonable
    n_images = neb.calc_n_images(fbonds=[fbond],
                                 bbonds=[bbond],
                                 average_spacing=0.1)
    assert 0 < n_images < 20
Ejemplo n.º 4
0
def test_bonds():

    h1 = Atom(atomic_symbol='H', x=0.0, y=0.0, z=0.0)
    h2 = Atom(atomic_symbol='H', x=0.0, y=0.0, z=0.7)
    h3 = Atom(atomic_symbol='H', x=0.0, y=0.0, z=1.7)

    hydrogen = Reactant(name='H2', atoms=[h1, h2], charge=0, mult=1)
    h = Reactant(name='H', atoms=[h3], charge=0, mult=2)

    reac = ReactantComplex(hydrogen, h)

    prod_h2 = Product(name='H2', atoms=[h1, h2], charge=0, mult=1)
    prod_h = Product(name='H', atoms=[h3], charge=0, mult=2)

    fbond = FormingBond(atom_indexes=(1, 2), species=reac)
    bbond = BreakingBond(atom_indexes=(0, 1), species=reac, reaction=Reaction(hydrogen, h, prod_h2, prod_h))

    assert fbond.curr_dist == 1.0
    assert 0.6 < fbond.final_dist < 0.8

    assert 2.0 < bbond.final_dist < 2.5
    assert bbond.curr_dist == 0.7
Ejemplo n.º 5
0
def test_get_ts_guess_2dscan():

    ch3cl_f = Reactant(name='CH3Cl_F-',
                       charge=-1,
                       mult=1,
                       atoms=[
                           Atom('F', -4.14292, -0.24015, 0.07872),
                           Atom('Cl', 1.63463, 0.09787, -0.02490),
                           Atom('C', -0.14523, -0.00817, 0.00208),
                           Atom('H', -0.47498, -0.59594, -0.86199),
                           Atom('H', -0.45432, -0.49900, 0.93234),
                           Atom('H', -0.56010, 1.00533, -0.04754)
                       ])

    ch3f_cl = Product(name='CH3Cl_F-',
                      charge=-1,
                      mult=1,
                      atoms=[
                          Atom('F', 1.63463, 0.09787, -0.02490),
                          Atom('Cl', -4.14292, -0.24015, 0.07872),
                          Atom('C', -0.14523, -0.00817, 0.00208),
                          Atom('H', -0.47498, -0.59594, -0.86199),
                          Atom('H', -0.45432, -0.49900, 0.93234),
                          Atom('H', -0.56010, 1.00533, -0.04754)
                      ])

    #         H                H
    #   F-   C--Cl     ->   F--C         Cl-
    #       H H               H H
    pes = pes_2d.PES2d(reactant=ReactantComplex(ch3cl_f),
                       product=ProductComplex(ch3f_cl),
                       r1s=np.linspace(4.0, 1.5, 9),
                       r1_idxs=(0, 2),
                       r2s=np.linspace(1.78, 4.0, 8),
                       r2_idxs=(1, 2))

    pes.calculate(name='SN2_PES', method=xtb, keywords=xtb.keywords.low_opt)

    assert pes.species[0, 1] is not None
    assert -13.13 < pes.species[0, 1].energy < -13.11
    assert pes.species.shape == (9, 8)
    assert pes.rs.shape == (9, 8)
    assert type(pes.rs[0, 1]) == tuple
    assert pes.rs[1, 1] == (np.linspace(4.0, 1.5,
                                        9)[1], np.linspace(1.78, 4.0, 8)[1])

    # Fitting the surface with a 2D polynomial up to order 3 in r1 and r2 i.e.
    #  r1^3r2^3
    pes.fit(polynomial_order=3)
    assert pes.coeff_mat is not None
    assert pes.coeff_mat.shape == (4, 4)  # Includes r1^0 etc.

    pes.print_plot(name='pes_plot')
    assert os.path.exists('pes_plot.png')
    os.remove('pes_plot.png')

    # Products should be made on this surface
    assert pes.products_made()

    # Get the TS guess from this surface calling all the above functions
    reactant = ReactantComplex(ch3cl_f)
    fbond = FormingBond(atom_indexes=(0, 2), species=reactant)
    fbond.final_dist = 1.5

    bbond = BreakingBond(atom_indexes=(1, 2),
                         species=reactant,
                         reaction=Reaction(ch3cl_f, ch3f_cl))
    bbond.final_dist = 4.0

    ts_guess = pes_2d.get_ts_guess_2d(reactant=reactant,
                                      product=ProductComplex(ch3f_cl),
                                      bond1=fbond,
                                      bond2=bbond,
                                      polynomial_order=3,
                                      name='SN2_PES',
                                      method=xtb,
                                      keywords=xtb.keywords.low_opt,
                                      dr=0.3)
    assert ts_guess is not None
    assert ts_guess.n_atoms == 6
    assert ts_guess.energy is None
    assert 1.9 < ts_guess.get_distance(0, 2) < 2.1
    assert 1.9 < ts_guess.get_distance(1, 2) < 2.0
Ejemplo n.º 6
0
def get_ts_guess_function_and_params(reaction, bond_rearr):
    """Get the functions (1dscan or 2dscan) and parameters required for the
    function for a TS scan

    Arguments:
        reaction (autode.reaction.Reaction):
        bond_rearr (autode.bond_rearrangement.BondRearrangement):

    Returns:
        (list): updated funcs and params list
    """
    name = str(reaction)
    scan_name = name

    r, p = reaction.reactant, reaction.product

    lmethod, hmethod = get_lmethod(), get_hmethod()

    # Bonds with initial and final distances
    bbonds = [BreakingBond(pair, r, reaction) for pair in bond_rearr.bbonds]
    scan_name += "_".join(str(bb) for bb in bbonds)

    fbonds = [FormingBond(pair, r) for pair in bond_rearr.fbonds]
    scan_name += "_".join(str(fb) for fb in fbonds)

    # Ideally use a transition state template, then only a single constrained
    # optimisation needs to be run...
    yield get_template_ts_guess, (r, p, bond_rearr,
                                  f'{name}_template_{bond_rearr}', hmethod)

    # Otherwise try a nudged elastic band calculation, don't use the low level
    # method if there are any metals..
    if not any(atom.label in metals for atom in r.atoms):
        yield get_ts_guess_neb, (r, p, lmethod, fbonds, bbonds,
                                 f'{name}_ll_neb_{bond_rearr}')

    # Always attempt a high-level NEB
    yield get_ts_guess_neb, (r, p, hmethod, fbonds, bbonds,
                             f'{name}_hl_neb_{bond_rearr}')

    # Otherwise run 1D or 2D potential energy surface scans to generate a
    # transition state guess cheap -> most expensive
    if len(bbonds) == 1 and len(fbonds) == 1 and reaction.type in (Substitution, Elimination):
        yield get_ts_guess_2d, (r, p, fbonds[0], bbonds[0], f'{scan_name}_ll2d',
                                lmethod, lmethod.keywords.low_opt)

        yield get_ts_guess_1d, (r, p, bbonds[0], f'{scan_name}_hl1d_bbond',
                                hmethod, hmethod.keywords.low_opt)

        yield get_ts_guess_1d, (r, p, bbonds[0], f'{scan_name}_hl1d_alt_bbond',
                                hmethod,  hmethod.keywords.opt)

    if len(bbonds) > 0 and len(fbonds) == 1:
        yield get_ts_guess_1d, (r, p, fbonds[0], f'{scan_name}_hl1d_fbond',
                                hmethod, hmethod.keywords.low_opt)

        yield get_ts_guess_1d, (r, p, fbonds[0], f'{scan_name}_hl1d_alt_fbond',
                                hmethod, hmethod.keywords.opt)

    if len(bbonds) >= 1 and len(fbonds) >= 1:
        for fbond in fbonds:
            for bbond in bbonds:

                yield get_ts_guess_2d, (r, p, fbond, bbond,
                                        f'{scan_name}_ll2d', lmethod,
                                        lmethod.keywords.low_opt)

                yield get_ts_guess_2d, (r, p, fbond, bbond,
                                        f'{scan_name}_hl2d', hmethod,
                                        hmethod.keywords.low_opt)

    if len(bbonds) == 1 and len(fbonds) == 0:

        yield get_ts_guess_1d, (r, p, bbonds[0], f'{scan_name}_hl1d', hmethod,
                                hmethod.keywords.low_opt)

        yield get_ts_guess_1d, (r, p, bbonds[0], f'{scan_name}_hl1d_alt',
                                hmethod, hmethod.keywords.opt)

    if len(fbonds) == 2:
        yield get_ts_guess_2d, (r, p, fbonds[0], fbonds[1],
                                f'{scan_name}_ll2d_fbonds', lmethod,
                                lmethod.keywords.low_opt)
        yield get_ts_guess_2d, (r, p, fbonds[0], fbonds[1],
                                f'{scan_name}_hl2d_fbonds', hmethod,
                                hmethod.keywords.low_opt)

    if len(bbonds) == 2:
        yield get_ts_guess_2d, (r, p, bbonds[0], bbonds[1],
                                f'{scan_name}_ll2d_bbonds', lmethod,
                                lmethod.keywords.low_opt)

        yield get_ts_guess_2d, (r, p, bbonds[0], bbonds[1],
                                f'{scan_name}_hl2d_bbonds', hmethod,
                                hmethod.keywords.low_opt)

    return None