Beispiel #1
0
def test_neb_methods(method, optimizer, precon, optmethod, ref_vacancy,
                     setup_images):
    # unpack the reference result
    Ef_ref, dE_ref, saddle_ref = ref_vacancy

    # now relax the MEP for comparison
    images, _, _ = setup_images

    fmax_history = []

    def save_fmax_history(mep):
        fmax_history.append(mep.get_residual())

    k = 0.1
    if precon == 'Exp':
        k = 0.01
    mep = NEB(images, k=k, method=method, precon=precon)

    if optmethod is not None:
        opt = optimizer(mep, method=optmethod)
    else:
        opt = optimizer(mep)
    opt.attach(save_fmax_history, 1, mep)
    opt.run(fmax=1e-2)

    nebtools = NEBTools(images)
    Ef, dE = nebtools.get_barrier(fit=False)
    print(f'{method},{optimizer.__name__},{precon} '
          f'=> Ef = {Ef:.3f}, dE = {dE:.3f}')

    forcefit = fit_images(images)

    output_dir = os.path.dirname(__file__)
    with open(
            f'{output_dir}/MEP_{method}_{optimizer.__name__}_{optmethod}'
            f'_{precon}.json', 'w') as f:
        json.dump(
            {
                'fmax_history': fmax_history,
                'method': method,
                'optmethod': optmethod,
                'precon': precon,
                'optimizer': optimizer.__name__,
                'path': forcefit.path,
                'energies': forcefit.energies.tolist(),
                'fit_path': forcefit.fit_path.tolist(),
                'fit_energies': forcefit.fit_energies.tolist(),
                'lines': np.array(forcefit.lines).tolist(),
                'Ef': Ef,
                'dE': dE
            }, f)

    centre = 2  # we have 5 images total, so central image has index 2
    vdiff, _ = find_mic(images[centre].positions - saddle_ref.positions,
                        images[centre].cell)
    print(f'Ef error {Ef - Ef_ref} dE error {dE - dE_ref} '
          f'position error at saddle {abs(vdiff).max()}')
    assert abs(Ef - Ef_ref) < 1e-2
    assert abs(dE - dE_ref) < 1e-2
    assert abs(vdiff).max() < 1e-2
Beispiel #2
0
 def neb(self):
     from ase.utils.forcecurve import fit_images
     try:
         forcefit = fit_images(self.images)
     except Exception as err:
         self.bad_plot(err, _('Images must have energies and forces, '
                              'and atoms must not be stationary.'))
     else:
         self.pipe('neb', forcefit)
Beispiel #3
0
def test_integrate_forces(setup_images):
    images, _, _ = setup_images
    forcefit = fit_images(images)

    neb = NEB(images)
    spline_points = 1000  # it is the default value
    s, E, F = neb.integrate_forces(spline_points=spline_points)
    # check the difference between initial and final images
    np.testing.assert_allclose(E[0] - E[-1],
                               forcefit.energies[0] - forcefit.energies[-1],
                               atol=1.0e-10)
    # assert the maximum Energy value is in the middle
    assert np.argmax(E) == spline_points // 2 - 1
    # check the maximum values (barrier value)
    # tolerance value is rather high since the images are not relaxed
    np.testing.assert_allclose(E.max(), forcefit.energies.max(), rtol=2.5e-2)
Beispiel #4
0
 def get_barrier(self, fit=True, raw=False):
     """Returns the barrier estimate from the NEB, along with the
     Delta E of the elementary reaction. If fit=True, the barrier is
     estimated based on the interpolated fit to the images; if
     fit=False, the barrier is taken as the maximum-energy image
     without interpolation. Set raw=True to get the raw energy of the
     transition state instead of the forward barrier."""
     forcefit = fit_images(self.images)
     energies = forcefit.energies
     fit_energies = forcefit.fit_energies
     dE = energies[-1] - energies[0]
     if fit:
         barrier = max(fit_energies)
     else:
         barrier = max(energies)
     if raw:
         barrier += self.images[0].get_potential_energy()
     return barrier, dE
Beispiel #5
0
 def plot_band(self, ax=None):
     """Plots the NEB band on matplotlib axes object 'ax'. If ax=None
     returns a new figure object."""
     forcefit = fit_images(self.images)
     ax = forcefit.plot(ax=ax)
     return ax.figure
Beispiel #6
0
 def get_fit(self):
     return fit_images(self.images)