Easy NEB restarts
by Andrew Peterson
The Nudged Elastic Band (NEB) method allows for the automated search for saddle points. While the technique works well, it can take many resubmissions to get it to converge. Most researchers will either change an index number in their script to change the filenames, or will have some code in their script that does this for them.
To automate this, we wrote a class compatibile with the ASE NEB method known as ReNEB
. The below script gives a framework for this, assuming you have existing endstates known as initial.traj
and final.traj
which have consistent atomic numbering, as in a standard NEB calculation.
from ase import io, Atoms
from ase.neb import interpolate
from pgroup.ase import ReNEB
initial = io.read('initial.traj')
final = io.read('final.traj')
images = [Atoms(initial) for _ in range(7)]
images[-1] = Atoms(final)
interpolate(images)
def set_calc(atoms, index):
"""Set any desired calculator here. index is used to label the
different internal images."""
calc = AnyCalculator(label='calc%02i' % index,
...)
atoms.set_calculator(calc)
def set_constraint(atoms):
"""Apply constraints to all images."""
constraints = [...]
atoms.set_constraint(constraints)
rneb = ReNEB(images, calcfxn=set_calc, constraintfxn=set_constraint)
rneb.run(fmax=0.05, fmax_climb=0.05)
The above script can then be submitted, without modification, over and over until the NEB converges. Notes:
-
You supply the module with functions which set the calculator and constraint, then the ReNEB class sets these to the images in your supplied or stored band (on the internal images only).
-
The band of images is set up at the beginning of the script. If the ReNEB class finds existing files (e.g., 'neb-03.traj') it will use the latest band from those instead, but set the calculator and constraint functions on those images.
-
Two
fmax
values are fed toReNEB
. It will run a normal NEB untilfmax
is reached, followed by a climbing-image version (CI-NEB) untilfmax_climb
is reached. Either can be set toNone
to have only one or the other.
Use with auto-resubmission module
For really hands-off operation, you can use this with our ReQueue
module: this will stop the job right before it is about to be killed by the batching system, then resubmit it to the queue. To use it, replace the rneb.run(...)
line with:
from pgroup.requeue import ReQueue
requeue = ReQueue(maxtime=24., checktime=0.5)
status = requeue(rneb.run, fmax=0.05, fmax_climb=0.05)
if status == 'time_elapsed':
import os
os.system('sbatch --begin=now+2minutes run.py')
The above ReQueue
parameters are set for a job walltime of 25 hours. 24 hours in, this would kill and re-submit your job, just an hour before the system was going to kill it for you.
Note: this page is a special case of Make any job re-submit itself.