def relax_defect_cell(self, ats, output_name='defect_cell_relaxed.xyz', force_tol=0.0001, relax_cell=False): """ Accepts atoms object with an attached calculator.Minimize forces. Args: ats (:obj:`Atoms`): Atoms with defect to relax. output_name (str, optional): Filename to print relaxed atoms structure to. force_tol (float, optional): Force tolerance to stop relaxation. relax_cell (bool, optional): Relax lattice parameters. Returns: :class:`Atoms`: A relaxed Atoms object. """ from ase.optimize import FIRE if relax_cell: strain_mask = [1, 1, 1, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) else: strain_mask = [0, 0, 0, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) opt.run(fmax=force_tol) ats.write(output_name) return ats
def test_direct_evaluation(self): a = FaceCenteredCubic('Au', size=[2,2,2]) a.rattle(0.1) calc = EAM('Au-Grochola-JCP05.eam.alloy') a.set_calculator(calc) f = a.get_forces() calc2 = EAM('Au-Grochola-JCP05.eam.alloy') i_n, j_n, dr_nc, abs_dr_n = neighbour_list('ijDd', a, cutoff=calc2.cutoff) epot, virial, f2 = calc2.energy_virial_and_forces(a.numbers, i_n, j_n, dr_nc, abs_dr_n) self.assertArrayAlmostEqual(f, f2) a = FaceCenteredCubic('Cu', size=[2,2,2]) calc = EAM('CuAg.eam.alloy') a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e_Cu = a.get_potential_energy()/len(a) a = FaceCenteredCubic('Ag', size=[2,2,2]) a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e_Ag = a.get_potential_energy()/len(a) self.assertTrue(abs(e_Ag+2.85)<1e-6) a = L1_2(['Ag', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue(abs((e-(syms=='Cu').sum()*e_Cu- (syms=='Ag').sum()*e_Ag)/len(a)-0.096)<0.0005) a = B1(['Ag', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue(abs((e-(syms=='Cu').sum()*e_Cu- (syms=='Ag').sum()*e_Ag)/len(a)-0.516)<0.0005) a = B2(['Ag', 'Cu'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue(abs((e-(syms=='Cu').sum()*e_Cu- (syms=='Ag').sum()*e_Ag)/len(a)-0.177)<0.0003) a = L1_2(['Cu', 'Ag'], size=[2,2,2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue(abs((e-(syms=='Cu').sum()*e_Cu- (syms=='Ag').sum()*e_Ag)/len(a)-0.083)<0.0005)
def test_CuAg(self): a = FaceCenteredCubic('Cu', size=[2, 2, 2]) calc = EAM('CuAg.eam.alloy') a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e_Cu = a.get_potential_energy() / len(a) a = FaceCenteredCubic('Ag', size=[2, 2, 2]) a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e_Ag = a.get_potential_energy() / len(a) self.assertTrue(abs(e_Ag + 2.85) < 1e-6) a = L1_2(['Ag', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue( abs((e - (syms == 'Cu').sum() * e_Cu - (syms == 'Ag').sum() * e_Ag) / len(a) - 0.096) < 0.0005) a = B1(['Ag', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue( abs((e - (syms == 'Cu').sum() * e_Cu - (syms == 'Ag').sum() * e_Ag) / len(a) - 0.516) < 0.0005) a = B2(['Ag', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue( abs((e - (syms == 'Cu').sum() * e_Cu - (syms == 'Ag').sum() * e_Ag) / len(a) - 0.177) < 0.0003) a = L1_2(['Cu', 'Ag'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e = a.get_potential_energy() syms = np.array(a.get_chemical_symbols()) self.assertTrue( abs((e - (syms == 'Cu').sum() * e_Cu - (syms == 'Ag').sum() * e_Ag) / len(a) - 0.083) < 0.0005)
def test_stress(atoms): cell0 = atoms.get_cell() atoms.set_cell(np.dot( atoms.cell, [[1.02, 0, 0.03], [0, 0.99, -0.02], [0.1, -0.01, 1.03]]), scale_atoms=True) atoms *= (1, 2, 3) cell0 *= np.array([1, 2, 3])[:, np.newaxis] atoms.rattle() # Verify analytical stress tensor against numerical value s_analytical = atoms.get_stress() s_numerical = atoms.calc.calculate_numerical_stress(atoms, 1e-5) s_p_err = 100 * (s_numerical - s_analytical) / s_numerical print("Analytical stress:\n", s_analytical) print("Numerical stress:\n", s_numerical) print("Percent error in stress:\n", s_p_err) assert np.all(abs(s_p_err) < 1e-5) # Minimize unit cell opt = BFGS(UnitCellFilter(atoms)) opt.run(fmax=1e-3) # Verify minimized unit cell using Niggli tensors g_minimized = np.dot(atoms.cell, atoms.cell.T) g_theory = np.dot(cell0, cell0.T) g_p_err = 100 * (g_minimized - g_theory) / g_theory print("Minimized Niggli tensor:\n", g_minimized) print("Theoretical Niggli tensor:\n", g_theory) print("Percent error in Niggli tensor:\n", g_p_err) assert np.all(abs(g_p_err) < 1)
def __init__(self, doc, queue, calculator=None): """ Initialise a relaxation with ASE. Parameters: doc (dict): the structure to optimise. queue (mp.Queue): the queue to push the result to. Keyword arguments: calculator (ase.Calculator): the calculator object to use for force/energy computation. Default is LennardJones. """ from copy import deepcopy from matador.utils.viz_utils import doc2ase from ase.constraints import UnitCellFilter if calculator is None: from ase.calculators.lj import LennardJones self.calc = LennardJones() else: self.calc = calculator self.doc = deepcopy(doc) self.atoms = doc2ase(doc) self.atoms.set_calculator(self.calc) self.ucf = UnitCellFilter(self.atoms) self.queue = queue
def test_md(factory): # XXX ugly hack ver = factory.factory.version() if LooseVersion(ver) < '3.8': pytest.skip('No stress tensor until openmx 3.8+') bud = Atoms('CH4', np.array([[0.000000, 0.000000, 0.100000], [0.682793, 0.682793, 0.682793], [-0.682793, -0.682793, 0.68279], [-0.682793, 0.682793, -0.682793], [0.682793, -0.682793, -0.682793]]), cell=[10, 10, 10]) calc = factory.calc( label='ch4', xc='GGA', energy_cutoff=300 * Ry, convergence=1e-4 * Ha, # Use 'C_PBE19' and 'H_PBE19' for version 3.9 definition_of_atomic_species=[['C', 'C5.0-s1p1', 'C_PBE13'], ['H', 'H5.0-s1', 'H_PBE13']], kpts=(1, 1, 1), eigensolver='Band') bud.calc = calc with Trajectory('example.traj', 'w', bud) as traj: ucf = UnitCellFilter(bud, mask=[True, True, False, False, False, False]) dyn = QuasiNewton(ucf) dyn.attach(traj.write) dyn.run(fmax=0.1) bud.get_potential_energy()
def relax(runID): db = connect(db_name) atoms = db.get_atoms(id=runID) con = sq.connect(db_name) cur = con.cursor() cur.execute("SELECT value FROM text_key_values WHERE id=? AND key='name'", (runID, )) name = cur.fetchone()[0] con.close() calc = gp.GPAW(mode=gp.PW(600), xc="PBE", kpts=(4, 4, 4), nbands="120%", symmetry="off") atoms.set_calculator(calc) precon = Exp(mu=1.0, mu_c=1.0) save_to_db = SaveToDB(db_name, runID, name) logfile = "logfile%d.log" % (runID) traj = "trajectory%d.traj" % (runID) uf = UnitCellFilter(atoms, hydrostatic_strain=True) relaxer = PreconLBFGS(uf, logfile=logfile, use_armijo=True, precon=precon) relaxer.attach(save_to_db, interval=1, atoms=atoms) trajObj = Trajectory(traj, "w", atoms) relaxer.attach(trajObj) relaxer.run(fmax=0.05, smax=0.003)
def evaluate(self, imember): entry = self.population.get_entry(imember) pcm_structure = pychemia.Structure.from_dict(entry['structure']) ase_structure = pychemia.external.ase.pychemia2ase(pcm_structure) ase_structure.set_calculator(LennardJones()) dyn = QuasiNewton(ase_structure) dyn.run() ase_structure.set_constraint( FixAtoms(mask=[True for atom in ase_structure])) ucf = UnitCellFilter(ase_structure) qn = QuasiNewton(ucf) qn.run() new_structure = pychemia.external.ase.ase2pychemia(ase_structure) energy = ase_structure.get_potential_energy() forces = ase_structure.get_forces() stress = ase_structure.get_stress() new_properties = { 'energy': float(energy), 'forces': generic_serializer(forces), 'stress': generic_serializer(stress) } self.population.db.update(imember, structure=new_structure, properties=new_properties)
def test_NaCl_minimize(): from ase.calculators.lammpsrun import LAMMPS from ase.spacegroup import crystal from ase.data import atomic_numbers, atomic_masses from ase.optimize import QuasiNewton from ase.constraints import UnitCellFilter from numpy.testing import assert_allclose a = 6.15 n = 4 nacl = crystal(['Na', 'Cl'], [(0, 0, 0), (0.5, 0.5, 0.5)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90]).repeat((n, n, n)) # Buckingham parameters from # https://physics.stackexchange.com/questions/250018 pair_style = 'buck/coul/long 12.0' pair_coeff = ['1 1 3796.9 0.2603 124.90'] pair_coeff += ['2 2 1227.2 0.3214 124.90'] pair_coeff += ['1 2 4117.9 0.3048 0.0'] masses = [ '1 {}'.format(atomic_masses[atomic_numbers['Na']]), '2 {}'.format(atomic_masses[atomic_numbers['Cl']]) ] with LAMMPS( specorder=['Na', 'Cl'], pair_style=pair_style, pair_coeff=pair_coeff, masses=masses, atom_style='charge', kspace_style='pppm 1.0e-5', keep_tmp_files=True, ) as calc: for a in nacl: if a.symbol == 'Na': a.charge = +1. else: a.charge = -1. nacl.set_calculator(calc) assert_allclose(nacl.get_potential_energy(), -1896.216737561538, atol=1e-4, rtol=1e-4) nacl.get_potential_energy() ucf = UnitCellFilter(nacl) dyn = QuasiNewton(ucf, force_consistent=False) dyn.run(fmax=1.0E-2) assert_allclose(nacl.get_potential_energy(), -1897.208861729178, atol=1e-4, rtol=1e-4)
def relax(fname): atoms = read(fname) calc = gp.GPAW(mode=gp.PW(600),kpts=(4,4,4),xc="PBE") atoms.set_calculator(calc) uf = UnitCellFilter(atoms,hydrostatic_strain=True) relaxer = PreconLBFGS( uf, logfile="logfile.log" ) relaxer.run( fmax=0.025,smax=0.003 ) write( fname, atoms )
def relax(atoms, name, calc_mag_state): # relax only along xy-axis to opitmize lattice sf = UnitCellFilter(atoms, mask=[1, 1, 0, 0, 0, 0]) opt = BFGS(sf, trajectory='{0}_relaxed.traj'.format(name), logfile='{0}_relaxed.log'.format(name)) opt.run(fmax=0.05) # until forces < 0.05 eV/atom calc.write('relaxed.gpw') #write gpw file for the magnetic relaxations
def test_unitcellfilter(asap3): cu = bulk('Cu') * (6, 6, 6) cu.calc = asap3.EMT() f = UnitCellFilter(cu, [1, 1, 1, 0, 0, 0]) opt = LBFGS(f) t = Trajectory('Cu-fcc.traj', 'w', cu) opt.attach(t) opt.run(5.0)
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 test_CuZr(self): # This is a test for the potential published in: # Mendelev, Sordelet, Kramer, J. Appl. Phys. 102, 043501 (2007) a = FaceCenteredCubic('Cu', size=[2, 2, 2]) calc = EAM('CuZr_mm.eam.fs', kind='eam/fs') a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) a_Cu = a.cell.diagonal().mean() / 2 #print('a_Cu (3.639) = ', a_Cu) self.assertAlmostEqual(a_Cu, 3.639, 3) a = HexagonalClosedPacked('Zr', size=[2, 2, 2]) a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) a, b, c = a.cell / 2 #print('a_Zr (3.220) = ', norm(a), norm(b)) #print('c_Zr (5.215) = ', norm(c)) self.assertAlmostEqual(norm(a), 3.220, 3) self.assertAlmostEqual(norm(b), 3.220, 3) self.assertAlmostEqual(norm(c), 5.215, 3) # CuZr3 a = L1_2(['Cu', 'Zr'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) self.assertAlmostEqual(a.cell.diagonal().mean() / 2, 4.324, 3) # Cu3Zr a = L1_2(['Zr', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) self.assertAlmostEqual(a.cell.diagonal().mean() / 2, 3.936, 3) # CuZr a = B2(['Zr', 'Cu'], size=[2, 2, 2], latticeconstant=3.3) a.set_calculator(calc) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) self.assertAlmostEqual(a.cell.diagonal().mean() / 2, 3.237, 3)
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_unitcellfilter_hcp(asap3, testdir): cu = bulk('Cu', 'hcp', a=3.6 / 2.0**0.5) cu.cell[1, 0] -= 0.05 cu *= (6, 6, 3) cu.calc = asap3.EMT() print(cu.get_forces()) print(cu.get_stress()) f = UnitCellFilter(cu) opt = MDMin(f, dt=0.01) with Trajectory('Cu-hcp.traj', 'w', cu) as t: opt.attach(t) opt.run(0.2)
def main(runId): db = connect(DB_NAME) row = db.get(id=runId) group = row.group atoms = row.toatoms() niggli_reduce(atoms) calc = EMT() atoms.set_calculator(calc) ucell = UnitCellFilter(atoms) opt = PreconLBFGS(ucell) opt.run(fmax=0.02, smax=0.003) db.write(atoms, group=group, struct_type='relaxed')
def calc_gap(): oraxis = '0,0,1' pot_param = PotentialParameters() ener_per_atom = pot_param.gs_ener_per_atom() selected_grains = GrainBoundary.select().where( GrainBoundary.orientation_axis == oraxis).where( GrainBoundary.boundary_plane != oraxis) f = open('./locenviron/gap_energies.dat', 'a') for gb in selected_grains.order_by(GrainBoundary.angle)[2:]: subgbs = (gb.subgrains.select( GrainBoundary, SubGrainBoundary).where(SubGrainBoundary.potential == 'PotBH.xml').join(GrainBoundary).dicts()) subgbs = [ (16.02 * (subgb['E_gb'] - float(subgb['n_at'] * ener_per_atom['PotBH.xml'])) / (2.0 * subgb['area']), subgb) for subgb in subgbs ] subgbs.sort(key=lambda x: x[0]) try: print subgbs[0][1]['path'] continue target_dir = os.path.join('./grain_boundaries', subgbs[0][1]['path']) struct_file = os.path.join(target_dir, subgbs[0][1]['gbid']) + '_traj.xyz' print struct_file ats = AtomsReader(struct_file)[-1] pot = Potential('IP GAP', param_filename='gp33b.xml') ats.set_calculator(pot) print subgbs[0][1]['n_at'], subgbs[0][1]['area'] strain_mask = [0, 0, 1, 0, 0, 0] ucf = UnitCellFilter(ats, strain_mask) opt = FIRE(ucf) FORCE_TOL = 0.1 opt.run(fmax=FORCE_TOL) gap_en = ats.get_potential_energy() print gap_en print round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) print >> f, round(gb.angle * (180.0 / 3.14159), 3), round( subgbs[0][0], 3), 16.02 * (gap_en - float( subgbs[0][1]['n_at'] * ener_per_atom['gp33b.xml'])) / ( 2.0 * subgbs[0][1]['area']) ats.write('./locenviron/{}.xyz'.format(subgbs[0][1]['gbid'])) except IndexError: print '\t', round(gb.angle * (180.0 / 3.14159), 3), subgbs
def test_md(): import numpy as np import unittest from ase.units import Ry, Ha from ase.calculators.openmx import OpenMX from ase.io.trajectory import Trajectory from ase.optimize import QuasiNewton from ase.constraints import UnitCellFilter from ase.calculators.calculator import PropertyNotImplementedError from ase import Atoms """ Only OpenMX 3.8 or higher version pass this test""" bud = Atoms('CH4', np.array([ [0.000000, 0.000000, 0.100000], [0.682793, 0.682793, 0.682793], [-0.682793, -0.682793, 0.68279], [-0.682793, 0.682793, -0.682793], [0.682793, -0.682793, -0.682793]]), cell=[10, 10, 10]) calc = OpenMX( label='ch4', xc='GGA', energy_cutoff=300 * Ry, convergence=1e-4 * Ha, # Use 'C_PBE19' and 'H_PBE19' for version 3.9 definition_of_atomic_species=[['C', 'C5.0-s1p1', 'C_PBE13'], ['H', 'H5.0-s1', 'H_PBE13']], kpts=(4, 4, 4), eigensolver='Band' ) bud.set_calculator(calc) try: bud.get_stress() except PropertyNotImplementedError as err: raise unittest.SkipTest(err) traj = Trajectory('example.traj', 'w', bud) ucf = UnitCellFilter(bud, mask=[True, True, False, False, False, False]) dyn = QuasiNewton(ucf) dyn.attach(traj.write) dyn.run(fmax=0.1) bud.get_potential_energy() # XXX maybe assert something? traj.close()
def run(self, fmax, smax, smask=None, emin=-np.inf): self.smax = smax self.smask = smask self.emin = emin uf = UnitCellFilter(self.atoms, mask=smask) self.opt = ase.optimize.BFGS(uf, logfile=self._logfile, trajectory=self.trajectory) self.opt.log = self.log self.opt.converged = self.converged self.force_consistent = self.opt.force_consistent self.step0 = self.opt.step self.opt.step = self.step self.opt.run(fmax)
def test_unitcellfilter(asap3): a = 3.6 b = a / 2 cu = Atoms('Cu', cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=1) * (6, 6, 6) cu.calc = asap3.EMT() f = UnitCellFilter(cu, [1, 1, 1, 0, 0, 0]) opt = LBFGS(f) t = Trajectory('Cu-fcc.traj', 'w', cu) opt.attach(t) opt.run(5.0) # HCP: from ase.build import bulk cu = bulk('Cu', 'hcp', a=a / sqrt(2)) cu.cell[1, 0] -= 0.05 cu *= (6, 6, 3) cu.calc = asap3.EMT() print(cu.get_forces()) print(cu.get_stress()) f = UnitCellFilter(cu) opt = MDMin(f, dt=0.01) t = Trajectory('Cu-hcp.traj', 'w', cu) opt.attach(t) opt.run(0.2)
def test_unitcellfilter(): from math import sqrt from ase import Atoms from ase.optimize import LBFGS from ase.constraints import UnitCellFilter from ase.io import Trajectory from ase.optimize.mdmin import MDMin try: from asap3 import EMT except ImportError: pass else: a = 3.6 b = a / 2 cu = Atoms('Cu', cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=1) * (6, 6, 6) cu.set_calculator(EMT()) f = UnitCellFilter(cu, [1, 1, 1, 0, 0, 0]) opt = LBFGS(f) t = Trajectory('Cu-fcc.traj', 'w', cu) opt.attach(t) opt.run(5.0) # HCP: from ase.build import bulk cu = bulk('Cu', 'hcp', a=a / sqrt(2)) cu.cell[1, 0] -= 0.05 cu *= (6, 6, 3) cu.set_calculator(EMT()) print(cu.get_forces()) print(cu.get_stress()) f = UnitCellFilter(cu) opt = MDMin(f, dt=0.01) t = Trajectory('Cu-hcp.traj', 'w', cu) opt.attach(t) opt.run(0.2)
def opt_run(ixsf_path, itraj_path, ixsf_file_name, index): print('%d' % index + ' In directory : %s' % (ixsf_path + ixsf_file_name)) atoms = read(ixsf_path + ixsf_file_name) calc = ANNCalculator(potentials={ "Ga": "Ga.10t-10t.nn", "N": "N.10t-10t.nn" }) atoms.set_calculator(calc) ucf = UnitCellFilter(atoms) opt = BFGS(ucf) traj = Trajectory(itraj_path + 'opt_%i.traj' % index, 'w', atoms) opt.attach(traj, interval=40) opt.run(fmax=0.05)
def main(runID): db = connect(db_name) atoms = db.get_atoms(id=runID) N = 14 calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=(N, N, N), nbands=-50, symmetry={'do_not_symmetrize_the_density': True}) atoms.set_calculator(calc) precon = Exp(mu=1.0, mu_c=1.0) uf = UnitCellFilter(atoms, hydrostatic_strain=True) logfile = "al3mg2{}.log".format(runID) relaxer = PreconLBFGS(uf, logfile=logfile, use_armijo=True, precon=precon) relaxer.run(fmax=0.025, smax=0.003) energy = atoms.get_potential_energy() del db[db.get(id=runID)] db.write(atoms)
def optimize(self, atoms, name): args = self.args if args.constrain_tags: tags = [int(t) for t in args.constrain_tags.split(',')] mask = [t in tags for t in atoms.get_tags()] atoms.constraints = FixAtoms(mask=mask) logfile = self.get_filename(name, 'log') if args.maximum_stress: optimizer = LBFGS(UnitCellFilter(atoms), logfile=logfile) fmax = args.maximum_stress else: optimizer = LBFGS(atoms, logfile=logfile) fmax = args.maximum_force trajectory = Trajectory(self.get_filename(name, 'traj'), 'w', atoms) optimizer.attach(trajectory) optimizer.run(fmax=fmax)
def test_pwscf_calculator(): if not have_ase(): skip("no ASE found, skipping test") elif not have_pwx(): skip("no pw.x found, skipping test") else: pseudo_dir = pj(testdir, prefix, 'pseudo') print(common.backtick("mkdir -pv {p}; cp files/qe_pseudos/*.gz {p}/; \ gunzip {p}/*".format(p=pseudo_dir))) at = get_atoms_with_calc_pwscf(pseudo_dir) print("scf") # trigger calculation here forces = at.get_forces() etot = at.get_potential_energy() stress = at.get_stress(voigt=False) # 3x3 st = io.read_pw_scf(at.calc.label + '.out') assert np.allclose(forces, st.forces) assert np.allclose(etot, st.etot) assert np.allclose(st.stress, -stress * constants.eV_by_Ang3_to_GPa) # files/ase/pw.scf.out.start is a norm-conserving LDA struct, # calculated with pz-vbc.UPF, so the PBE vc-relax will make the cell # a bit bigger print("vc-relax") from ase.optimize import BFGS from ase.constraints import UnitCellFilter opt = BFGS(UnitCellFilter(at)) cell = parse.arr2d_from_txt(""" -1.97281509 0. 1.97281509 0. 1.97281509 1.97281509 -1.97281509 1.97281509 0.""") assert np.allclose(cell, at.get_cell()) opt.run(fmax=0.05) # run only 2 steps cell = parse.arr2d_from_txt(""" -2.01837531 0. 2.01837531 0. 2.01837531 2.01837531 -2.01837531 2.01837531 0""") assert np.allclose(cell, at.get_cell()) # at least 1 backup files must exist: pw.*.0 is the SCF run, backed up # in the first iter of the vc-relax assert os.path.exists(at.calc.infile + '.0')
def test_stress(): # Theoretical infinite-cutoff LJ FCC unit cell parameters vol0 = 4 * 0.91615977036 # theoretical minimum a0 = vol0**(1 / 3) a = bulk('X', 'fcc', a=a0) cell0 = a.get_cell() a.calc = LennardJones() a.set_cell(np.dot(a.cell, [[1.02, 0, 0.03], [0, 0.99, -0.02], [0.1, -0.01, 1.03]]), scale_atoms=True) a *= (1, 2, 3) cell0 *= np.array([1, 2, 3])[:, np.newaxis] a.rattle() # Verify analytical stress tensor against numerical value s_analytical = a.get_stress() s_numerical = a.calc.calculate_numerical_stress(a, 1e-5) s_p_err = 100 * (s_numerical - s_analytical) / s_numerical print("Analytical stress:\n", s_analytical) print("Numerical stress:\n", s_numerical) print("Percent error in stress:\n", s_p_err) assert np.all(abs(s_p_err) < 1e-5) # Minimize unit cell opt = BFGS(UnitCellFilter(a)) opt.run(fmax=1e-3) # Verify minimized unit cell using Niggli tensors g_minimized = np.dot(a.cell, a.cell.T) g_theory = np.dot(cell0, cell0.T) g_p_err = 100 * (g_minimized - g_theory) / g_theory print("Minimized Niggli tensor:\n", g_minimized) print("Theoretical Niggli tensor:\n", g_theory) print("Percent error in Niggli tensor:\n", g_p_err) assert np.all(abs(g_p_err) < 1)
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 optimise_cell(self, fmax=0.01, use_precon=None, use_armijo=None): """ Relax cell to a given force/stress threshold """ if use_precon is None: use_precon = self.parameters.use_precon if use_armijo is None: use_armijo = self.parameters.use_armijo if use_precon: precon = Exp(A=3, use_pyamg=False) else: precon = None uf = UnitCellFilter(self.atoms) if self.parameters.optimizer == 'BFGS': relax = BFGS(uf) elif self.parameters.optimizer == 'FIRE': relax = PreconFIRE(uf, precon=precon) elif self.parameters.optimizer == 'ase-FIRE': relax = ASEFIRE(uf) elif self.parameters.optimizer == 'LBFGS': relax = PreconLBFGS(uf, precon=precon, use_armijo=use_armijo) elif self.parameters.optimizer == 'ase-LBFGS': relax = ASELBFGS(uf) else: parprint("ERROR: unknown optimizer {}. " "Reverting to BFGS".format(self.parameters.optimizer)) relax = BFGS(self.atoms) name = self.atoms.get_chemical_formula() relax.attach( lambda: self.atoms.calc.write(name + '_relax.gpw', mode='all')) relax.attach(lambda: write_atat_input(self.atoms, 'str_last.out')) relax.run(fmax=fmax, steps=100) if not relax.converged(): relax = BFGS(uf) relax.run(fmax=fmax, steps=100) if not relax.converged(): max_force = self.atoms.get_forces() max_force = np.sqrt((max_force**2).sum(axis=1).max()) print('WARNING: optimisation not converged.' + ' Maximum force: %.4f' % max_force)