def nudged_elastic_band(images, fmax=0.01, algo='BFGS', trajectory='path-neb.traj', final='neb.traj'): calc = cline.gen_active_calc() load1 = calc.size[0] master = calc.rank == 0 for image in images: image.calc = calc # calculate for the first and last images # (for more efficient ML) images[0].get_potential_energy() images[-1].get_potential_energy() # define and run NEB neb = NEB(images, allow_shared_calculator=True) Min = getattr(optimize, algo) dyn = Min(neb, trajectory=trajectory, master=master) dyn.run(fmax) load2 = calc.size[0] if master: print(f'\tTotal number of Ab initio calculations: {load2-load1}\n') # output if master: out = Trajectory(final, 'w') for image in images: image.get_potential_energy() if master: out.write(image)
def test(*args, r='::', o='test.traj'): if 'calculator' in cline.ARGS and cline.ARGS['calculator'] is not None: raise RuntimeError('set calculator = None in ARGS!') traj = Trajectory(o, 'w') calc = cline.gen_active_calc() for arg in args: data = [read(arg)] if (r is None or ':' not in r) else read(arg, r) for atoms in data: atoms.set_calculator(calc) atoms.get_forces() if calc.rank == 0: traj.write(atoms)
def init_model(atoms, samples=5, rattle=0.05, trajectory='init.traj'): """ atoms: ASE atoms samples: number of samples rattle: stdev for random displacements trajectory: traj file name """ calc = cline.gen_active_calc() master = calc.rank == 0 if master: traj = Trajectory(trajectory, 'w') for _ in range(samples): tmp = atoms.copy() tmp.rattle(rattle, rng=np.random) tmp.set_calculator(calc) tmp.get_potential_energy() if master: traj.write(tmp)
def relax(atoms, fmax=0.01, cell=False, mask=None, algo='BFGS', trajectory='relax.traj', rattle=0.02, clear_hist=True, confirm=True): """ atoms: ASE atoms fmax: maximum forces cell: if True, minimize stress mask: stress components for relaxation algo: algo from ase.optimize trajectory: traj file name rattle: rattle atoms at initial step clear_hist: clear optimizer histtory if ML model is updated confirm: if True, do ab initio for the last step """ calc = cline.gen_active_calc() load1 = calc.size[0] master = calc.rank == 0 atoms.rattle(rattle, rng=np.random) atoms.set_calculator(calc) # define and run relaxation dynamics if cell: filtered = UnitCellFilter(atoms, mask=mask) else: filtered = atoms Min = getattr(optimize, algo) dyn = Min(filtered, trajectory=trajectory, master=master) for _ in dyn.irun(fmax): if calc.updated and clear_hist: dyn.initialize() load2 = calc.size[0] # confirm: if calc.active and confirm: while True: load2 += 1 if calc.update_data(try_fake=False): calc.update(data=False) calc.results.clear() dyn.initialize() dyn.run(fmax=fmax) else: break ML = ('ML', calc.results['energy'], calc.results['forces']) Ab = ('Ab initio', *calc._test()) for method, energy, forces in [ML, Ab]: f_rms = np.sqrt(np.mean(forces**2)) f_max = abs(forces).max() report = f""" relaxation result ({method}): energy: {energy} force (rms): {f_rms} force (max): {f_max} """ if master: print(report) if master: print(f'\tTotal number of Ab initio calculations: {load2-load1}\n')
def md(atoms, dynamics='NPT', dt=None, tem=300., picos=100, bulk_modulus=None, stress=0., mask=None, iso=False, trajectory='md.traj', loginterval=1, append=False, rattle=0.0, tdamp=25, pdamp=100, friction=1e-3, ml_filter=0.8): """ atoms: ASE atoms dynamics: 'NPT' dt: time-step in fs tem: temperature in Kelvin picos: pico-seconds for md bulk_modulus: bulk_modulus for NPT simulations. if None, NVT is performed stress: external stress (GPa) for NPT mask: see ase.npt.NPT iso: if True, keep the shape constant trajectory: traj file name loginterval: for traj file append: append to traj file rattle: rattle atoms at initial step (recommended ~0.05) tdamp: temperature damping time (fs) pdamp: pressure damping time (fs) friction: for Langevin dynamics ml_filter: filters force discontinuities due to ML updates range(0, 1) """ calc = cline.gen_active_calc() atoms.rattle(rattle, rng=np.random) atoms.set_calculator(calc) atoms.get_potential_energy() init_velocities(atoms, tem) if dt is None: if (atoms.numbers == 1).any(): dt = 0.25 else: dt = 1. if ml_filter: md_atoms = FilterDeltas(atoms, shrink=ml_filter) else: md_atoms = atoms if dynamics.upper() == 'NPT': dyn = npt_dynamics(md_atoms, dt, tem, bulk_modulus, stress, mask, iso, trajectory, loginterval, append, tdamp, pdamp) elif dynamics.upper() == 'LANGEVIN': dyn = langevin_dynamics(md_atoms, dt, tem, friction, trajectory, loginterval, append) if calc.meta is not None: dyn.attach(calc.meta.update) steps = int(picos * 1000 / dt) if picos > 0 else -picos dyn.run(steps)