def test_opt_with_precon(atoms, forcefield_params): kw = dict(forcefield_params) kw.pop('vdws') precon = FF(**kw) opt = PreconLBFGS(atoms, use_armijo=True, precon=precon) opt.run(fmax=0.1) e = atoms.get_potential_energy() assert abs(e - ref_energy) < 0.01
def symmetrized_optimisation(at_init, filter): rng = np.random.RandomState(1) at = at_init.copy() at.calc = NoisyLennardJones(rng=rng) at_cell = filter(at) dyn = PreconLBFGS(at_cell, precon=None) print("Initial Energy", at.get_potential_energy(), at.get_volume()) dyn.run(steps=300, fmax=0.001) print("n_steps", dyn.get_number_of_steps()) print("Final Energy", at.get_potential_energy(), at.get_volume()) print("Final forces\n", at.get_forces()) print("Final stress\n", at.get_stress()) print("initial symmetry at 1e-6") di = check_symmetry(at_init, 1.0e-6, verbose=True) print("final symmetry at 1e-6") df = check_symmetry(at, 1.0e-6, verbose=True) return di, df
def do_lattice(bulk, elastic=True): tol = 1e-3 # max force tol for relaxation n_E_vs_V_steps = 10 # use one of the routines from utilities module to relax the initial # unit cell and atomic positions bulk = relax_atoms_cell(bulk, tol=tol, traj_file=None, symmetrize=True) print("relaxed bulk") ase.io.write(sys.stdout, bulk, format='extxyz') if elastic: # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w calc = bulk.get_calculator().calc bulk.set_calculator(calc) precon = Exp(3.0) opt = lambda atoms, **kwargs: PreconLBFGS( atoms, precon=precon, **kwargs) elastic_consts = matscipy.elasticity.fit_elastic_constants( bulk, symmetry='cubic', optimizer=opt) c11 = elastic_consts[0][0, 0] / GPa c12 = elastic_consts[0][0, 1] / GPa c44 = elastic_consts[0][3, 3] / GPa V0 = bulk.get_volume() E_vs_V = [] f = open("relaxed_E_vs_V_configs.xyz", "w") cell_scalings = np.linspace(0.90**(1.0 / 3.0), 1.1**(1.0 / 3.0), 30) for cell_scaling in cell_scalings: scaled_bulk = bulk.copy() scaled_bulk.set_calculator(bulk.get_calculator()) scaled_bulk.set_cell(scaled_bulk.get_cell() * cell_scaling, scale_atoms=True) scaled_bulk = relax_atoms_cell(scaled_bulk, tol=tol, traj_file=None, constant_volume=True, method='fire', symmetrize=True) # evaluate(scaled_bulk) ase.io.write(f, scaled_bulk, format='extxyz') E_vs_V.insert(0, (scaled_bulk.get_volume() / len(scaled_bulk), scaled_bulk.get_potential_energy() / len(bulk))) for (V, E) in E_vs_V: print("EV_final ", V, E) if elastic: return (c11, c12, c44, E_vs_V) else: return (E_vs_V)
def relax_atoms(atoms, tol=1e-3, method='lbfgs_precon', max_steps=1000, traj_file=None, **kwargs): import model atoms.set_calculator(model.calculator) if hasattr(model, 'Optimizer'): method = 'model_optimizer' opt = model.Optimizer(atoms) opt.run(tol, max_steps) elif method.startswith('lbfgs') or method == 'fire' or method == 'cg_n': if method == 'lbfgs_ASE': from ase.optimize import LBFGS opt = LBFGS(atoms, **kwargs) elif method == 'cg_n': from quippy import Minim opt = Minim(atoms, relax_positions=True, relax_cell=False, method='cg_n') else: from ase.optimize.precon.precon import Exp from ase.optimize.precon.lbfgs import PreconLBFGS precon = None if method.endswith('precon'): precon = Exp(3.0, recalc_mu=True) if method.startswith('lbfgs'): opt = PreconLBFGS(atoms, precon=precon, **kwargs) else: opt = FIRE(atoms, **kwargs) if traj_file is not None and method != 'cg_n': traj = open(traj_file, 'w') def write_trajectory(): write(traj, atoms, format='extxyz') opt.attach(write_trajectory) opt.run(tol, max_steps) try: traj.close() except: pass else: raise ValueError('unknown method %s!' % method) return atoms
if vdw_list[i, j]: vdws.append( VdW(atomi=i, atomj=j, epsilonij=vdw_epsilonij, rminij=vdw_rminij)) # set up ForceField calculator calc = ForceField(morses=morses, angles=angles, dihedrals=dihedrals, vdws=vdws) a1 = a.copy() a1.set_calculator(calc) a1.rattle(0.05) # geometry optimisation without preconditioner opt = PreconLBFGS(a1, use_armijo=True, precon='ID') opt.run(fmax=0.1) e1 = a1.get_potential_energy() a2 = a.copy() a2.set_calculator(calc) a2.rattle(0.05) # geometry optimisation with FF based preconditioner precon = FF(morses=morses, angles=angles, dihedrals=dihedrals) opt = PreconLBFGS(a2, use_armijo=True, precon=precon) opt.run(fmax=0.1) e2 = a2.get_potential_energy() print(e1, e2)
def test_opt_no_precon(atoms): opt = PreconLBFGS(atoms, use_armijo=True, precon='ID') opt.run(fmax=0.1) e = atoms.get_potential_energy() assert abs(e - ref_energy) < 0.01
def relax_atoms_cell(atoms, tol=1e-3, stol=None, method='lbfgs_precon', max_steps=100, mask=None, traj_file=None, hydrostatic_strain=False, constant_volume=False, precon_apply_positions=True, precon_apply_cell=True, symmetrize=False, **kwargs): import model #print "relax_atoms_cell using method",method if symmetrize: atoms.set_calculator(SymmetrizedCalculator(model.calculator, atoms)) else: atoms.set_calculator(model.calculator) ## print "relax_atoms_cell initial e ", atoms.get_potential_energy() ## print "relax_atoms_cell initial f ", atoms.get_forces() ## print "relax_atoms_cell initial s ", atoms.get_stress() if hasattr(model, 'Optimizer'): method = 'model_optimizer' if method != 'cg_n': atoms = UnitCellFilter(atoms, mask=mask, hydrostatic_strain=hydrostatic_strain, constant_volume=constant_volume) if method.startswith('lbfgs') or method == 'fire' or method == 'cg_n': if method == 'cg_n': from quippy import Minim, fzeros atoms.info['Minim_Hydrostatic_Strain'] = hydrostatic_strain atoms.info['Minim_Constant_Volume'] = constant_volume if mask is not None: atoms.info['Minim_Lattice_Fix'] = fzeros((3, 3)) if not mask[0]: atoms.info['Minim_Lattice_Fix'][1, 1] = 1.0 if not mask[1]: atoms.info['Minim_Lattice_Fix'][2, 2] = 1.0 if not mask[2]: atoms.info['Minim_Lattice_Fix'][3, 3] = 1.0 if not mask[3]: atoms.info['Minim_Lattice_Fix'][1, 2] = 1.0 atoms.info['Minim_Lattice_Fix'][2, 1] = 1.0 if not mask[4]: atoms.info['Minim_Lattice_Fix'][2, 3] = 1.0 atoms.info['Minim_Lattice_Fix'][3, 2] = 1.0 if not mask[5]: atoms.info['Minim_Lattice_Fix'][1, 3] = 1.0 atoms.info['Minim_Lattice_Fix'][3, 1] = 1.0 opt = Minim(atoms, relax_positions=True, relax_cell=True, method='cg_n') else: from ase.optimize.precon.precon import Exp from ase.optimize.precon.lbfgs import PreconLBFGS precon = None if method.endswith('precon'): precon = Exp(3.0, apply_positions=precon_apply_positions, apply_cell=precon_apply_cell, recalc_mu=True) if method.startswith('lbfgs'): opt = PreconLBFGS(atoms, precon=precon, **kwargs) else: opt = FIRE(atoms, **kwargs) if traj_file is not None: traj = open(traj_file, 'w') def write_trajectory(): try: write(traj, atoms.atoms, format='extxyz') except: write(traj, atoms, format='extxyz') opt.attach(write_trajectory) if method != 'cg_n' and isinstance(opt, PreconLBFGS): opt.run(tol, max_steps, smax=stol) else: opt.run(tol, max_steps) if traj_file is not None: traj.close() elif method == 'model_optimizer': opt = model.Optimizer(atoms.atoms) opt.run() else: raise ValueError('unknown method %s!' % method) if isinstance(atoms, UnitCellFilter): return atoms.atoms else: return atoms
def do_lattice(bulk, use_precon=True, elastic=True, tol=1.0e-3): print "unrelaxed bulk" ase.io.write(sys.stdout, bulk, format='extxyz') # use one of the routines from utilities module to relax the initial # unit cell and atomic positions if use_precon: bulk = relax_atoms_cell(bulk, tol=tol, traj_file="bulk.relax.extxyz", symmetrize=True) else: bulk = relax_atoms_cell(bulk, tol=tol, traj_file=None, method='cg_n', symmetrize=True) print "relaxed bulk" ase.io.write(sys.stdout, bulk, format='extxyz') print "calculating elastic constants" precon = None if use_precon: precon = Exp(3.0) opt = lambda atoms, **kwargs: PreconLBFGS(atoms, precon=precon, **kwargs) if elastic: # reset calculator to non-symmetrized one (not optimal, but would otherwise need to have optimizer used by fit_elastic_constants to reset symmetry for each relaxation):w bulk.set_calculator(model.calculator) try: elastic_consts = matscipy.elasticity.fit_elastic_constants( bulk, symmetry='tetragonal_high', optimizer=opt, logfile=sys.stdout) except RuntimeError: # fallback on FIRE if we get a linesearch failure with LBFGS opt = FIRE elastic_consts = matscipy.elasticity.fit_elastic_constants( bulk, symmetry='tetragonal_high', optimizer=opt, logfile=sys.stdout) c11 = elastic_consts[0][0, 0] / GPa c33 = elastic_consts[0][2, 2] / GPa c12 = elastic_consts[0][0, 1] / GPa c13 = elastic_consts[0][0, 2] / GPa c44 = elastic_consts[0][3, 3] / GPa c66 = elastic_consts[0][5, 5] / GPa print "calculating E vs. V" V0 = bulk.get_volume() dV = bulk.get_volume() * 0.025 E_vs_V = [] scaled_bulk = bulk.copy() print "bulk going into E vs. V" ase.io.write(sys.stdout, scaled_bulk, format='extxyz') f = open("relaxed_E_vs_V_configs.xyz", "w") scaled_bulk = bulk.copy() constraints = [] # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int) # scaled_bulk.arrays["move_mask_3"][:,0] = 1 # for i in range(len(scaled_bulk)): # constraints.append(FixedLine_forces_only(i, (0.0, 0.0, 1.0))) # scaled_bulk.set_constraint(constraints) for i in range(0, -5 - 1, -1): print "doing volume step", i vcur = scaled_bulk.get_volume() scaled_bulk.set_cell(scaled_bulk.get_cell() * ((V0 + i * dV) / vcur)**(1.0 / 3.0), scale_atoms=True) try: scaled_bulk = relax_atoms_cell(scaled_bulk, tol=tol, traj_file=None, constant_volume=True, method='cg_n', symmetrize=True, max_steps=500) except: break print "done relaxing step", i ase.io.write(f, scaled_bulk, format='extxyz') f.flush() E_vs_V.insert(0, (scaled_bulk.get_volume() / len(bulk), scaled_bulk.get_potential_energy() / len(bulk))) evaluate(scaled_bulk) print "done evaluate step", i print "EV ", i, scaled_bulk.get_volume( ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress() scaled_bulk = bulk.copy() # scaled_bulk.arrays["move_mask_3"] = np.zeros((len(scaled_bulk),3), dtype=np.int) # scaled_bulk.arrays["move_mask_3"][:,0] = 1 # scaled_bulk.set_constraint(constraints) for i in range(1, 6 + 1): print "doing volume step", i vcur = scaled_bulk.get_volume() scaled_bulk.set_cell(scaled_bulk.get_cell() * ((V0 + i * dV) / vcur)**(1.0 / 3.0), scale_atoms=True) try: scaled_bulk = relax_atoms_cell(scaled_bulk, tol=tol, traj_file=None, constant_volume=True, method='cg_n', symmetrize=True, max_steps=500) except: break print "done relaxing step", i ase.io.write(f, scaled_bulk, format='extxyz') f.flush() E_vs_V.append((scaled_bulk.get_volume() / len(bulk), scaled_bulk.get_potential_energy() / len(bulk))) evaluate(scaled_bulk) print "done evaluate step", i print "EV ", i, scaled_bulk.get_volume( ), scaled_bulk.get_potential_energy(), scaled_bulk.get_stress() for (V, E) in E_vs_V: print "EV_final ", V, E if elastic: return (c11, c33, c12, c13, c44, c66, E_vs_V) else: return (E_vs_V)
# create list of van der Waals interactions for i in range(len(a)): for j in range(i + 1, len(a)): if vdw_list[i, j]: vdws.append(VdW(atomi=i, atomj=j, epsilonij=vdw_epsilonij, rminij=vdw_rminij)) # set up ForceField calculator calc = ForceField(morses=morses, angles=angles, dihedrals=dihedrals, vdws=vdws) a1 = a.copy() a1.set_calculator(calc) a1.rattle(0.05) # geometry optimisation without preconditioner opt = PreconLBFGS(a1, use_armijo=True, precon='ID') opt.run(fmax=0.1) e1 = a1.get_potential_energy() a2 = a.copy() a2.set_calculator(calc) a2.rattle(0.05) # geometry optimisation with FF based preconditioner precon = FF(morses=morses, angles=angles, dihedrals=dihedrals, use_pyamg=False) opt = PreconLBFGS(a2, use_armijo=True, precon=precon) opt.run(fmax=0.1) e2 = a2.get_potential_energy() print(e1, e2)