def test_qmmm_acn(): import numpy as np import ase.units as units from ase import Atoms from ase.calculators.acn import (ACN, m_me, r_cn, r_mec, sigma_me, sigma_c, sigma_n, epsilon_me, epsilon_c, epsilon_n) from ase.calculators.qmmm import SimpleQMMM, LJInteractionsGeneral, EIQMMM from ase.constraints import FixLinearTriatomic from ase.optimize import BFGS # From https://www.sciencedirect.com/science/article/pii/S0166128099002079 eref = 4.9 * units.kcal / units.mol dref = 3.368 aref = 79.1 sigma = np.array([sigma_me, sigma_c, sigma_n]) epsilon = np.array([epsilon_me, epsilon_c, epsilon_n]) inter = LJInteractionsGeneral(sigma, epsilon, sigma, epsilon, 3) for calc in [ACN(), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN()), SimpleQMMM([0, 1, 2], ACN(), ACN(), ACN(), vacuum=3.0), EIQMMM([0, 1, 2], ACN(), ACN(), inter), EIQMMM([0, 1, 2], ACN(), ACN(), inter, vacuum=3.0), EIQMMM([3, 4, 5], ACN(), ACN(), inter, vacuum=3.0)]: dimer = Atoms('CCNCCN', [(-r_mec, 0, 0), (0, 0, 0), (r_cn, 0, 0), (r_mec, 3.7, 0), (0, 3.7, 0), (-r_cn, 3.7, 0)]) masses = dimer.get_masses() masses[::3] = m_me dimer.set_masses(masses) dimer.calc = calc fixd = FixLinearTriatomic(triples=[(0, 1, 2), (3, 4, 5)]) dimer.set_constraint(fixd) opt = BFGS(dimer, maxstep=0.04, trajectory=calc.name + '.traj', logfile=calc.name + 'd.log') opt.run(0.001, steps=1000) e0 = dimer.get_potential_energy() d0 = dimer.get_distance(1, 4) a0 = dimer.get_angle(2, 1, 4) fmt = '{0:>25}: {1:.3f} {2:.3f} {3:.1f}' print(fmt.format(calc.name, -e0, d0, a0)) assert abs(e0 + eref) < 0.013 assert abs(d0 - dref) < 0.224 assert abs(a0 - aref) < 2.9 print(fmt.format('reference', eref, dref, aref))
def test_turbomole_h3o2m(): # http://jcp.aip.org/resource/1/jcpsa6/v97/i10/p7507_s1 doo = 2.74 doht = 0.957 doh = 0.977 angle = radians(104.5) initial = Atoms('HOHOH', positions=[(-sin(angle) * doht, 0., cos(angle) * doht), (0., 0., 0.), (0., 0., doh), (0., 0., doo), (sin(angle) * doht, 0., doo - cos(angle) * doht) ]) if 0: view(initial) final = Atoms('HOHOH', positions=[(-sin(angle) * doht, 0., cos(angle) * doht), (0., 0., 0.), (0., 0., doo - doh), (0., 0., doo), (sin(angle) * doht, 0., doo - cos(angle) * doht)]) if 0: view(final) # Make band: images = [initial.copy()] for i in range(3): images.append(initial.copy()) images.append(final.copy()) neb = NEB(images, climb=True) # Write all commands for the define command in a string define_str = ('\n\na coord\n\n*\nno\nb all 3-21g ' 'hondo\n*\neht\n\n-1\nno\ns\n*\n\ndft\non\nfunc ' 'pwlda\n\n\nscf\niter\n300\n\n*') # Set constraints and calculator: constraint = FixAtoms(indices=[1, 3]) # fix OO BUG No.1: fixes atom 0 and 1 # constraint = FixAtoms(mask=[0,1,0,1,0]) # fix OO #Works without patch for image in images: image.calc = Turbomole(define_str=define_str) image.set_constraint(constraint) # Relax initial and final states: if 1: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.10) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.10) # Interpolate positions between initial and final states: neb.interpolate() if 1: for image in images: print(image.get_distance(1, 2), image.get_potential_energy()) dyn = BFGS(neb, trajectory='turbomole_h3o2m.traj') dyn.run(fmax=0.10) for image in images: print(image.get_distance(1, 2), image.get_potential_energy())
def test_Ag_Cu100(): from math import sqrt from ase import Atom, Atoms from ase.neb import NEB from ase.constraints import FixAtoms from ase.vibrations import Vibrations from ase.calculators.emt import EMT from ase.optimize import QuasiNewton, BFGS # Distance between Cu atoms on a (100) surface: d = 3.6 / sqrt(2) initial = Atoms('Cu', positions=[(0, 0, 0)], cell=(d, d, 1.0), pbc=(True, True, False)) initial *= (2, 2, 1) # 2x2 (100) surface-cell # Approximate height of Ag atom on Cu(100) surfece: h0 = 2.0 initial += Atom('Ag', (d / 2, d / 2, h0)) # Make band: images = [initial.copy() for i in range(6)] neb = NEB(images, climb=True) # Set constraints and calculator: constraint = FixAtoms(range(len(initial) - 1)) for image in images: image.calc = EMT() image.set_constraint(constraint) # Displace last image: images[-1].positions[-1] += (d, 0, 0) # Relax height of Ag atom for initial and final states: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.01) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.01) # Interpolate positions between initial and final states: neb.interpolate() for image in images: print(image.positions[-1], image.get_potential_energy()) dyn = BFGS(neb, trajectory='mep.traj') dyn.run(fmax=0.05) for image in images: print(image.positions[-1], image.get_potential_energy()) a = images[0] vib = Vibrations(a, [4]) vib.run() print(vib.get_frequencies()) vib.summary() print(vib.get_mode(-1)) vib.write_mode(-1, nimages=20)
def test_bad_restart(testdir): fname = 'tmp.dat' with open(fname, 'w') as fd: fd.write('hello world\n') with pytest.raises(RestartError, match='Could not decode'): BFGS(Atoms(), restart=fname)
def run_dft(): kpt = 16 atoms = bulk("Al",crystalstructure="fcc",a=4.05) calc = gp.GPAW( mode=gp.PW(600), xc="PBE", kpts=(kpt,kpt,kpt), nbands=-50 ) atoms.set_calculator( calc ) relaxer = BFGS( UnitCellFilter(atoms) ) relaxer.run( fmax=0.025 ) energy = atoms.get_potential_energy() print (energy)
def minimize(self, ani_input): #calculator = self.model.ase(dtype=torch.float32) calculator = torchani.models.ANI1ccx().ase(dtype=torch.float64) mol = ani_input['ase_hybrid_mol'] mol.set_calculator(calculator) print("Begin minimizing...") opt = BFGS(mol) opt.run(fmax=0.001)
def test_h3o2m(): # http://jcp.aip.org/resource/1/jcpsa6/v97/i10/p7507_s1 doo = 2.74 doht = 0.957 doh = 0.977 angle = radians(104.5) initial = Atoms('HOHOH', positions=[(-sin(angle) * doht, 0, cos(angle) * doht), (0., 0., 0.), (0., 0., doh), (0., 0., doo), (sin(angle) * doht, 0., doo - cos(angle) * doht) ]) if 0: view(initial) final = Atoms('HOHOH', positions=[(-sin(angle) * doht, 0., cos(angle) * doht), (0., 0., 0.), (0., 0., doo - doh), (0., 0., doo), (sin(angle) * doht, 0., doo - cos(angle) * doht)]) if 0: view(final) # Make band: images = [initial.copy()] for i in range(3): images.append(initial.copy()) images.append(final.copy()) neb = NEB(images, climb=True) def calculator(): return NWChem(task='gradient', theory='scf', charge=-1) # Set constraints and calculator: constraint = FixAtoms(indices=[1, 3]) # fix OO for image in images: image.calc = calculator() image.set_constraint(constraint) # Relax initial and final states: if 1: dyn1 = QuasiNewton(images[0]) dyn1.run(fmax=0.10) dyn2 = QuasiNewton(images[-1]) dyn2.run(fmax=0.10) # Interpolate positions between initial and final states: neb.interpolate() if 1: for image in images: print(image.get_distance(1, 2), image.get_potential_energy()) dyn = BFGS(neb, trajectory='nwchem_h3o2m.traj') dyn.run( fmax=0.10) # use better basis (e.g. aug-cc-pvdz) for NEB to converge for image in images: print(image.get_distance(1, 2), image.get_potential_energy())
def test_fake_ase_opt(): atoms = Icosahedron("Ar", noshells=2, latticeconstant=3) atoms.set_calculator(FakeASE(LennardJones())) dyn = BFGS(atoms) dyn.run(fmax=0.0005) assert dyn.converged() assert dyn.get_number_of_steps() == 14 assert np.linalg.norm(dyn.f0) == pytest.approx(0.0041872094)
def opt_conf(conformer, calculator, i): """ A helper function to optimize the geometry of a conformer. Only for use within this parent function """ combo = combinations[i] # labels = [] # for bond in conformer.bonds: # labels.append(bond.atom_indices) if isinstance(conformer, TS): label = conformer.reaction_label ind1 = conformer.rmg_molecule.getLabeledAtom("*1").sortingLabel ind2 = conformer.rmg_molecule.getLabeledAtom("*2").sortingLabel ind3 = conformer.rmg_molecule.getLabeledAtom("*3").sortingLabel labels = [[ind1, ind2],[ind1,ind3],[ind2,ind3]] type = "ts" else: label = conformer.smiles type = "species" if isinstance(calc, FileIOCalculator): calculator.directory = os.path.join( 'conformer_logs', type, label, "systematic", '{}_{}'.format(conformer.smiles,i)) if not os.path.exists(calculator.directory): try: os.mkdirs(calculator.directory) except: logging.info("An error occured when creating {}".format(calculator.directory)) calculator.atoms = conformer.ase_molecule # from ase.constraints import FixBondLengths # c = FixBondLengths(labels) # conformer.ase_molecule.set_constraint(c) conformer.ase_molecule.set_calculator(calculator) if type == 'species': opt = BFGS(conformer.ase_molecule, logfile=None) opt.run() conformer.update_coords_from("ase") energy = get_energy(conformer) if type == 'ts': energy = get_energy(conformer) return_dict[i] = (energy, conformer.ase_molecule.arrays, conformer.ase_molecule.get_all_distances())
def relaxGPAW(structure, label, forcemax=0.1, niter_max=1, steps=10): ''' Relax a structure and saves the trajectory based in the index i Parameters ---------- structure : ase Atoms object to be relaxed i : index which the trajectory is saved under ranks: ranks of the processors to relax the structure Returns ------- structure : relaxed Atoms object ''' # Create calculator calc=GPAW(#poissonsolver = PoissonSolver(relax = 'GS',eps = 1.0e-7), # C mode = 'lcao', basis = 'dzp', xc='PBE', #gpts = h2gpts(0.2, structure.get_cell(), idiv = 8), # C occupations=FermiDirac(0.1), #maxiter=99, # C maxiter=49, # Sn3O3 mixer=Mixer(nmaxold=5, beta=0.05, weight=75), nbands=-50, #kpts=(1,1,1), # C kpts=(2,2,1), # Sn3O3 txt = label+ '_lcao.txt') # Set calculator structure.set_calculator(calc) # loop a number of times to capture if minimization stops with high force # due to the VariansBreak calls niter = 0 # If the structure is already fully relaxed just return it if (structure.get_forces()**2).sum(axis = 1).max()**0.5 < forcemax: return structure traj = Trajectory(label+'_lcao.traj','w', structure) while (structure.get_forces()**2).sum(axis = 1).max()**0.5 > forcemax and niter < niter_max: dyn = BFGS(structure, logfile=label+'.log') vb = VariansBreak(structure, dyn, min_stdev = 0.01, N = 15) dyn.attach(traj) dyn.attach(vb) dyn.run(fmax = forcemax, steps = steps) niter += 1 return structure
def test_ase_relax(): slab = create_slab_with_constraints() calc = Vasp(xc='LDA', ediffg=-1e-3, lwave=False, lcharg=False) slab.set_calculator(calc) opt = BFGS(slab, logfile=None) opt.run(fmax=0.1, steps=3) init_slab = create_slab_with_constraints() res = read('OUTCAR') assert np.allclose(res.positions[0], init_slab.positions[0]) assert not np.allclose(res.positions[2], init_slab.positions[2])
def run(symb, a, n, ads): atoms = fcc111(symb, (1, 1, n), a=a) add_adsorbate(atoms, ads, height=1.0, position='fcc') # Constrain all atoms except the adsorbate: fixed = list(range(len(atoms) - 1)) atoms.constraints = [FixAtoms(indices=fixed)] atoms.calc = EMT() opt = BFGS(atoms, logfile=None) opt.run(fmax=0.01) return atoms
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 _get_optimized_cell(self, structure, potential): atoms = self._get_ase_from_pmg(structure) atoms.set_calculator(potential) try: sf = UnitCellFilter(atoms) dyn = BFGS(sf) dyn.run(fmax=1e-5) sf = StrainFilter(atoms) dyn = BFGS(sf) dyn.run(fmax=1e-5) dyn = BFGS(atoms) dyn.run(fmax=1e-5) sf = UnitCellFilter(atoms) dyn = BFGS(sf) dyn.run(fmax=1e-5) except AttributeError: warnings.warn("No optimization is performed.") return self._get_pmg_from_ase(atoms)
def test_bpnn_calculator(): from pinn.models import BPNN from pinn.calculator import PiNN_calc from ase.collections import g2 from ase.optimize import BFGS model = BPNN('tmp/BPNN-ANI') calc = PiNN_calc(model=model) water = g2['H2O'] water.set_calculator(calc) dyn = BFGS(water) dyn.run(fmax=0.05)
def main(atoms_list, fmax=0.05): """Does BFGS relaxations of atoms Args: atoms_list (list): list of atoms, as given by runner Returns: atoms object: relaxed atoms object""" atoms = atoms_list[0] opt = BFGS(atoms) opt.run(fmax=fmax) return atoms
def compute_energy(self, particle): cell_width = particle.lattice.width * particle.lattice.lattice_constant cell_length = particle.lattice.length * particle.lattice.lattice_constant cell_height = particle.lattice.height * particle.lattice.lattice_constant atoms = particle.get_ASE_atoms() atoms.set_cell(np.array([[cell_width, 0, 0], [0, cell_length, 0], [0, 0, cell_height]])) atoms.set_calculator(EMT()) dyn = BFGS(atoms) dyn.run(fmax=self.fmax, steps=self.steps) energy = atoms.get_potential_energy() particle.set_energy(self.energy_key, energy)
def construct_geometries(parent_calc, ml2relax): counter_calc = parent_calc # Initial structure guess initial_slab = fcc100("Cu", size=(2, 2, 3)) add_adsorbate(initial_slab, "C", 1.7, "hollow") initial_slab.center(axis=2, vacuum=4.0) mask = [atom.tag > 1 for atom in initial_slab] initial_slab.set_constraint(FixAtoms(mask=mask)) initial_slab.set_pbc(True) initial_slab.wrap(pbc=[True] * 3) initial_slab.set_calculator(counter_calc) # Final structure guess final_slab = initial_slab.copy() final_slab[-1].x += final_slab.get_cell()[0, 0] / 3 final_slab.set_calculator(counter_calc) if not ml2relax: print("BUILDING INITIAL") qn = BFGS(initial_slab, trajectory="initial.traj", logfile="initial_relax_log.txt") qn.run(fmax=0.01, steps=100) print("BUILDING FINAL") qn = BFGS(final_slab, trajectory="final.traj", logfile="final_relax_log.txt") qn.run(fmax=0.01, steps=100) initial_slab = read("initial.traj", "-1") final_slab = read("final.traj", "-1") # If there is already a pre-existing initial and final relaxed parent state we can read # that to use as a starting point # initial_slab = read("/content/parent_initial.traj") # final_slab = read("/content/parent_final.traj") else: initial_slab = initial_slab final_slab = final_slab # initial_force_calls = counter_calc.force_calls return initial_slab, final_slab # , initial_force_calls
def main(argv): db_id = int(argv[0]) db_name = argv[1] db = connect(db_name) calc = EMT() atoms = db.get(id=db_id).toatoms() atoms.set_calculator(calc) str_filter = StrainFilter(atoms) relaxer = BFGS(str_filter) relaxer.run(fmax=0.003) update_db(uid_initial=db_id, final_struct=atoms, db_name=db_name)
def relax_structure(atoms: Atoms) -> float: """Relax and return the energy of the ground state Args: atoms """ atoms.set_calculator(calc) dyn = BFGS(atoms, logfile=os.devnull) dyn.run(fmax=1e-3) return atoms.get_potential_energy()
def relaxGPAW(structure, label, calc=None, forcemax=0.1, niter_max=1, steps=10): # Create calculator if calc is None: calc = GPAW( poissonsolver=PoissonSolver(relax='GS', eps=1.0e-7), # C mode='lcao', basis='dzp', xc='PBE', gpts=h2gpts(0.2, structure.get_cell(), idiv=8), # C occupations=FermiDirac(0.1), maxiter=99, # C #maxiter=49, # Sn3O3 mixer=Mixer(nmaxold=5, beta=0.05, weight=75), nbands=-50, #kpts=(1,1,1), # C kpts=(2, 2, 1), # Sn3O3 txt=label + '_lcao.txt') else: calc.set(txt=label + '_true.txt') # Set calculator structure.set_calculator(calc) # loop a number of times to capture if minimization stops with high force # due to the VariansBreak calls niter = 0 # If the structure is already fully relaxed just return it if (structure.get_forces()**2).sum(axis=1).max()**0.5 < forcemax: return structure traj = Trajectory(label + '_lcao.traj', 'w', structure) while (structure.get_forces()** 2).sum(axis=1).max()**0.5 > forcemax and niter < niter_max: dyn = BFGS(structure, logfile=label + '.log') vb = VariansBreak(structure, dyn, min_stdev=0.01, N=15) dyn.attach(traj) dyn.attach(vb) dyn.run(fmax=forcemax, steps=steps) niter += 1 E = structure.get_potential_energy() F = structure.get_forces() return structure, E, F
def optTSpoint(self, trans, path, MolList, TrajStart, idx): self.TS = MolList[TrajStart].copy() self.TS = tl.setCalc(self.TS, self.lowString, self.lowMeth, self.lowLev) c = FixAtoms(trans) self.TS.set_constraint(c) min = BFGS(self.TS) min.run(fmax=0.05, steps=50) os.mkdir(path + '/Data/') write(path + '/Data/TSGuess.xyz', self.TS) TSGuess = self.TS.copy() del self.TS.constraints if self.biReac or self.biProd: QTS3 = False else: QTS3 = True if (self.twoStageTS): try: self.TSFreqs, self.imaginaryFreq, zpe, energy, self.TS, rmol, pmol = self.characteriseTSExt( self.TS, True, path, QTS3) except: pass try: self.TSFreqs, self.imaginaryFreq, zpe, energy, self.TS, rmol, pmol = self.characteriseTSExt( self.TS, False, path, QTS3) except: try: print( "High Level TS opt for TS1 failed looking at lower level") self.TSFreqs, self.imaginaryFreq, zpe, energy, self.TS, rmol, pmol = self.characteriseTSExt( self.TS, True, path, QTS3) except: pass try: self.TScorrect = self.compareRandP(rmol, pmol) except: self.TScorrect = False self.TS = TSGuess self.TSFreqs, self.imaginaryFreq, zpe, energy = self.characteriseTSinternal( self.TS) write(path + '/TS1.xyz', self.TS) self.forwardBarrier = energy if (self.forwardBarrier < self.reactantEnergy and self.forwardBarrier < self.productEnergy): self.barrierlessReaction = True
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 main(): calculator = calculators.get_calculator("_deploy_", debug=False) atom_labels, coordinates = rmsd.get_coordinates_xyz("examples/ethanol.xyz") molecule = ase.Atoms(atom_labels, coordinates) molecule.set_calculator(calculator) dyn = BFGS(molecule) dyn.run(fmax=0.3) dump_xyz(molecule, "_tmp_molecule_optimize.xyz") return
def opt_conf(conformer, calculator, i): """ A helper function to optimize the geometry of a conformer. Only for use within this parent function """ labels = [] for bond in conformer.bonds: labels.append(bond.atom_indices) if isinstance(conformer, TS): label = conformer.reaction_label ind1 = conformer.rmg_molecule.getLabeledAtom("*1").sortingLabel ind2 = conformer.rmg_molecule.getLabeledAtom("*3").sortingLabel labels.append([ind1, ind2]) type = 'ts' else: label = conformer.smiles type = 'species' if isinstance(calc, FileIOCalculator): if calculator.directory: directory = calculator.directory else: directory = 'conformer_logs' calculator.label = "{}_{}".format(conformer.smiles, i) calculator.directory = os.path.join( directory, label, '{}_{}'.format(conformer.smiles, i)) if not os.path.exists(calculator.directory): try: os.makedirs(calculator.directory) except OSError: logging.info("An error occured when creating {}".format( calculator.directory)) calculator.atoms = conformer.ase_molecule from ase.constraints import FixBondLengths c = FixBondLengths(labels) conformer.ase_molecule.set_constraint(c) conformer.ase_molecule.set_calculator(calculator) opt = BFGS(conformer.ase_molecule, logfile=None) opt.run() conformer.update_coords_from("ase") energy = get_energy(conformer) return_dict[i] = (energy, conformer.ase_molecule.arrays, conformer.ase_molecule.get_all_distances())
def test_vibrations_example(testdir): """Test the example from the Vibrations.__init__() docstring""" n2 = Atoms('N2', [(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) BFGS(n2).run(fmax=0.01) vib = Vibrations(n2) vib.run() with io.StringIO() as f: vib.summary(log=f) f.seek(0) summary = f.read() assert len(summary.split()) == len(expected_summary.split())
def opt(st): comp = str(st.composition) comp = comp.replace(" ", "") aaa=AseAtomsAdaptor() atoms=aaa.get_atoms(st) atoms.set_calculator(calc) dyn = BFGS(atoms) #dyn = BFGS(atoms,trajectory=comp+'.traj') ret=dyn.run(fmax=0.01,steps=800) if ret: aaa.get_structure(atoms) return aaa.get_structure(atoms) else: return None
def full_relaxation(self, fmax=0.025, smax=0.003): """ Perform a full relaxation of the system """ if (len(self.atoms) == 1): strfilter = StrainFilter(self.atoms) relaxer = BFGS(strfilter) fmax = smax * self.atoms.get_volume() relaxer.run(fmax=fmax) else: relaxer = PreconLBFGS(self.atoms, variable_cell=True) relaxer.run(fmax=fmax, smax=smax) db = connect(self.db_name) db.write(self.atoms, key_value_pairs={"full_relaxation": True})
def ase_vol_relax(): Al = bulk('Al', 'fcc', a=4.5, cubic=True) calc = factory.calc(xc='LDA') Al.calc = calc from ase.constraints import StrainFilter sf = StrainFilter(Al) with BFGS(sf, logfile='relaxation.log') as qn: qn.run(fmax=0.1, steps=5) print('Stress:\n', calc.read_stress()) print('Al post ASE volume relaxation\n', calc.get_atoms().get_cell()) return Al
def test_geoopt(cp2k_factory, atoms): calc = cp2k_factory.calc(label='test_H2_GOPT', print_level='LOW') atoms.calc = calc gopt = BFGS(atoms, logfile=None) gopt.run(fmax=1e-6) dist = atoms.get_distance(0, 1) dist_ref = 0.7245595 assert (dist - dist_ref) / dist_ref < 1e-7 energy_ref = -30.7025616943 energy = atoms.get_potential_energy() assert (energy - energy_ref) / energy_ref < 1e-10