def test_strain(): from math import sqrt from ase import Atoms from ase.constraints import StrainFilter from ase.optimize.mdmin import MDMin from ase.io import Trajectory 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 = StrainFilter(cu, [1, 1, 1, 0, 0, 0]) opt = MDMin(f, dt=0.01) t = Trajectory('Cu.traj', 'w', cu) opt.attach(t) opt.run(0.001) # 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()) f = StrainFilter(cu) opt = MDMin(f, dt=0.01) t = Trajectory('Cu.traj', 'w', cu) opt.attach(t) opt.run(0.01)
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 get_elastic_constants(pot_path=None, calculator=None, delta=1e-2, symbol="W"): """ return lattice parameter, and cubic elastic constants: C11, C12, 44 using matscipy function pot_path - path to the potential symbol : string Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory default is "W" for tungsten """ unit_cell = bulk(symbol) if (pot_path is not None) and (calculator is None): # create lammps calculator with the potential lammps = LAMMPSlib(lmpcmds=["pair_style eam/fs", "pair_coeff * * %s W" % pot_path], atom_types={'W': 1}, keep_alive=True) calculator = lammps unit_cell.set_calculator(calculator) # simple calculation to get the lattice constant and cohesive energy # alat0 = W.cell[0][1] - W.cell[0][0] sf = StrainFilter(unit_cell) # or UnitCellFilter(W) -> to minimise wrt pos, cell opt = FIRE(sf) opt.run(fmax=1e-4) # max force in eV/A alat = unit_cell.cell[0][1] - unit_cell.cell[0][0] # print("a0 relaxation %.4f --> %.4f" % (a0, a)) # e_coh = W.get_potential_energy() # print("Cohesive energy %.4f" % e_coh) Cij, Cij_err = fit_elastic_constants(unit_cell, symmetry="cubic", delta=delta) Cij = Cij/GPa # unit conversion to GPa elasticMatrix3x3 = Cij[:3, :3] # average of diagonal elements: C11, C22, C33 C11 = elasticMatrix3x3.diagonal().mean() # make mask to extract non diagonal elements mask = np.ones((3, 3), dtype=bool) np.fill_diagonal(mask, False) # average of all non diagonal elements from 1 to 3 C12 = elasticMatrix3x3[mask].mean() # average of diagonal elements from 4 till 6: C44, C55, C66, C44 = Cij[3:, 3:].diagonal().mean() # A = 2.*C44/(C11 - C12) if (pot_path is not None) and (calculator is None): lammps.lmp.close() return alat, C11, C12, C44
def test_rotation(self): for make_atoms, calc in [ # ( lambda a0,x : # FaceCenteredCubic('He', size=[1,1,1], # latticeconstant=3.5 if a0 is None else a0, # directions=x), # LJCut(epsilon=10.2, sigma=2.28, cutoff=5.0, shift=True) ), ( lambda a0,x : FaceCenteredCubic('Au', size=[1,1,1], latticeconstant=a0, directions=x), EAM('Au-Grochola-JCP05.eam.alloy') ), # ( lambda a0,x : Diamond('Si', size=[1,1,1], latticeconstant=a0, # directions=x), # Kumagai() ) #( lambda a0,x : FaceCenteredCubic('Au', size=[1,1,1], # latticeconstant=a0, directions=x), # EAM(potential='Au-Grochola-JCP05.eam.alloy') ), ]: a = make_atoms(None, [[1,0,0], [0,1,0], [0,0,1]]) a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None) \ .run(fmax=self.fmax) latticeconstant = np.mean(a.cell.diagonal()) C6 = measure_triclinic_elastic_constants(a, delta=self.delta, fmax=self.fmax) C11, C12, C44 = Voigt_6x6_to_cubic(C6)/GPa el = CubicElasticModuli(C11, C12, C44) C_m = measure_triclinic_elastic_constants(a, delta=self.delta, fmax=self.fmax)/GPa self.assertArrayAlmostEqual(el.stiffness(), C_m, tol=0.01) for directions in [ [[1,0,0], [0,1,0], [0,0,1]], [[0,1,0], [0,0,1], [1,0,0]], [[1,1,0], [0,0,1], [1,-1,0]], [[1,1,1], [-1,-1,2], [1,-1,0]] ]: a, b, c = directions directions = np.array([ np.array(x)/np.linalg.norm(x) for x in directions ]) a = make_atoms(latticeconstant, directions) a.set_calculator(calc) C = el.rotate(directions) C_check = el._rotate_explicit(directions) C_check2 = rotate_cubic_elastic_constants(C11, C12, C44, directions) C_check3 = \ rotate_elastic_constants(cubic_to_Voigt_6x6(C11, C12, C44), directions) self.assertArrayAlmostEqual(C, C_check, tol=1e-6) self.assertArrayAlmostEqual(C, C_check2, tol=1e-6) self.assertArrayAlmostEqual(C, C_check3, tol=1e-6) C_m = measure_triclinic_elastic_constants(a, delta=self.delta, fmax=self.fmax)/GPa self.assertArrayAlmostEqual(C, C_m, tol=1e-2)
def run_one_in_plane_distance(self, cell_length_x=2.0, cell_length_y=2.0, direction=(0, 0, 1), smax=0.003): # Rotate the atoms object such that the z-direction points along target_z_direction self.atoms = align_direction_with_z(self.atoms, direction=direction) lengths_angles = self.atoms.get_cell_lengths_and_angles() ratio_x = cell_length_x / lengths_angles[0] ratio_y = cell_length_y / lengths_angles[1] cell = self.atoms.get_cell() cell[0, :] *= ratio_x cell[1, :] *= ratio_y self.atoms.set_cell(cell.T, scale_atoms=True) strfilter = StrainFilter(self.atoms, mask=[0, 0, 1, 1, 1, 1]) relaxer = BFGS(self.atoms) V = self.atoms.get_volume() relaxer.run(fmax=smax * V) # Store the results to ase db db = connect(self.db_name) kvp = { "cell_length_x": cell_length_x, "cell_length_y": cell_length_y, "direction_x": direction[0], "direction_y": direction[1], "direction_z": direction[2] } db.write(self.atoms, key_value_pairs=kvp)
def test_strain_fcc(asap3): cu = bulk('Cu', a=a) * (6, 6, 6) cu.calc = asap3.EMT() f = StrainFilter(cu, [1, 1, 1, 0, 0, 0]) opt = MDMin(f, dt=0.01) t = Trajectory('Cu.traj', 'w', cu) opt.attach(t) opt.run(0.001)
def test_strain_hcp(asap3): cu = bulk('Cu', 'hcp', a=a / sqrt(2)) cu.cell[1, 0] -= 0.05 cu *= (6, 6, 3) cu.calc = asap3.EMT() f = StrainFilter(cu) opt = MDMin(f, dt=0.01) opt.run(0.01)
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 test_strain_hcp(asap3): cu = bulk('Cu', 'hcp', a=a / sqrt(2)) cu.cell[1, 0] -= 0.05 cu *= (6, 6, 3) cu.calc = asap3.EMT() f = StrainFilter(cu) opt = MDMin(f, dt=0.01) t = Trajectory('Cu.traj', 'w', cu) opt.attach(t) opt.run(0.01)
def calculate(self, name, atoms): #???? if self.sfmax is not None and self.fmax is not None: # this performs first relaxation of internal degrees of freedom data = OptimizeTask.calculate(self, name, atoms) # writing traj from optimizer does not work for StrainFilter! traj = PickleTrajectory(self.get_filename(name, 'traj'), 'a', atoms) sf = StrainFilter(atoms) while not self.converged(atoms, sfmax=self.sfmax, fmax=self.fmax): # take a step on the cell self.soptimize(name, sf, data, trajectory=traj) # relax internal degrees of freedom OptimizeTask.optimize(self, name, atoms, data, trajectory=traj) data['relaxed energy'] = atoms.get_potential_energy() data['relaxed volume'] = atoms.get_volume() elif self.sfmax is not None: # this performs single-point energy calculation data = OptimizeTask.calculate(self, name, atoms) sf = StrainFilter(atoms) # writing traj from optimizer does not work for StrainFilter! traj = PickleTrajectory(self.get_filename(name, 'traj'), 'w', atoms) self.soptimize(name, sf, data, trajectory=traj) data['relaxed energy'] = atoms.get_potential_energy() data['relaxed volume'] = atoms.get_volume() elif self.fmax is not None: data = OptimizeTask.calculate(self, name, atoms) else: # no optimization if self.fit is None: # only calculate single-point energy if no fit follows data = OptimizeTask.calculate(self, name, atoms) if self.fit is not None: if self.sfmax is not None or self.fmax is not None: # fit after optimization self.fit_volume(name, atoms, data) else: # fit is the only task performed data = self.fit_volume(name, atoms) return data
def test_Grochola(self): a = FaceCenteredCubic('Au', size=[2,2,2]) calc = EAM('Au-Grochola-JCP05.eam.alloy') a.set_calculator(calc) FIRE(StrainFilter(a, mask=[1,1,1,0,0,0]), logfile=None).run(fmax=0.001) a0 = a.cell.diagonal().mean()/2 self.assertTrue(abs(a0-4.0701)<2e-5) self.assertTrue(abs(a.get_potential_energy()/len(a)+3.924)<0.0003) C, C_err = fit_elastic_constants(a, symmetry='cubic', verbose=False) C11, C12, C44 = Voigt_6x6_to_cubic(C) self.assertTrue(abs((C11-C12)/GPa-32.07)<0.7) self.assertTrue(abs(C44/GPa-45.94)<0.5)
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 ase_vol_relax(): Al = bulk('Al', 'fcc', a=4.5, cubic=True) calc = Vasp(xc='LDA') Al.set_calculator(calc) from ase.constraints import StrainFilter sf = StrainFilter(Al) qn = QuasiNewton(sf, logfile='relaxation.log') 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 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 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 relax_cell(atoms, max_step=60, thr=0.01, logfile='relaxation.log', mask=[0, 0, 1, 1, 1, 0], optimizer='BFGS', restart='relax_restart.pckl'): """ mask: [xx,yy,zz,xz,yz,xy] """ from ase.constraints import StrainFilter sf = StrainFilter(atoms, mask=mask) qn = BFGS(sf, logfile='relaxation.log', restart=restart) qn.run(fmax=thr, steps=max_step) return atoms
def test_strain_emt(): """This test checks that the StrainFilter works using the default built-in EMT calculator.""" import numpy as np from ase.constraints import StrainFilter from ase.optimize.mdmin import MDMin from ase.calculators.emt import EMT from ase.build import bulk cu = bulk('Cu', 'fcc', a=3.6) class EMTPlus(EMT): def get_stress(self, atoms): return np.zeros(6) cu.calc = EMTPlus() f = StrainFilter(cu) opt = MDMin(f, dt=0.01) opt.run(0.1, steps=2)
def run_single(name="Si", prototype=None): sb = StructureBuilder() mater = sb.get_structure(formula=name, prototype=prototype) parprint("Before", mater) if len(mater) != 1: return mater = mater[0] base_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "../../tmp/", "{}-{}/".format(name, prototype)) if rank == 0: if not os.path.exists(base_dir): os.makedirs(base_dir) world.barrier() calc = GPAW( mode=dict(name="pw", ecut=800), occupations=dict(name="fermi-dirac", width=0.01), basis="dzp", xc="PBE", kpts=dict(gamma=True, density=4.0), # Very rough k-density txt=os.path.join(base_dir, "{}-{}.txt".format(name, prototype))) mater.set_calculator(calc) sf = StrainFilter(mater) traj_filename = os.path.join(base_dir, "{}-{}.traj".format(name, prototype)) log_filename = os.path.join(base_dir, "{}-{}.log".format(name, prototype)) # Overwrite file with open(traj_filename, "w") as _: pass with open(log_filename, "w") as _: pass opt_strain = ase.optimize.BFGS(sf, trajectory=traj_filename, logfile=log_filename) opt_force = ase.optimize.BFGS(mater, trajectory=traj_filename, logfile=log_filename) opt_strain.run(fmax=0.02) # opt_force.run(fmax=0.02) parprint("After", mater)
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 fit_lattice_parameters_with_stress_tensor(cell, calculator, log_dir=None, verbose=True): """Optimizes the bulk lattice parameters using the stress tensor method. Requires a calculator that supports computing the stress tensor (e.g., GPAW using a PW mode). """ # Print header if verbose: print("BASC: FITTING LATTICE PARAMETERS (STRESS TENSOR METHOD)") print("Compound: %s" % cell.get_name()) print("calculator: %s" % str(calculator)) print("log_dir: %s" % log_dir) # Make log dir try: os.mkdir(log_dir) except OSError: pass # Set up optimizer relaxed_cell = cell.copy() relaxed_cell.set_calculator(calculator) sf = StrainFilter(relaxed_cell) dyn = BFGS(sf) # Run the optimizer dyn.run(fmax=0.005) # Save and return if verbose: ase.io.write("%s/lattice_final.cif" % log_dir, relaxed_cell) return relaxed_cell
def vasp_relax_cell(atoms, max_step=60, thr=0.01, logfile='relaxation.log', mask=[0, 0, 1, 1, 1, 0], optimizer='BFGS', restart='relax_restart.pckl'): """ relax cell which are far from equibrium. """ from ase.constraints import StrainFilter calc = atoms.calc nelmdl = calc.int_params['nelmdl'] ibrion = calc.int_params['ibrion'] sigma = calc.float_params['sigma'] if sigma is None: sigma = 0.1 ediff = calc.exp_params['ediff'] if ediff is None: ediff = 1e-4 ediffg = calc.exp_params['ediffg'] if ediffg is None: ediffg = -0.01 ldipol = calc.bool_params['ldipol'] if ldipol is None: ldipol = False nsw = calc.int_params['nsw'] #first do this calc.set(nelmdl=6, nelmin=-9, ediff=1e-3, ediffg=-0.3, nsw=20, ibrion=2, sigma=sigma * 3, ldipol=False) atoms.set_calculator(calc) sf = StrainFilter(atoms, mask=mask) if optimizer == 'BFGSLineSearch': qn = BFGSLineSearch(sf, logfile='relaxation.log', use_free_energy=False) else: qn = BFGS(sf, logfile='relaxation.log') qn.run(fmax=0.3, steps=5) # then increase the accuracy. calc.set(nelmdl=nelmdl, nelmin=5, ediff=ediff, ediffg=ediffg, ibrion=ibrion, sigma=sigma, ldipol=ldipol, nsw=nsw) calc.set(istart=1) atoms.set_calculator(calc) sf = StrainFilter(atoms, mask=mask) qn = BFGS(sf, logfile='relaxation.log', restart=restart) qn.run(fmax=0.01, steps=max_step) return atoms
def main( argv ): runID = int( argv[0] ) params = { "cutoff":200, "kpts":1, "n_atoms_to_shift":0, "nbands":-1, "relax":False, "gamma":False } db_name = "none" dbPaths = [ "/home/ntnu/davidkl/GPAWTutorial/Exercises/AlOutOfPositionEnergy/aloutofpos.db", "aloutofpos.db" ] # Find the correct database for name in dbPaths: if ( os.path.isfile(name) ): db_name = name break if ( db_name == "none" ): print ("Could not find database") return # Read parameters from database con = sq.connect( db_name ) cur = con.cursor() cur.execute( "SELECT cutoff,kpts,n_atoms_to_shift,nbands,relax,gamma FROM simpar WHERE ID=?", (runID,) ) dbparams = cur.fetchall()[0] con.close() # Transfer the parameters to the params dictionary params["cutoff"] = dbparams[0] params["kpts"] = dbparams[1] params["n_atoms_to_shift"] = dbparams[2] params["nbands"] = dbparams[3] params["relax"] = dbparams[4] params["gamma"] = dbparams[5] if ( params["gamma"] ): kpts = {"size":(params["kpts"],params["kpts"],params["kpts"]), "gamma":True} else: kpts = (params["kpts"],params["kpts"],params["kpts"]) # Initialize the calculator calc = gp.GPAW( mode=gp.PW(params["cutoff"]), xc="PBE", nbands=params["nbands"], kpts=kpts ) # Initialize the atoms aluminum = build.bulk( "Al", crystalstructure="fcc" ) P = build.find_optimal_cell_shape_pure_python( aluminum.cell, 32, "sc" ) aluminum = build.make_supercell( aluminum, P ) aluminum = moveAtoms( aluminum, params["n_atoms_to_shift"], alat=4.05 ) aluminum.set_calculator( calc ) if ( params["relax"] ): logfile = "logilfe%d.log"%(runID) trajfile = "optTrajectory%d.traj"%(runID) traj = Trajectory( trajfile, 'w', aluminum ) # Optimize internal positions relaxer = BFGS( aluminum, logfile=logfile ) relaxer.attach( traj ) relaxer.run( fmax=0.05 ) # Optimize cell strain = StrainFilter( aluminum ) relaxer = BFGS( strain, logfile=logfile ) relaxer.attach( traj ) relaxer.run( fmax=0.05 ) energy = aluminum.get_potential_energy() # Add results to the database asedb = ase.db.connect( db_name ) lastID = asedb.write( aluminum, relaxed=True ) # Update the parameters in the database con = sq.connect( db_name ) cur = con.cursor() cur.execute( "UPDATE simpar SET status=?,systemID=? WHERE ID=?", ("finished",lastID,runID) ) con.commit() con.close()
import sys sys.path.insert(0, '.') import params a = params.cryst.copy() # ***** Find eqm. lattice constant ****** # find the equilibrium lattice constant by minimising atoms wrt virial # tensor given by SW pot (possibly replace this with parabola fit in # another script and hardcoded a0 here) a.set_calculator(params.calc) if hasattr(params, 'relax_bulk') and params.relax_bulk: print('Minimising bulk unit cell...') opt = FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0])) opt.run(fmax=params.bulk_fmax) a0 = a.cell[0, 0] print('Lattice constant %.3f A\n' % a0) a.set_calculator(params.calc) # ******* Find elastic constants ******* # Get 6x6 matrix of elastic constants C_ij C = measure_triclinic_elastic_constants(a, optimizer=FIRE, fmax=params.bulk_fmax) print('Elastic constants (GPa):') print((C / units.GPa).round(0))
def main(argv): relax_mode = "both" # both, cell, positions system = "AlMg" runID = int(argv[0]) nkpt = int(argv[1]) single_point = False if (len(argv) >= 3): single_point = (int(argv[2]) == 1) print("Running job: %d" % (runID)) db_paths = [ "/home/ntnu/davidkl/GPAWTutorial/CE/almg_fcc_vac.db", "almg_fcc_vac.db", "/home/davidkl/GPAWTutorial/CE/almg_fcc_vac.db" ] for path in db_paths: if (os.path.isfile(path)): db_name = path break #db_name = "almgsi_test_db.db" db = ase.db.connect(db_name) name = db.get(id=runID).key_value_pairs["name"] new_run = not db.get(id=runID).key_value_pairs["started"] # Update the databse db.update(runID, started=True, converged=False) db.update(runID, nkpt=nkpt) atoms = db.get_atoms(id=runID) atoms = delete_vacancies(atoms) if (len(atoms) == 1): nbands = -10 else: nbands = "120%" kpts = (nkpt, nkpt, nkpt) try: restart_name = SaveRestartFiles.restart_name(name) atoms, calc = gp.restart(restart_name) except: calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=kpts, nbands=nbands) atoms.set_calculator(calc) if (single_point): calc = gp.GPAW(mode=gp.PW(500), xc="PBE", kpts=kpts, nbands=nbands) atoms.set_calculator(calc) logfile = "almg_fcc_vac{}.log".format(name) traj = "almg_bcc{}.traj".format(name) db.update(runID, trajfile=traj) trajObj = Trajectory(traj, 'w', atoms) #storeBest = SaveToDB(db_name,runID,name,mode=relax_mode) save_calc = SaveRestartFiles(calc, name) update_db_info = UpdateDBInfo(db_name, runID, atoms) volume = atoms.get_volume() try: precon = Exp(mu=1.0, mu_c=1.0) fmax = 0.025 smax = 0.003 if (relax_mode == "both"): relaxer = PreconLBFGS(atoms, logfile=logfile, use_armijo=True, variable_cell=True) elif (relax_mode == "positions"): #relaxer = SciPyFminCG( atoms, logfile=logfile ) relaxer = BFGS(atoms, logfile=logfile) elif (relax_mode == "cell"): str_f = StrainFilter(atoms, mask=[1, 1, 1, 0, 0, 0]) relaxer = BFGS(str_f, logfile=logfile) fmax = smax * volume relaxer.attach(trajObj) #relaxer.attach( storeBest, interval=1, atoms=atoms ) relaxer.attach(save_calc, interval=1) relaxer.attach(update_db_info, interval=1) if (not single_point): if (relax_mode == "both"): relaxer.run(fmax=fmax, smax=smax) else: relaxer.run(fmax=fmax) energy = atoms.get_potential_energy() orig_atoms = db.get_atoms(runID) single_p_calc = SinglePointCalculator(orig_atoms, energy=energy) orig_atoms.set_calculator(single_p_calc) kvp = db.get(name=name).key_value_pairs del db[runID] newID = db.write(orig_atoms, key_value_pairs=kvp) if (relax_mode == "positions"): db.update(newID, converged_force=True) elif (relax_mode == "cell"): db.update(newID, converged_stress=True) else: db.update(newID, converged_stress=True, converged_force=True) db.update(newID, single_point=single_point) db.update(newID, restart_file=SaveRestartFiles.restart_name(name)) row = db.get(id=newID) conv_force = row.get("converged_force", default=0) conv_stress = row.get("converged_stress", default=0) if ((conv_force == 1) and (conv_stress == 1) and (nkpt == 4)): db.update(newID, converged=True) except Exception as exc: print(exc)
import numpy as np from ase.build import bulk from ase.optimize import BFGS from ase.io import Trajectory from ase.constraints import StrainFilter from gpaw import GPAW, PW co = bulk('Co') co.set_initial_magnetic_moments([1.6, 1.6]) co.calc = GPAW(mode=PW(700), xc='PBE', kpts=(8, 8, 4), txt='co.txt') BFGS(StrainFilter(co)).run(0.005) a0 = co.cell[0, 0] c0 = co.cell[2, 2] traj = Trajectory('co.traj', 'w') eps = 0.01 for a in a0 * np.linspace(1 - eps, 1 + eps, 3): for c in c0 * np.linspace(1 - eps, 1 + eps, 3): co.set_cell(bulk('Co', a=a, covera=c / a).cell, scale_atoms=True) co.get_potential_energy() traj.write(co)
#!/usr/bin/env python3 from ase import Atom, Atoms from ase.build import bulk, fcc100, add_adsorbate, add_vacuum from ase.calculators.vasp import Vasp from ase.calculators.kim.kim import KIM from ase.calculators.qmmm import ForceQMMM, RescaledCalculator from ase.constraints import StrainFilter from ase.optimize import LBFGS from ase.visualize import view atoms = bulk("Pd", "fcc", a=3.5, cubic=True) atoms.calc = KIM("MEAM_LAMMPS_JeongParkDo_2018_PdMo__MO_356501945107_000") opt = LBFGS(StrainFilter(atoms), logfile=None) opt.run(0.03, steps=30) length = atoms.cell.cellpar()[0] atoms = fcc100("Pd", (2,2,5), a=length, vacuum=10, periodic=True) add_adsorbate(atoms, Atoms([Atom("Mo")]), 1.2) qm_mask = [len(atoms)-1, len(atoms)-2] qm_calc = Vasp(directory="./qmmm") mm_calc = KIM("MEAM_LAMMPS_JeongParkDo_2018_PdMo__MO_356501945107_000") mm_calc = RescaledCalculator(mm_calc, 1, 1, 1, 1) qmmm = ForceQMMM(atoms, qm_mask, qm_calc, mm_calc, buffer_width=3) qmmm.initialize_qm_buffer_mask(atoms) atoms.pbc=True atoms.calc = qmmm print(atoms.get_forces())
"""This test checks that the StrainFilter works using the default built-in EMT calculator.""" from ase.constraints import StrainFilter from ase.optimize.mdmin import MDMin from ase.calculators.emt import EMT from ase.structure import bulk cu = bulk('Cu', 'fcc', a=3.6) cu.set_calculator(EMT(fakestress=True)) f = StrainFilter(cu) opt = MDMin(f, dt=0.01) opt.run(0.1, steps=2)
from jasp import * from ase.lattice import bulk from ase.optimize import BFGS as QuasiNewton Al = bulk('Al', 'fcc', a=4.5, cubic=True) with jasp('bulk/Al-lda-ase', xc='LDA', atoms=Al) as calc: from ase.constraints import StrainFilter sf = StrainFilter(Al) qn = QuasiNewton(sf, logfile='relaxation.log') 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() print calc
def test_mix_eam_alloy(self): if False: source, parameters, F, f, rep = read_eam("CuAu_Zhou.eam.alloy", kind="eam/alloy") source1, parameters1, F1, f1, rep1 = mix_eam( ["Cu_Zhou.eam.alloy", "Au_Zhou.eam.alloy"], "eam/alloy", "weight") write_eam(source1, parameters1, F1, f1, rep1, "CuAu_mixed.eam.alloy", kind="eam/alloy") calc0 = EAM('CuAu_Zhou.eam.alloy') calc1 = EAM('CuAu_mixed.eam.alloy') a = FaceCenteredCubic('Cu', size=[2, 2, 2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = FaceCenteredCubic('Cu', size=[2, 2, 2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = FaceCenteredCubic('Au', size=[2, 2, 2]) a.set_calculator(calc0) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = FaceCenteredCubic('Au', size=[2, 2, 2]) a.set_calculator(calc1) FIRE(StrainFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = L1_2(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = L1_2(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = L1_2(['Cu', 'Au'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = L1_2(['Cu', 'Au'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) a = B1(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc0) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e0 = a.get_potential_energy() / len(a) a = B1(['Au', 'Cu'], size=[2, 2, 2], latticeconstant=4.0) a.set_calculator(calc1) FIRE(UnitCellFilter(a, mask=[1, 1, 1, 0, 0, 0]), logfile=None).run(fmax=0.001) e1 = a.get_potential_energy() / len(a) self.assertTrue(e0 - e1 < 0.0005) os.remove("CuAu_mixed.eam.alloy")