def test_Pt_stress_cellopt(factory, pt_eam_potential_file): params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pt_eam_potential_file)] # XXX Should it accept Path objects? Yes definitely for files. with factory.calc(specorder=['Pt'], files=[str(pt_eam_potential_file)], **params) as calc: rng = np.random.RandomState(17) atoms = bulk('Pt') * (2, 2, 2) atoms.rattle(stdev=0.1) atoms.cell += 2 * rng.rand(3, 3) atoms.calc = calc assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) opt = BFGS(ExpCellFilter(atoms), trajectory='opt.traj') for i, _ in enumerate(opt.irun(fmax=0.001)): pass cell1_ref = np.array( [[0.16524, 3.8999, 3.92855], [4.211015, 0.634928, 5.047811], [4.429529, 3.293805, 0.447377]] ) assert_allclose(np.asarray(atoms.cell), cell1_ref, atol=3e-4, rtol=3e-4) assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) assert i < 80, 'Expected 59 iterations, got many more: {}'.format(i)
def test_dftb_relax_bulk(): import os from ase.test import require from ase.test.testsuite import datafiles_directory from ase.build import bulk from ase.calculators.dftb import Dftb from ase.optimize import QuasiNewton from ase.constraints import ExpCellFilter require('dftb') os.environ['DFTB_PREFIX'] = datafiles_directory calc = Dftb(label='dftb', kpts=(3,3,3), Hamiltonian_SCC='Yes') atoms = bulk('Si') atoms.set_calculator(calc) ecf = ExpCellFilter(atoms) dyn = QuasiNewton(ecf) dyn.run(fmax=0.01) e = atoms.get_potential_energy() assert abs(e - -73.150819) < 1., e
def relax(atoms, cellbounds=None): # Performs a variable-cell relaxation of the structure calc = EMT() atoms.set_calculator(calc) converged = False niter = 0 while not converged and niter < 10: if cellbounds is not None: cell = atoms.get_cell() if not cellbounds.is_within_bounds(cell): niggli_reduce(atoms) cell = atoms.get_cell() if not cellbounds.is_within_bounds(cell): # Niggli reduction did not bring the unit cell # within the specified bounds; this candidate should # be discarded so we set an absurdly high energy finalize(atoms, 1e9) return ecf = ExpCellFilter(atoms) dyn = FIRE(ecf, maxmove=0.2, logfile=None, trajectory=None) dyn.run(fmax=1e-3, steps=100) converged = dyn.converged() niter += 1 dyn = FIRE(atoms, maxmove=0.2, logfile=None, trajectory=None) dyn.run(fmax=1e-2, steps=100) e = atoms.get_potential_energy() f = atoms.get_forces() s = atoms.get_stress() finalize(atoms, energy=e, forces=f, stress=s)
def test_socketio_espresso(factory): name = factory.name if name == 'abinit': factory.require_version('9.4') atoms = bulk('Si') exe = factory.factory.executable unixsocket = f'ase_test_socketio_{name}' espresso = factory.calc( kpts=[2, 2, 2], ) template = commands[name] command = template.format(exe=exe, unixsocket=unixsocket) espresso.command = command atoms.rattle(stdev=.2, seed=42) with BFGS(ExpCellFilter(atoms)) as opt, \ pytest.warns(UserWarning, match='Subprocess exited'), \ SocketIOCalculator(espresso, unixsocket=unixsocket) as calc: atoms.calc = calc for _ in opt.irun(fmax=0.05): e = atoms.get_potential_energy() fmax = max(np.linalg.norm(atoms.get_forces(), axis=0)) print(e, fmax)
def _optimize(self): """Perform an optimization.""" self._atoms.set_momenta(np.zeros(self._atoms.get_momenta().shape)) ecf = ExpCellFilter(self._atoms) opt = self._optimizer(ecf, trajectory='qn%05i.traj' % self._counter, logfile='qn%05i.log' % self._counter) self._log('msg', 'Optimization: qn%05i' % self._counter) opt.run(fmax=self._fmax) self._log('ene')
def relax_poscar(poscar_file, calc, fmax=1e-4): atoms = read(poscar_file) atoms.set_calculator(calc) ecf = ExpCellFilter(atoms) opt = BFGS(ecf) opt.run(fmax=fmax) write_vasp('POSCAR-opt', atoms, vasp5=True) return
def test_dftb_relax_bulk(dftb_factory): calc = dftb_factory.calc(label='dftb', kpts=(3, 3, 3), Hamiltonian_SCC='Yes') atoms = bulk('Si') atoms.calc = calc ecf = ExpCellFilter(atoms) with QuasiNewton(ecf) as dyn: dyn.run(fmax=0.01) e = atoms.get_potential_energy() assert abs(e - -73.150819) < 1., e
def test_Pt_stress_cellopt(): import numpy as np from numpy.testing import assert_allclose from ase.calculators.lammpsrun import LAMMPS from ase.build import bulk from ase.test.eam_pot import Pt_u3 from ase.constraints import ExpCellFilter from ase.optimize import BFGS # (For now) reuse eam file stuff from other lammps test: pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] with LAMMPS(specorder=['Pt'], files=[pot_fn], **params) as calc: rng = np.random.RandomState(17) atoms = bulk('Pt') * (2, 2, 2) atoms.rattle(stdev=0.1) atoms.cell += 2 * rng.rand(3, 3) atoms.calc = calc assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) opt = BFGS(ExpCellFilter(atoms), trajectory='opt.traj') for i, _ in enumerate(opt.irun(fmax=0.001)): pass cell1_ref = np.array([[0.16524, 3.8999, 3.92855], [4.211015, 0.634928, 5.047811], [4.429529, 3.293805, 0.447377]]) assert_allclose(np.asarray(atoms.cell), cell1_ref, atol=3e-4, rtol=3e-4) assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) assert i < 80, 'Expected 59 iterations, got many more: {}'.format(i)
def _optimize(self): """Perform an optimization.""" # del self._atoms.constraints self._atoms.set_momenta(np.zeros(self._atoms.get_momenta().shape)) geo_opt = FIRE(self._atoms) geo_opt.run(fmax=self._fmax2) ecf = ExpCellFilter(self._atoms) opt = self._optimizer(ecf, trajectory='qn%05i.traj' % self._counter, logfile='qn%05i.log' % self._counter) self._log('msg', 'Optimization: qn%05i' % self._counter) opt.run(fmax=self._fmax) self._log('ene') # del self._atoms.constraints tri_mat, coord_transform = convert_cell_4NPT(self._atoms.get_cell()) self._atoms.set_positions([np.matmul(coord_transform, position) for position in self._atoms.get_positions()]) self._atoms.set_cell(tri_mat.transpose())
def opt_lammpslib(struc, lmp, parameters=None, mask=None, logfile='-', path='tmp', calc_type=None, lmp_file=None, molecule=False, method='FIRE', fmax=0.01, opt_cell=False, a=0.1, steps=500): """ mask: [1, 1, 1, 1, 1, 1], a, b, c, alpha, beta, gamma [1, 1, 0, 0, 0, 1] """ if lmp_file is not None: lammps = LAMMPSlib(lmp=lmp, lmp_file=lmp_file, log_file='lammps.log', \ molecule=molecule, path=path) elif calc_type is not None: lammps = LAMMPSlib(lmp=lmp, lmpcmds=parameters, calc_type=calc_type, \ log_file='lammps.log', molecule=molecule, path=path) else: lammps = LAMMPSlib(lmp=lmp, lmpcmds=parameters, log_file='lammps.log', \ molecule=molecule, path=path) #check_symmetry(si, 1.0e-6, verbose=True) struc.set_calculator(lammps) struc.set_constraint(FixSymmetry(struc)) if opt_cell: ecf = ExpCellFilter(struc, mask) if method == 'FIRE': dyn = FIRE(ecf, logfile=logfile, a=a) else: dyn = LBFGS(ecf, logfile=logfile) else: if method == 'FIRE': dyn = FIRE(struc, logfile=logfile) else: dyn = LBFGS(struc, logfile=logfile) dyn.run(fmax=fmax, steps=steps) return struc
def test_socketio_python(): from ase.build import bulk from ase.constraints import ExpCellFilter from ase.optimize import BFGS atoms = bulk('Au') * (2, 2, 2) atoms.rattle(stdev=0.05) fmax = 0.01 atoms.cell += np.random.RandomState(42).rand(3, 3) * 0.05 client = PySocketIOClient(EMT) pid = os.getpid() with SocketIOCalculator(launch_client=client, unixsocket=f'ase-python-{pid}') as atoms.calc: with BFGS(ExpCellFilter(atoms)) as opt: opt.run(fmax=fmax) forces = atoms.get_forces() assert np.linalg.norm(forces, axis=0).max() < fmax
def test_unitcellfilterpressure(): a0 = bulk('Cu', cubic=True) # perturb the atoms s = a0.get_scaled_positions() s[:, 0] *= 0.995 a0.set_scaled_positions(s) # perturb the cell a0.cell[...] += np.random.uniform(-1e-2, 1e-2, size=9).reshape((3, 3)) atoms = a0.copy() atoms.calc = LennardJones() ucf = UnitCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all derivatives f, fn = gradient_test(ucf) assert abs(f - fn).max() < 1e-6 opt = FIRE(ucf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1 atoms = a0.copy() atoms.calc = LennardJones() ecf = ExpCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all deritatives f, fn = gradient_test(ecf) assert abs(f - fn).max() < 1e-6 opt = LBFGSLineSearch(ecf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1
def test_precon(): cu0 = bulk("Cu") * (2, 2, 2) lj = LennardJones(sigma=cu0.get_distance(0,1)) cu = cu0.copy() cu.set_cell(1.2*cu.get_cell()) cu.calc = lj ucf = UnitCellFilter(cu, constant_volume=True) opt = PreconLBFGS(ucf, precon=Exp(mu=1.0, mu_c=1.0)) opt.run(fmax=1e-3) assert abs(np.linalg.det(cu.cell)/np.linalg.det(cu0.cell) - 1.2**3) < 1e-3 # EcpCellFilter allows relaxing to lower tolerance cu = cu0.copy() cu.set_cell(1.2*cu.get_cell()) cu.calc = lj ecf = ExpCellFilter(cu, constant_volume=True) opt = PreconLBFGS(ecf, precon=Exp(mu=1.0, mu_c=1.0)) opt.run(fmax=1e-3) assert abs(np.linalg.det(cu.cell)/np.linalg.det(cu0.cell) - 1.2**3) < 1e-7
def test_gulp_opt(): import numpy as np from ase.calculators.gulp import GULP from ase.optimize import BFGS from ase.build import molecule, bulk from ase.constraints import ExpCellFilter # GULP optmization test atoms = molecule('H2O') atoms1 = atoms.copy() atoms1.calc = GULP(library='reaxff.lib') with BFGS(atoms1) as opt1: opt1.run(fmax=0.005) atoms2 = atoms.copy() calc2 = GULP(keywords='opti conp', library='reaxff.lib') with calc2.get_optimizer(atoms2) as opt2: opt2.run() print(np.abs(opt1.atoms.positions - opt2.atoms.positions)) assert np.abs(opt1.atoms.positions - opt2.atoms.positions).max() < 1e-5 # GULP optimization test using stress atoms = bulk('Au', 'bcc', a=2.7, cubic=True) atoms1 = atoms.copy() atoms1.calc = GULP(keywords='conp gradient stress_out', library='reaxff_general.lib') atoms1f = ExpCellFilter(atoms1) with BFGS(atoms1f) as opt1: opt1.run(fmax=0.005) atoms2 = atoms.copy() calc2 = GULP(keywords='opti conp', library='reaxff_general.lib') with calc2.get_optimizer(atoms2) as opt2: opt2.run() print(np.abs(opt1.atoms.positions - opt2.atoms.positions)) assert np.abs(opt1.atoms.positions - opt2.atoms.positions).max() < 1e-5
def optimize(atoms, sym=True, box=False, method='FIRE', fmax=0.01, steps=1000, logfile='ase.log'): if sym: atoms.set_constraint(FixSymmetry(atoms)) if box: ecf = ExpCellFilter(atoms) if method == 'FIRE': dyn = FIRE(ecf, logfile=logfile) else: dyn = LBFGS(ecf, logfile=logfile) else: if method == 'FIRE': dyn = FIRE(atoms, logfile=logfile) else: dyn = FIRE(atoms, logfile=logfile) dyn.run(fmax=fmax, steps=steps) atoms.set_constraint() return atoms
os.environ['DFTB_PREFIX'] = './' # Coordinates taken from the following publication: # Borlido et al., "The ground state of two-dimensional silicon", # 2D Mater. 5, 035010 (2018), doi:10.1088/2053-1583/aab9ea # and reoptimized with GPAW (LDA, 400 eV plane wave basis) atoms = Atoms('Si10', pbc=True, cell=(6.3245948276063171, 7.3351795905906787, 15., 90., 90., 90.), positions=[[2.5238234215085167, 1.8915376909714172, 7.5000000000042730], [4.4402893598836890, 1.8913405945624528, 8.8460149135358996], [1.2984521401199047, 3.8644391832367875, 7.5000000000030678], [2.1934070307608962, 5.5591598065851038, 6.1539843200547191], [4.4402893598687605, 1.8913405945582829, 6.1539850864607581], [2.1934070307611422, 5.5591598065878962, 8.8460156799451646], [5.3352644364352750, 0.1966184137746097, 7.4999999999998295], [1.2984323446246357, 7.2538814320204086, 7.4999999999998987], [5.3352446040859824, 3.5860618244812916, 7.4999999999982716], [4.1098722380006052, 5.5589627502960530, 7.4999999999981020]]) calc = DftbPlusCalculator(atoms, kpts=(4, 3, 1), use_spline=True, maximum_angular_momenta={'Si': 1}) atoms.set_calculator(calc) atoms.set_calculator(calc) # Local geometry optimization ecf = ExpCellFilter(atoms, mask=(1, 1, 0, 0, 0, 1)) dyn = BFGS(ecf, logfile='-', trajectory='opt_zigzag_dumbbell.traj') dyn.run(fmax=0.01) write('relaxed_zigzag_dumbbell.traj', atoms)
def relax_config(atoms, calculator, relax_pos, relax_cell, tol=1e-3, method='lbfgs', max_steps=200, traj_file=None, constant_volume=False, refine_symmetry_tol=None, keep_symmetry=False, strain_mask=None, config_label=None, from_base_model=False, save_config=False, fix_cell_dependence=False, applied_P=0.0, **kwargs): # get from base model if requested #import model if from_base_model: if config_label is None: raise ValueError( 'from_base_model is set but no config_label provided') try: base_run_file = os.path.join( '..', base_run_root, base_run_root + '-' + config_label + '-relaxed.xyz') atoms_in = read(base_run_file, format='extxyz') # set positions from atoms_in rescaling to match current cell saved_cell = atoms.get_cell().copy() atoms.set_cell(atoms_in.get_cell()) atoms.set_positions(atoms_in.get_positions()) atoms.set_cell(saved_cell, scale_atoms=True) print("relax_config read config from ", base_run_file) except: try: print("relax_config failed to read base run config from ", base_run_root + '-' + config_label + '-relaxed.xyz') except: print("relax_config failed to determined base_run_root") print("relax_config symmetry before refinement at default tol 1.0e-6") check_symmetry(atoms, 1.0e-6, verbose=True) if refine_symmetry_tol is not None: refine_symmetry(atoms, refine_symmetry_tol) print("relax_config symmetry after refinement") check_symmetry(atoms, refine_symmetry_tol, verbose=True) if keep_symmetry: print("relax_config trying to maintain symmetry") atoms.set_constraint(FixSymmetry(atoms)) atoms.set_calculator(calculator) # if needed, fix cell dependence before running # if fix_cell_dependence and hasattr(model, "fix_cell_dependence"): # model.fix_cell_dependence(atoms) if method == 'lbfgs' or method == 'sd2': if 'move_mask' in atoms.arrays: atoms.set_constraint( FixAtoms(np.where(atoms.arrays['move_mask'] == 0)[0])) if relax_cell: atoms_cell = ExpCellFilter(atoms, mask=strain_mask, constant_volume=constant_volume, scalar_pressure=applied_P * GPa) else: atoms_cell = atoms atoms.info["n_minim_iter"] = 0 if method == 'sd2': (traj, run_stat) = sd2_run("", atoms_cell, tol, lambda i: sd2_converged(i, atoms_cell, tol), max_steps) #if traj_file is not None: #write(traj_file, traj) else: # precon="Exp" specified to resolve an error with the lbfgs not optimising opt = PreconLBFGS(atoms_cell, use_armijo=False, **kwargs) if traj_file is not None: traj = open(traj_file, "w") def write_trajectory(): if "n_minim_iter" in atoms.info: atoms.info["n_minim_iter"] += 1 write(traj, atoms, format='extxyz') #opt.attach(write_trajectory) elif method == 'cg_n': raise ValueError( 'minim method cg_n not supported in new python3 quippy') # if strain_mask is not None: # raise(Exception("strain_mask not supported with method='cg_n'")) # atoms.info['Minim_Constant_Volume'] = constant_volume # opt = Minim(atoms, relax_positions=relax_pos, relax_cell=relax_cell, method='cg_n') else: raise ValueError('unknown method %s!' % method) if method != 'sd2': opt.run(tol, max_steps) if refine_symmetry_tol is not None: print("symmetry at end of relaxation at desired tol") check_symmetry(atoms, refine_symmetry_tol, verbose=True) print("symmetry at end of relaxation at default tol 1e-6") check_symmetry(atoms, 1.0e-6, verbose=True) # in case we had a trajectory saved try: traj.close() except: pass if save_config: if config_label is None: raise ValueError('save_config is set but no config_label provided') #write('-'+config_label+'-relaxed.xyz', atoms, format='extxyz') if keep_symmetry: for (i_c, c) in enumerate(atoms.constraints): if isinstance(c, FixSymmetry): del atoms.constraints[i_c] break # undo fix cell dependence # if fix_cell_dependence and hasattr(model, "fix_cell_dependence"): # sys.stderr.write("WARNING: relax_config undoing fix_cell_dependence, whether or not it was set before it started\n") # model.fix_cell_dependence() return atoms
def relax_use_method(xc, method, fmax=0.002, steps=100, clear=False): # allow only up to 100 steps atoms = mater.copy() # same start point! if xc.upper() not in ("PBE", "LDA"): raise ValueError("XC method not known!") if method.upper() not in ("UCF", "ECF", "IT"): raise ValueError("Optimization method not known!") parprint("Running {}-{} for {}-{}".format(xc, method, name, prototype)) calc = GPAW( mode=dict(name="pw", ecut=800), occupations=dict(name="fermi-dirac", width=0.01), basis="dzp", xc=xc.upper(), kpts=dict(gamma=True, density=4.0), # Very rough k-density txt=os.path.join(base_dir, "{}-{}.txt".format(xc.upper(), method.upper()))) atoms.set_calculator(calc) traj_filename = os.path.join( base_dir, "{}-{}.traj".format(xc.upper(), method.upper())) log_filename = os.path.join( base_dir, "{}-{}.log".format(xc.upper(), method.upper())) if clear is True: with open(traj_filename, "w") as _: pass with open(log_filename, "w") as _: pass res_fmax = None if method.upper() == "UCF": # UnitCellFilter ff = UnitCellFilter(atoms) opt = ase.optimize.BFGS(ff, trajectory=traj_filename, logfile=log_filename) opt.run(fmax=fmax, steps=steps) f = ff.get_forces() smax = numpy.sqrt((f**2).sum(axis=1).max()) elif method.upper() == "ECF": # ExpCellFilter ff = ExpCellFilter(atoms) opt = ase.optimize.BFGS(ff, trajectory=traj_filename, logfile=log_filename) opt.run(fmax=fmax, steps=steps) f = ff.get_forces() smax = numpy.sqrt((f**2).sum(axis=1).max()) elif method.upper() == "IT": # Iterative sf = StrainFilter(atoms) opt_strain = ase.optimize.BFGS(sf, trajectory=traj_filename, logfile=log_filename) opt_force = ase.optimize.BFGS(atoms, trajectory=traj_filename, logfile=log_filename) opt_strain.run(fmax=fmax, steps=steps) opt_force.run(fmax=fmax, steps=steps) f = atoms.get_forces() smax = numpy.sqrt((f**2).sum(axis=1).max()) a, b, c, *_ = atoms.get_cell_lengths_and_angles() if "smax" not in dir(): smax = None res_entry = dict(name=name, prototype=prototype, xc=xc.upper(), method=method.upper(), abc=(a, b, c), max_force=smax) return res_entry
def test_expcellfilter(setup_atoms): ecf = ExpCellFilter(setup_atoms) # test all derivatives f, fn = gradient_test(ecf) assert abs(f - fn).max() < 3e-6
################################################################################## atoms.set_calculator(lammps) print('Calculator set!') ################################################################################## energy_i = atoms.get_potential_energy() print('Starting potential energy: ' + str(energy_i)) opt = BFGS(atoms, trajectory='PREFIX_opt.traj') opt.run(fmax=5e-01) ecf = ExpCellFilter(atoms) qn = BFGS(ecf) cell_traj = Trajectory('PREFIX_copt.traj', 'w', atoms) qn.attach(cell_traj) qn.run(fmax=0.0005) #tri_mat, coord_transform = convert_cell2(atoms.get_cell()) #if coord_transform is not None: # atoms.set_positions([np.matmul(coord_transform, position) for position in atoms.get_positions()]) # atoms.set_cell(tri_mat.transpose()) #Temp = 300 #MaxwellBoltzmannDistribution(atoms, temp=Temp*units.kB)
kp2 = [1 for i in range(3)] for i in range(3): kp2[i] = int(np.ceil(20 / np.linalg.norm(atoms.cell[i, :]))) vdW = 'BEEF-vdW' calc = GPAW(xc=vdW, mode=PW(700, dedecut='estimate'), kpts={ 'size': kp2, 'gamma': True }, occupations=FermiDirac(width=0.05)) atoms.set_calculator(calc) name = atoms.get_chemical_formula(mode='hill') atoms.calc.set(txt=name + '_final.txt') atoms.calc.attach(atoms.calc.write, 5, name + '_final.gpw') uf = ExpCellFilter(atoms, constant_volume=True) relax = BFGS(uf) traj = Trajectory(name + '_final.traj', 'w', atoms) relax.attach(traj) relax.run(fmax=0.03) atoms.calc.write(name + '_final.gpw') #Writing ensemble energies to file if atoms.calc.get_xc_functional() == 'BEEF-vdW': ens = BEEFEnsemble(atoms.calc) ens_material = ens.get_ensemble_energies() np.savetxt(str(name) + '_Ensemble_Energies.txt', ens_material)
import ase from ase.calculators.vasp import Vasp from ase.optimize import BFGS from ase.constraints import ExpCellFilter #read atoms from POSCAR file atoms = ase.io.read("POSCAR") # set environments os.environ["VASP_PP_PATH"] = "/---/---/vasp/potentials/potpaw_PBE.54/" # set calculator dft = Vasp( kpts=[18, 18, 1], gamma=True, encut=400, ismear=0, sigma=0.1, xc='pbe', ivdw=202, ediff=1E-6, pp=os.getenv("VASP_PP_PATH"), setups='recommended', ) atoms.set_calculator(dft) #Optimizer opt = BFGS(ExpCellFilter(atoms, mask=[1, 1, 0, 0, 0, 0]), logfile="ase_vasp_opt.log") opt.run(fmax=0.001)
import numpy as np from ase.build import bulk from ase.calculators.lj import LennardJones from ase.optimize.precon import PreconLBFGS, Exp from ase.constraints import UnitCellFilter, ExpCellFilter cu0 = bulk("Cu") * (2, 2, 2) lj = LennardJones(sigma=cu0.get_distance(0, 1)) cu = cu0.copy() cu.set_cell(1.2 * cu.get_cell()) cu.set_calculator(lj) ucf = UnitCellFilter(cu, constant_volume=True) opt = PreconLBFGS(ucf, precon=Exp(mu=1.0, mu_c=1.0)) opt.run(fmax=1e-3) assert abs(np.linalg.det(cu.cell) / np.linalg.det(cu0.cell) - 1.2**3) < 1e-3 # EcpCellFilter allows relaxing to lower tolerance cu = cu0.copy() cu.set_cell(1.2 * cu.get_cell()) cu.set_calculator(lj) ecf = ExpCellFilter(cu, constant_volume=True) opt = PreconLBFGS(ecf, precon=Exp(mu=1.0, mu_c=1.0)) opt.run(fmax=1e-3) assert abs(np.linalg.det(cu.cell) / np.linalg.det(cu0.cell) - 1.2**3) < 1e-7
structures = ['Si', 'Ge', 'C'] db = connect('database.db') for f in structures: db.write(bulk(f)) for row in db.select(): atoms = row.toatoms() calc = GPAW(mode=PW(400), kpts=(4, 4, 4), txt=f'{row.formula}-gpaw.txt', xc='LDA') atoms.calc = calc atoms.get_stress() filter = ExpCellFilter(atoms) opt = BFGS(filter) opt.run(fmax=0.05) db.write(atoms=atoms, relaxed=True) for row in db.select(relaxed=True): atoms = row.toatoms() calc = GPAW(mode=PW(400), kpts=(4, 4, 4), txt=f'{row.formula}-gpaw.txt', xc='LDA') atoms.calc = calc atoms.get_potential_energy() bg, _, _ = bandgap(calc=atoms.calc) db.update(row.id, bandgap=bg)
params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] calc = LAMMPS(specorder=['Pt'], files=[pot_fn], **params) rng = np.random.RandomState(17) atoms = bulk('Pt') * (2, 2, 2) atoms.rattle(stdev=0.1) atoms.cell += 2 * rng.rand(3, 3) atoms.calc = calc assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) opt = BFGS(ExpCellFilter(atoms), trajectory='opt.traj') for i, _ in enumerate(opt.irun(fmax=0.05)): pass cell1_ref = np.array([[0.16298762, 3.89912471, 3.92825365], [4.21007577, 0.63362427, 5.04668170], [4.42895706, 3.29171414, 0.44623618]]) assert_allclose(np.asarray(atoms.cell), cell1_ref, atol=1e-4, rtol=1e-4) assert_allclose(atoms.get_stress(), calc.calculate_numerical_stress(atoms), atol=1e-4, rtol=1e-4) assert i < 80, 'Expected 59 iterations, got many more: {}'.format(i)
solvent=args.solvent) else: raise Exception("Method not implemented.") mol.set_calculator(calc) e = mol.get_potential_energy() print('Initial energy: eV, Eh', e, e / Hartree) if args.precon: precon = Exp(A=3, r_NN=args.rnn + 0.1, r_cut=args.rnn + 0.6) else: precon = None if args.optcell: sf = ExpCellFilter(mol) relax = PatchedOptimizer(sf, precon=precon, trajectory=args.trajectory, logfile=args.logfile, use_armijo=args.armijo) else: relax = PatchedOptimizer(mol, precon=precon, trajectory=args.trajectory, logfile=args.logfile, use_armijo=args.armijo) try: relax.run(econv=args.econv, fconv=args.fconv) except KeyboardInterrupt:
atoms.set_calculator(LennardJones()) ucf = UnitCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all deritatives f, fn = gradient_test(ucf) assert abs(f - fn).max() < 1e-6 opt = FIRE(ucf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1 atoms = a0.copy() atoms.set_calculator(LennardJones()) ecf = ExpCellFilter(atoms, scalar_pressure=10.0 * GPa) # test all deritatives f, fn = gradient_test(ecf) assert abs(f - fn).max() < 1e-6 opt = FIRE(ecf) opt.run(1e-3) # check pressure is within 0.1 GPa of target sigma = atoms.get_stress() / GPa pressure = -(sigma[0] + sigma[1] + sigma[2]) / 3.0 assert abs(pressure - 10.0) < 0.1
atoms = molecule('H2O') atoms1 = atoms.copy() atoms1.calc = GULP(library='reaxff.lib') opt1 = BFGS(atoms1, trajectory='bfgs.traj') opt1.run(fmax=0.005) atoms2 = atoms.copy() calc2 = GULP(keywords='opti conp', library='reaxff.lib') opt2 = calc2.get_optimizer(atoms2) opt2.run() print(np.abs(opt1.atoms.positions - opt2.atoms.positions)) assert np.abs(opt1.atoms.positions - opt2.atoms.positions).max() < 1e-5 # GULP optimization test using stress atoms = bulk('Au', 'bcc', a=2.7, cubic=True) atoms1 = atoms.copy() atoms1.calc = GULP(keywords='conp gradient stress_out', library='reaxff_general.lib') atoms1f = ExpCellFilter(atoms1) opt1 = BFGS(atoms1f, trajectory='bfgs.traj') opt1.run(fmax=0.005) atoms2 = atoms.copy() calc2 = GULP(keywords='opti conp', library='reaxff_general.lib') opt2 = calc2.get_optimizer(atoms2) opt2.run() print(np.abs(opt1.atoms.positions - opt2.atoms.positions)) assert np.abs(opt1.atoms.positions - opt2.atoms.positions).max() < 1e-5