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 calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): Calculator.calculate(self, atoms, properties, system_changes) self.write_input(self.atoms, properties, system_changes) if self.command is None: raise CalculatorSetupError('Please set ${} environment variable '. format('ASE_' + self.name.upper() + '_COMMAND') + 'or supply the command keyword') command = self.command if 'PREFIX' in command: command = command.replace('PREFIX', self.prefix) try: proc = subprocess.Popen(command, shell=True, cwd=self.directory) except OSError as err: # Actually this may never happen with shell=True, since # probably the shell launches successfully. But we soon want # to allow calling the subprocess directly, and then this # distinction (failed to launch vs failed to run) is useful. msg = 'Failed to execute "{}"'.format(command) raise EnvironmentError(msg) from err errorcode = proc.wait() if errorcode: path = os.path.abspath(self.directory) msg = ('Calculator "{}" failed with command "{}" failed in ' '{} with error code {}'.format(self.name, command, path, errorcode)) raise CalculationFailed(msg) self.read_results()
def __init__(self, restart=None, ignore_bad_restart_file=False, label=None, atoms=None, command=None, **kwargs): """File-IO calculator. command: str Command used to start calculation. """ Calculator.__init__(self, restart, ignore_bad_restart_file, label, atoms, **kwargs) if command is not None: self.command = command else: name = 'ASE_' + self.name.upper() + '_COMMAND' self.command = os.environ.get(name, self.command)
def do_monte_carlo(atoms, iteration, outdir, use_gas): tempcalc = EMT() if use_gas == True: atoms.set_calculator( adscalc(tempcalc, temperature=tgas, pressure=pgas, species=species)) else: atoms.set_calculator(tempcalc) Esmc = atoms.get_potential_energy() mc = Metropolis(atoms=atoms, log=None) surfmove = SurfaceMove() mc.attach_move(surfmove) outfilename = "a%05i.amc" % iteration amcd = AtomMonteCarloData(atoms=atoms, surfmove=surfmove, temp=temperature, filename=outfilename, Esmc=Esmc) mc.attach_observer( amcd.accept_move) #Because default event is at acceptmove mc.attach_observer(amcd.reject_move, attime='reject') amcd.accept_move() #We need to write the first configuration, mc.run(nsteps, temp=temperature) amcd.write(os.path.join(outdir, outfilename))
def compute_energy(self, particle, relax_atoms=False): """Compute the energy using EMT. BFGS is used for relaxation. By default, the atoms are NOT relaxed, i.e. the geometry remains unchanged unless this is explicitly stated. Parameters: particle : Nanoparticle relax_atoms : bool """ cell_width = 1e3 cell_height = 1e3 cell_length = 1e3 atoms = particle.get_ase_atoms(exclude_x=True) if not relax_atoms: atoms = atoms.copy() 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 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 calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): Calculator.calculate(self, atoms, properties, system_changes) self.write_input(self.atoms, properties, system_changes) if self.command is None: raise CalculatorSetupError( 'Please set ${} environment variable ' .format('ASE_' + self.name.upper() + '_COMMAND') + 'or supply the command keyword') command = self.command.replace('PREFIX', self.prefix) errorcode = subprocess.call(command, shell=True, cwd=self.directory) if errorcode: raise CalculationFailed('{} in {} returned an error: {}' .format(self.name, self.directory, errorcode)) self.read_results()
def calculate(self, atoms=None, properties=['energy'], system_changes=all_changes): Calculator.calculate(self, atoms, properties, system_changes) self.write_input(self.atoms, properties, system_changes) if self.command is None: raise RuntimeError('Please set $%s environment variable ' % ('ASE_' + self.name.upper() + '_COMMAND') + 'or supply the command keyword') command = self.command.replace('PREFIX', self.prefix) olddir = os.getcwd() try: os.chdir(self.directory) errorcode = subprocess.call(command, shell=True) finally: os.chdir(olddir) if errorcode: raise RuntimeError('%s returned an error: %d' % (self.name, errorcode)) self.read_results()
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 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 EMTFit(elements, parameters): """Create an EMT object from a list (not dict!) of parameters.""" #print "EMTFit called with:" #print " elements =", elements #print " parameters =", parameters parameternames = ['eta2', 'lambda', 'kappa', 'E0', 'V0', 'S0', 'n0'] param = {} for k, v in parameters.items(): if isinstance(k, tuple): k, k2 = k assert k == k2 p = {} for name, value in zip(parameternames, v): p[name] = value # Check for resonable parameters #if p['eta2'] * 1.809 - p['kappa'] < 0.01: # return None param[k] = p #print " new parameters:", param return EMT(param)
def test_vacancy(): from ase import Atoms from ase.optimize import QuasiNewton from ase.neb import NEB from ase.optimize.mdmin import MDMin try: from asap3 import EMT except ImportError: pass else: a = 3.6 b = a / 2 initial = Atoms('Cu4', positions=[(0, 0, 0), (0, b, b), (b, 0, b), (b, b, 0)], cell=(a, a, a), pbc=True) initial *= (4, 4, 4) del initial[0] images = [initial] + [initial.copy() for i in range(6)] images[-1].positions[0] = (0, 0, 0) for image in images: image.calc = EMT() #image.calc = ASAP() for image in [images[0], images[-1]]: QuasiNewton(image).run(fmax=0.01) neb = NEB(images) neb.interpolate() for a in images: print(a.positions[0], a.get_potential_energy()) dyn = MDMin(neb, dt=0.1, trajectory='mep1.traj') #dyn = QuasiNewton(neb) print(dyn.run(fmax=0.01, steps=25)) for a in images: print(a.positions[0], a.get_potential_energy())
def run_md(): # Use Asap for a huge performance increase if it is installed use_asap = True if use_asap: from asap3 import EMT size = 10 else: from ase.calculators.emt import EMT size = 3 # Set up a crystal atoms = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], symbol="Cu", size=(size, size, size), pbc=True) # Describe the interatomic interactions with the Effective Medium Theory atoms.calc = EMT() # Set the momenta corresponding to T=300K MaxwellBoltzmannDistribution(atoms, 300 * units.kB) # We want to run MD with constant energy using the VelocityVerlet algorithm. dyn = VelocityVerlet(atoms, 5 * units.fs) # 5 fs time step. traj = Trajectory('cu.traj', 'w', atoms) dyn.attach(traj.write, interval=10) def printenergy(a=atoms): # store a reference to atoms in the definition. epot, ekin = calcenergy(a) print('Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) ' 'Etot = %.3feV' % (epot, ekin, ekin / (1.5 * units.kB), epot + ekin)) # Now run the dynamics dyn.attach(printenergy, interval=10) printenergy() dyn.run(200)
def calculate_numerical_forces(self, atoms, d=0.001, parallel=True): """Calculate numerical forces using finite difference. All atoms will be displaced by +d and -d in all directions.""" if (str(self.__class__) == "<class 'amp.Amp'>"): if (str(self.model.__class__) == "<class 'amp.model.tflow.NeuralNetwork'>"): disp_atoms = self.generate_disp(atoms, d=d) atomic_energies = self.calculateE_bunch(disp_atoms, parallel=parallel) atomic_energies = np.array( np.split( np.array(np.split(atomic_energies, len(atoms) * 3)), len(atoms))) forces = np.zeros((len(atoms), 3)) for i in range(len(atoms)): for j in range(3): forces [i][j] = \ -1 * ( atomic_energies[i][j][1] - atomic_energies[i][j][0] ) / (2 * d) return forces else: Calculator.calculate(self, atoms) disp_atoms = self.generate_disp(atoms, d=d) log = self._log log('Calculation requested.') from amp.utilities import hash_images images, seq_keys = hash_images(disp_atoms, list_seq=True) keys = list(images.keys())[0] ############### load neighborlist file list most recently used if hasattr(self, "neighborlist_keys"): n_keys = self.neighborlist_keys else: n_keys = None if hasattr(self, "fingerprints_keys"): f_keys = self.fingerprints_keys else: f_keys = None ############# update neighborlists & fingerprints file lists self.neighborlist_keys, self.fingerprints_keys = \ self.descriptor.calculate_fingerprints( images=images, log=log, calculate_derivatives=False, neighborlist_keys = n_keys, fingerprints_keys = f_keys, parallel = self._parallel if parallel else None, ) log('Calculating potential energy...', tic='pot-energy') seq_keys = np.array( np.split( np.array(np.split(np.array(seq_keys), len(atoms) * 3)), len(atoms))) forces = np.zeros((len(atoms), 3)) for a in range(len(atoms)): for i in range(3): eplus = self.model.calculate_energy( self.descriptor.fingerprints[seq_keys[a][i][1]]) self.descriptor.fingerprints.close() eminus = self.model.calculate_energy( self.descriptor.fingerprints[seq_keys[a][i][0]]) self.descriptor.fingerprints.close() forces[a][i] = (eminus - eplus) / (2 * d) log('Potential energy calc ended...', toc='pot-energy') return forces else: return np.array( [[self.numeric_force(atoms, a, i, d) for i in range(3)] for a in range(len(atoms))])
if use_asap: from asap3 import EMT size = 4 else: from ase.calculators.emt import EMT size = 2 # Set up a nanoparticle atoms = FaceCenteredCubic('Cu', surfaces=[[1, 0, 0], [1, 1, 0], [1, 1, 1]], layers=(size, size, size), vacuum=4) # Describe the interatomic interactions with the Effective Medium Theory atoms.set_calculator(EMT()) # Do a quick relaxation of the cluster qn = QuasiNewton(atoms) qn.run(0.001, 10) # Set the momenta corresponding to T=1200K MaxwellBoltzmannDistribution(atoms, 1200 * units.kB) Stationary(atoms) # zero linear momentum ZeroRotation(atoms) # zero angular momentum # We want to run MD using the VelocityVerlet algorithm. # Save trajectory: dyn = VelocityVerlet(atoms, 5 * units.fs, trajectory='moldyn4.traj')
from asap3 import EMT, EMT2013 from asap3.Tools.Timing import Timer from asap3.Tools.ParameterOptimization.EMT import EMT2011Fit timer = Timer() quantities = [ ('lattice_constant_a', 'fcc', 'Pt', 3.92), ('lattice_constant_a', 'hcp', 'Pt', 2.77), ('lattice_ratio_ca', 'hcp', 'Pt', 4.78 / 2.77), ('bulk_modulus', 'fcc', 'Pt', 278.3), ('elastic_anisotropy', 'fcc', 'Pt', 1.594), #('elastic_constant_C11', 'fcc', 'Pt', 346.7), #('elastic_constant_C12', 'fcc', 'Pt', 250.7), ('elastic_constant_C44', 'fcc', 'Pt', 76.5), ('cohesive_energy', 'fcc', 'Pt', 5.84), #('phase_energy', 'fcc-hcp', 'Pt', -0.05), ('surface_energy', 'fcc111', 'Pt', 0.631), ('surface_ratio', 'fcc111-fcc100', 'Pt', 0.631 / 0.892), #('lattice_constant_a', 'l12', ('Pt', 'Cu'), 3.67860), #('heat_of_formation', 'l12', ('Pt', 'Cu'), -0.12331), ] latticeconstants = [('fcc', 'Pt', 3.92), ('hcp', 'Pt', (2.77, 4.78)), ('fcc', 'Cu', 3.5), ('l12', ('Pt', 'Cu'), 3.8)] calc = QuantityCalc(latticeconstants, EMT(), timer, True) for name, structure, elements, value in quantities: value = calc.get_quantity(name, structure, elements) timer.write()
n_test = int(8e3) save_interval = 100 train_traj = "training.traj" test_traj = "test.traj" max_steps = int(2e3) cutoff = Polynomial(6.0, gamma=5.0) num_radial_etas = 6 num_angular_etas = 10 num_zetas = 1 angular_type = "G4" trn = Trainer(cutoff=cutoff) trn.create_Gs(elements, num_radial_etas, num_angular_etas, num_zetas, angular_type) trjbd = TrajectoryBuilder() calc = EMT() train_atoms = trjbd.build_atoms(system, size, temp, calc) calc = EMT() test_atoms = trjbd.build_atoms(system, size, temp, calc) steps, train_traj = trjbd.integrate_atoms( train_atoms, train_traj, n_train, save_interval ) steps, test_traj = trjbd.integrate_atoms( test_atoms, test_traj, n_test, save_interval ) plter = Plotter() energy_noforcetrain = "energy_noforcetrain.png" force_noforcetrain = "force_noforcetrain.png" energy_forcetrain = "energy_forcetrain.png"
from math import sqrt from ase import Atoms from ase.optimize.lbfgs import LBFGS from ase.constraints import StrainFilter, UnitCellFilter from ase.io import PickleTrajectory from ase.optimize.lbfgs import LBFGS 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 = PickleTrajectory('Cu-fcc.traj', 'w', cu) opt.attach(t) opt.run(5.0) # HCP: from ase.lattice.surface import hcp0001 cu = hcp0001('Cu', (1, 1, 2), 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)
def calc(self, **kwargs): from asap3 import EMT return EMT(**kwargs)
except ImportError: pass else: a = 3.6 b = a / 2 initial = Atoms('Cu4', positions=[(0, 0, 0), (0, b, b), (b, 0, b), (b, b, 0)], cell=(a, a, a), pbc=True) initial *= (4, 4, 4) del initial[0] images = [initial] + [initial.copy() for i in range(6)] images[-1].positions[0] = (0, 0, 0) for image in images: image.set_calculator(EMT()) #image.set_calculator(ASAP()) for image in [images[0], images[-1]]: QuasiNewton(image).run(fmax=0.01) neb = NEB(images) neb.interpolate() for a in images: print(a.positions[0], a.get_potential_energy()) dyn = MDMin(neb, dt=0.1, trajectory='mep1.traj') #dyn = QuasiNewton(neb) print(dyn.run(fmax=0.01, steps=25)) for a in images: print(a.positions[0], a.get_potential_energy())
delta=0.01, full_output=True, disp=False) #print "Minimize unit cell:", xopt, fopt, iter, calls if __name__ == '__main__': from asap3 import EMT, units, EMThcpParameters from ase.lattice.cubic import FaceCenteredCubic from ase.lattice.hexagonal import HexagonalClosedPacked print "Calculating cubic constants for Cu" atoms = FaceCenteredCubic(size=(5, 5, 5), symbol='Cu', latticeconstant=3.59495722231) atoms.set_calculator(EMT()) e = ElasticConstants(atoms, 'cubic') print np.array(e) / units.GPa print "Pretending that Cu is hexagonal" e = ElasticConstants(atoms, 'hexagonal', sanity=False) print np.array(e) / units.GPa print "Calculating elastic constants for Ru" atoms = HexagonalClosedPacked(size=(5, 5, 5), symbol='Ru', directions=[[1, -2, 1, 0], [1, 0, -1, 0], [0, 0, 0, 1]]) atoms.set_calculator(EMT(EMThcpParameters())) e = ElasticConstants(atoms, 'hexagonal', minimize=True) print np.array(e) / units.GPa
orthogonal=True)) return images, nlayeratoms if __name__ == '__main__': from asap3 import EMT from ase.data import reference_states debug = False layers = np.arange(5, 14, 2) print "Calculating (100) surface energies with EMT" images, nlayeratoms = get_surface_slabs('Cu', 'fcc100', (6, 6), layers, reference_states[29]['a']) surface_energy = SurfaceEnergy(images, nlayeratoms, EMT(), debug=debug) print "Cu:", surface_energy images, nlayeratoms = get_surface_slabs('Ag', 'fcc100', (6, 6), layers, reference_states[47]['a']) surface_energy = SurfaceEnergy(images, nlayeratoms, EMT(), debug=debug) print "Ag:", surface_energy images, nlayeratoms = get_surface_slabs('Au', 'fcc100', (6, 6), layers, reference_states[79]['a']) surface_energy = SurfaceEnergy(images, nlayeratoms, EMT(), debug=debug) print "Au:", surface_energy print "\nCalculating (111) surface energies with EMT" images, nlayeratoms = get_surface_slabs('Cu', 'fcc111', (6, 6), layers, reference_states[29]['a']) surface_energy = SurfaceEnergy(images, nlayeratoms, EMT(), debug=debug) print "Cu:", surface_energy
if use_asap: from asap3 import EMT size = 10 else: from ase.calculators.emt import EMT size = 3 # Set up a crystal atoms = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], symbol="Cu", size=(size, size, size), pbc=True) # Describe the interatomic interactions with the Effective Medium Theory atoms.calc = EMT() # Set the momenta corresponding to T=300K MaxwellBoltzmannDistribution(atoms, 300 * units.kB) # We want to run MD with constant energy using the VelocityVerlet algorithm. dyn = VelocityVerlet(atoms, 5 * units.fs) # 5 fs time step. def printenergy(a=atoms): # store a reference to atoms in the definition. """Function to print the potential, kinetic and total energy.""" epot = a.get_potential_energy() / len(a) ekin = a.get_kinetic_energy() / len(a) print('Energy per atom: Epot = %.3feV Ekin = %.3feV (T=%3.0fK) ' 'Etot = %.3feV' % (epot, ekin, ekin / (1.5 * units.kB), epot + ekin))
temp_metal_prop = [('lattice_constant_a', 'fcc', 'a', 0.001), ('bulk_modulus', 'fcc', 'B', 0.01), ('elastic_anisotropy', 'fcc', 'A', 0.03), ('elastic_constant_C11', 'fcc', 'C11', 0.03), ('elastic_constant_C12', 'fcc', 'C12', 0.03), ('elastic_constant_C44', 'fcc', 'C44', 0.01), ('cohesive_energy', 'fcc', 'Ecoh', 0.001), ('surface_energy', 'fcc111', 'E111', 0.02), ('surface_energy', 'fcc100', 'E100', 0.02), ('surface_ratio', 'fcc111-fcc100', 'E111_100', 0.01), ('stacking_fault', 'fcc', 'Esf', 0.01), ] for m in ('Al', 'Ni', 'Cu', 'Pd', 'Ag', 'Pt', 'Au'): latticeconstants = [('fcc', m, mp.get(m, 'a'))] quantities = [] for j, (name, struct, id, weight) in enumerate(temp_metal_prop): if id == 'E111_100': value = mp.get(m, 'E111') / mp.get(m, 'E100') else: value = mp.get(m, id) quantities.append((name, struct, m, value, weight)) calculator = EMT() #calculator = EMT2011Fit([m], parameters, 'delta') ParameterPerformance(calculator, quantities, latticeconstants, debug=False)