def relax(input_atoms, ref_db): atoms_string = input_atoms.get_chemical_symbols() # Open connection to the database with reference data db = connect(ref_db) # Load our model structure which is just FCC atoms = FaceCenteredCubic('X', latticeconstant=1.) atoms.set_chemical_symbols(atoms_string) # Compute the average lattice constant of the metals in this individual # and the sum of energies of the constituent metals in the fcc lattice # we will need this for calculating the heat of formation a = 0 ei = 0 for m in set(atoms_string): dct = db.get(metal=m) count = atoms_string.count(m) a += count * dct.latticeconstant ei += count * dct.energy_per_atom a /= len(atoms_string) atoms.set_cell([a, a, a], scale_atoms=True) # Since calculations are extremely fast with EMT we can also do a volume # relaxation atoms.set_calculator(EMT()) eps = 0.05 volumes = (a * np.linspace(1 - eps, 1 + eps, 9))**3 energies = [] for v in volumes: atoms.set_cell([v**(1. / 3)] * 3, scale_atoms=True) energies.append(atoms.get_potential_energy()) eos = EquationOfState(volumes, energies) v1, ef, B = eos.fit() latticeconstant = v1**(1. / 3) # Calculate the heat of formation by subtracting ef with ei hof = (ef - ei) / len(atoms) # Place the calculated parameters in the info dictionary of the # input_atoms object input_atoms.info['key_value_pairs']['hof'] = hof # Raw score must always be set # Use one of the following two; they are equivalent input_atoms.info['key_value_pairs']['raw_score'] = -hof # set_raw_score(input_atoms, -hof) input_atoms.info['key_value_pairs']['latticeconstant'] = latticeconstant # Setting the atoms_string directly for easier analysis atoms_string = ''.join(input_atoms.get_chemical_symbols()) input_atoms.info['key_value_pairs']['atoms_string'] = atoms_string
def test_stress(self): a = FaceCenteredCubic('Au', size=[2,2,2]) calc = EAM('Au-Grochola-JCP05.eam.alloy') a.set_calculator(calc) self.assertArrayAlmostEqual(a.get_stress(), calc.calculate_numerical_stress(a), tol=self.tol) sx, sy, sz = a.cell.diagonal() a.set_cell([sx, 0.9*sy, 1.2*sz], scale_atoms=True) self.assertArrayAlmostEqual(a.get_stress(), calc.calculate_numerical_stress(a), tol=self.tol) a.set_cell([[sx, 0.1*sx, 0], [0, 0.9*sy, 0], [0, -0.1*sy, 1.2*sz]], scale_atoms=True) self.assertArrayAlmostEqual(a.get_stress(), calc.calculate_numerical_stress(a), tol=self.tol)
def C44_Calculator(self, EMT, PARAMETERS): # Return 0 is used when the method is not desired to be used # return 0 """ This method uses the given EMT calculator to calculate and return the value of the matrix element C44 for a system of atoms of a given element type. The calculation is done by using that: C44 = 1 / Volume * d^2/depsilon^2 (E_system) where epsilon is the displacement in one direction of the system along one axis diveded by the highth of the system. """ # An atom object is created and the calculator attached atoms = FaceCenteredCubic(size=(self.Size, self.Size, self.Size), symbol=self.Element) atoms.set_calculator(EMT) # The volume of the sample is calculated Vol = atoms.get_volume() # The value of the relative displacement, epsilon, is set epsilon = 1. / 1000 # The matrix used to change the unitcell by n*epsilon is initialized LMM = numpy.array([[1, 0, -10 * epsilon], [0, 1, 0], [0, 0, 1]]) # The original unit cell is conserved OCell = atoms.get_cell() # The array for storing the energies is initialized E_calc = numpy.zeros(20) # The numerical value of C44 is calculated for i in range(20): # The new system cell based on the pertubation epsilon is set atoms.set_cell(numpy.dot(OCell, LMM), scale_atoms=True) # The energy of the system is calculated E_calc[i] = atoms.get_potential_energy() # The value of LMM is updated LMM[0, 2] += epsilon # A polynomial fit is made for the energy as a function of epsilon # The displaced axis is defined da = numpy.arange(-10, 10) * epsilon # The fit is made Poly = numpyfit.polyfit(da, E_calc, 2) # Now C44 can be estimated from this fit by the second derivative of Poly = a * x^2 + b * x + c , multiplied # with 1 / (2 * Volume) of system C44 = 2. / Vol * Poly[0] return C44
def test_minimum_image_convention(dim): size = 2 if dim == 2: pbc = [True, True, False] else: pbc = [True, True, True] atoms = FaceCenteredCubic(size=[size, size, size], symbol='Cu', latticeconstant=2, pbc=pbc) if dim == 2: cell = atoms.cell.uncomplete(atoms.pbc) atoms.set_cell(cell, scale_atoms=False) d0 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) if dim == 2: U = np.array([[1, 2, 0], [0, 1, 0], [0, 0, 1]]) else: U = np.array([[1, 2, 2], [0, 1, 2], [0, 0, 1]]) assert np.linalg.det(U) == 1 atoms.set_cell(U.T @ atoms.cell, scale_atoms=False) atoms.wrap() d1 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) assert_allclose(d0, d1) vnbrlist = NeighborListMic(atoms.get_positions(), atoms.cell, atoms.pbc) d2 = np.linalg.norm(vnbrlist, axis=1) assert_allclose(d0, d2) nl = NeighborList(np.ones(len(atoms)) * 2 * size * np.sqrt(3), bothways=True, primitive=PrimitiveNeighborList) nl.update(atoms) indices, offsets = nl.get_neighbors(0) d3 = float("inf") * np.ones(len(atoms)) for i, offset in zip(indices, offsets): p = atoms.positions[i] + offset @ atoms.get_cell() d = np.linalg.norm(p - atoms.positions[0]) d3[i] = min(d3[i], d) assert_allclose(d0, d3)
def test_minimum_image_convention(): import numpy as np from numpy.testing import assert_allclose from ase.lattice.cubic import FaceCenteredCubic from ase.neighborlist import mic as NeighborListMic from ase.neighborlist import NeighborList, PrimitiveNeighborList size = 2 atoms = FaceCenteredCubic(size=[size, size, size], symbol='Cu', latticeconstant=2, pbc=(1, 1, 1)) d0 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) U = np.array([[1, 2, 2], [0, 1, 2], [0, 0, 1]]) assert np.linalg.det(U) == 1 atoms.set_cell(U.T @ atoms.cell, scale_atoms=False) atoms.wrap() d1 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) assert_allclose(d0, d1) vnbrlist = NeighborListMic(atoms.get_positions(), atoms.cell, atoms.pbc) d2 = np.linalg.norm(vnbrlist, axis=1) assert_allclose(d0, d2) nl = NeighborList(np.ones(len(atoms)) * 2 * size * np.sqrt(3), bothways=True, primitive=PrimitiveNeighborList) nl.update(atoms) indices, offsets = nl.get_neighbors(0) d3 = float("inf") * np.ones(len(atoms)) for i, offset in zip(indices, offsets): p = atoms.positions[i] + offset @ atoms.get_cell() d = np.linalg.norm(p - atoms.positions[0]) d3[i] = min(d3[i], d) assert_allclose(d0, d3)
def MakeAtoms(elem1, elem2=None): if elem2 is None: elem2 = elem1 a1 = reference_states[elem1]['a'] a2 = reference_states[elem2]['a'] a0 = (0.5 * a1**3 + 0.5 * a2**3)**(1.0 / 3.0) * 1.03 if ismaster: print "Z1 = %i, Z2 = %i, a0 = %.5f" % (elem1, elem2, a0) # 50*50*50 would be big enough, but some vacancies are nice. atoms = FaceCenteredCubic(symbol='Cu', size=(51, 51, 51)) nremove = len(atoms) - 500000 assert nremove > 0 remove = np.random.choice(len(atoms), nremove, replace=False) del atoms[remove] if elem1 != elem2: z = atoms.get_atomic_numbers() z[np.random.choice(len(atoms), len(atoms) / 2, replace=False)] = elem2 atoms.set_atomic_numbers(z) if isparallel: # Move this contribution into position uc = atoms.get_cell() x = mpi.world.rank % cpuLayout[0] y = (mpi.world.rank // cpuLayout[0]) % cpuLayout[1] z = mpi.world.rank // (cpuLayout[0] * cpuLayout[1]) assert (0 <= x < cpuLayout[0]) assert (0 <= y < cpuLayout[1]) assert (0 <= z < cpuLayout[2]) offset = x * uc[0] + y * uc[1] + z * uc[2] new_uc = cpuLayout[0] * uc[0] + cpuLayout[1] * uc[1] + cpuLayout[ 2] * uc[2] atoms.set_cell(new_uc, scale_atoms=False) atoms.set_positions(atoms.get_positions() + offset) # Distribute atoms. Maybe they are all on the wrong cpu, but that will # be taken care of. atoms = MakeParallelAtoms(atoms, cpuLayout) MaxwellBoltzmannDistribution(atoms, T * units.kB) return atoms
def MakeAtoms(elem1, elem2=None): if elem2 is None: elem2 = elem1 a1 = reference_states[elem1]['a'] a2 = reference_states[elem2]['a'] a0 = (0.5 * a1**3 + 0.5 * a2**3)**(1.0/3.0) * 1.03 if ismaster: print "Z1 = %i, Z2 = %i, a0 = %.5f" % (elem1, elem2, a0) # 50*50*50 would be big enough, but some vacancies are nice. atoms = FaceCenteredCubic(symbol='Cu', size=(51,51,51)) nremove = len(atoms) - 500000 assert nremove > 0 remove = np.random.choice(len(atoms), nremove, replace=False) del atoms[remove] if elem1 != elem2: z = atoms.get_atomic_numbers() z[np.random.choice(len(atoms), len(atoms)/2, replace=False)] = elem2 atoms.set_atomic_numbers(z) if isparallel: # Move this contribution into position uc = atoms.get_cell() x = mpi.world.rank % cpuLayout[0] y = (mpi.world.rank // cpuLayout[0]) % cpuLayout[1] z = mpi.world.rank // (cpuLayout[0] * cpuLayout[1]) assert(0 <= x < cpuLayout[0]) assert(0 <= y < cpuLayout[1]) assert(0 <= z < cpuLayout[2]) offset = x * uc[0] + y * uc[1] + z * uc[2] new_uc = cpuLayout[0] * uc[0] + cpuLayout[1] * uc[1] + cpuLayout[2] * uc[2] atoms.set_cell(new_uc, scale_atoms=False) atoms.set_positions(atoms.get_positions() + offset) # Distribute atoms. Maybe they are all on the wrong cpu, but that will # be taken care of. atoms = MakeParallelAtoms(atoms, cpuLayout) MaxwellBoltzmannDistribution(atoms, T * units.kB) return atoms
from ase.neighborlist import NeighborList, PrimitiveNeighborList size = 2 atoms = FaceCenteredCubic(size=[size, size, size], symbol='Cu', latticeconstant=2, pbc=(1, 1, 1)) d0 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) U = np.array([[1, 2, 2], [0, 1, 2], [0, 0, 1]]) assert np.linalg.det(U) == 1 atoms.set_cell(U.T @ atoms.cell, scale_atoms=False) atoms.wrap() d1 = atoms.get_distances(0, np.arange(len(atoms)), mic=True) assert_allclose(d0, d1) vnbrlist = NeighborListMic(atoms.get_positions(), atoms.cell, atoms.pbc) d2 = np.linalg.norm(vnbrlist, axis=1) assert_allclose(d0, d2) nl = NeighborList(np.ones(len(atoms)) * 2 * size * np.sqrt(3), bothways=True, primitive=PrimitiveNeighborList) nl.update(atoms) indices, offsets = nl.get_neighbors(0)
from vasp import Vasp from ase.lattice.cubic import FaceCenteredCubic import numpy as np import matplotlib.pyplot as plt DELTAS = np.linspace(-0.05, 0.05, 5) calcs = [] volumes = [] for delta in DELTAS: atoms = FaceCenteredCubic(symbol='Al') cell = atoms.cell T = np.array([[1 + delta, 0, 0], [0, 1, 0], [0, 0, 1]]) newcell = np.dot(cell, T) atoms.set_cell(newcell, scale_atoms=True) volumes += [atoms.get_volume()] calcs += [ Vasp('bulk/Al-c11-{}'.format(delta), xc='pbe', kpts=[12, 12, 12], encut=350, atoms=atoms) ] Vasp.run() energies = [calc.potential_energy for calc in calcs] # fit a parabola eos = np.polyfit(DELTAS, energies, 2) # first derivative d_eos = np.polyder(eos) print(np.roots(d_eos)) xfit = np.linspace(min(DELTAS), max(DELTAS)) yfit = np.polyval(eos, xfit)
a1 = np.array([0, 1, 1]) d1 = np.cross(a1, d3) a2 = np.array([0, -1, 1]) d2 = np.cross(a2, d3) #create your slab slab = FaceCenteredCubic(directions=[d1, d2, d3], size=(2, 1, 2), symbol=('Pt'), latticeconstant=3.9) #add some vacuum to your slab uc = slab.get_cell() print(uc) uc[2] += [0, 0, 10] #there are ten layers of vacuum uc = slab.set_cell(uc, scale_atoms=False) #view the slab to make sure it is how you expect view(slab) #some positions needed to place the atom in the correct place x1 = 1.379 x2 = 4.137 x3 = 2.759 y1 = 0.0 y2 = 2.238 z1 = 7.165 z2 = 6.439 #Add the adatom to the list of atoms and set constraints of surface atoms. slab += Atoms('N', [((x2 + x1) / 2, y1, z1 + 1.5)]) mask = [atom.symbol == 'Pt' for atom in slab]
atoms = FaceCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], size=(6, 6, 6), symbol="Cu") atoms.set_calculator(EMT()) r = atoms.get_positions() print "Orig position", r[-1] uc = atoms.get_cell() print uc r[-1] = 1.51 * uc[2] atoms.set_positions(r) print atoms.get_potential_energy() p1 = atoms.get_positions()[-1] print "p1:", p1 atoms.set_cell(uc, scale_atoms=True) print atoms.get_potential_energy() p2 = atoms.get_positions()[-1] print "p2:", p2 atoms.set_cell(uc, scale_atoms=False) print atoms.get_potential_energy() p3 = atoms.get_positions()[-1] print "p3:", p3 ReportTest("p2 equals p1", p2[2], p1[2], 1e-6) ReportTest("p3 equals p1", p3[2], p1[2], 1e-6) ReportTest.Summary()
from asap3 import * from ase.lattice.cubic import FaceCenteredCubic import numpy as np set_verbose(1) #AsapThreads() n = 100 atoms = FaceCenteredCubic(symbol='Cu', size=(10, 10, 10)) atoms.set_calculator(EMT()) uc = atoms.get_cell() for i in range(n + 1): factor = float(n - i) / n print "Squeeze factor", factor uc2 = np.array(uc) uc2[2, 2] *= factor atoms.set_cell(uc2, scale_atoms=True) #nbl = NeighborList(10.0, atoms) print atoms.get_potential_energy()
T = atoms.get_kinetic_energy() / (1.5 * len(atoms) * units.kB) print "Temperature is now %.2f K" % (T,) print "Desired temperature reached!" lgv.set_temperature(T_goal*units.kB) for i in range(4): lgv.run(100) s = atoms.get_stress() p = -(s[0] + s[1] + s[2])/3.0 / units.GPa T = atoms.get_kinetic_energy() / (1.5 * len(atoms) * units.kB) print "Pressure is %f GPa, desired pressure is %f GPa (T = %.2f K)" % (p, p_goal, T) dv = (p - p_goal) / bulk print "Adjusting volume by", dv cell = atoms.get_cell() atoms.set_cell(cell * (1.0 + dv/3.0), scale_atoms=True) T = atoms.get_kinetic_energy() / (1.5 * len(atoms) * units.kB) print "Temperature is now %.2f K" % (T,) dyn = NPT(atoms, 5 * units.fs, T_goal * units.kB, p_goal * units.GPa, ttime * units.fs, (ptime*units.fs)**2 * bulk * units.GPa) traj = BundleTrajectory(trajfile, "w", atoms) dyn.attach(traj, interval=50) out = open(out1, "w") temp = [] pres = [] vol = [] for i in xrange(step1):
from vasp import Vasp from ase.lattice.cubic import FaceCenteredCubic import numpy as np import matplotlib.pyplot as plt DELTAS = np.linspace(-0.05, 0.05, 5) calcs = [] volumes = [] for delta in DELTAS: atoms = FaceCenteredCubic(symbol='Al') cell = atoms.cell T = np.array([[1 + delta, 0, 0], [0,1, 0], [0, 0, 1]]) newcell = np.dot(cell, T) atoms.set_cell(newcell, scale_atoms=True) volumes += [atoms.get_volume()] calcs += [Vasp('bulk/Al-c11-{}'.format(delta), xc='pbe', kpts=[12, 12, 12], encut=350, atoms=atoms)] Vasp.run() energies = [calc.potential_energy for calc in calcs] # fit a parabola eos = np.polyfit(DELTAS, energies, 2) # first derivative d_eos = np.polyder(eos) print(np.roots(d_eos)) xfit = np.linspace(min(DELTAS), max(DELTAS)) yfit = np.polyval(eos, xfit) plt.plot(DELTAS, energies, 'bo', xfit, yfit, 'b-')
T = atoms.get_kinetic_energy() / (1.5 * atoms.get_number_of_atoms() * units.kB) print "Temperature is now %.2f K" % (T,) print "Desired temperature reached!" lgv.set_temperature(T_goal*units.kB) for i in range(2): lgv.run(20) s = atoms.get_stress() p = -(s[0] + s[1] + s[2])/3.0 / units.GPa T = atoms.get_kinetic_energy() / (1.5 * atoms.get_number_of_atoms() * units.kB) print "Pressure is %f GPa, desired pressure is %f GPa (T = %.2f K)" % (p, p_goal, T) dv = (p - p_goal) / bulk print "Adjusting volume by", dv cell = atoms.get_cell() atoms.set_cell(cell * (1.0 + dv/3.0)) T = atoms.get_kinetic_energy() / (1.5 * atoms.get_number_of_atoms() * units.kB) print "Temperature is now %.2f K" % (T,) stressstate = array([-2, -1, 0, 0, 0, 0])*p_goal*units.GPa dyn = NPT(atoms, 5 * units.fs, T_goal*units.kB, stressstate, ttime*units.fs, (ptime*units.fs)**2 * bulk * units.GPa) traj = PickleTrajectory("NPT-atoms.traj", "w", atoms) #dyntraj = ParallelHooverNPTTrajectory("NPT-dyn-traj.nc", dyn, interval = 50) dyn.attach(traj, interval=50) #dyn.Attach(dyntraj) out = open(out1, "w") temp = []
from asap3 import * from ase.lattice.cubic import FaceCenteredCubic from asap3.testtools import ReportTest print __doc__ for pbc in (True, False, (1,1,0)): for scale in (True, False): print "Running test with pbc=%s and scale_atoms=%s" % (pbc, scale) atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], size=(6,6,6), symbol="Cu", pbc=pbc) atoms.set_calculator(EMT()) uc = atoms.get_cell() atoms.get_potential_energy() for factor in (1.0, 1.01, 1.02, 1.1, 1.5, 1.49, 1.4, 1.4, 1.0, 0.9): atoms.set_cell(uc * factor, scale_atoms=scale) f = atoms.get_forces() e = atoms.get_potential_energy() atoms2 = Atoms(atoms) atoms2.set_calculator(EMT()) e2 = atoms2.get_potential_energy() f2 = atoms2.get_forces() name = "(factor = %.3f PBC = %s scale_atoms = %s)" % (factor, pbc, scale) ReportTest("Energy "+name, e, e2, 1e-6) maxf = max(abs(f.flat[:] - f2.flat[:])) ReportTest("Forces "+name, maxf, 0.0, 1e-6) ReportTest.Summary()
if __name__ == '__main__': from ase.lattice.cubic import FaceCenteredCubic from ase.lattice.bravais import cross a = np.array([0.5, 0, 0]) c = np.array([0, 1, 0], dtype=np.float) b1 = c - a a = np.array([0, 1, 0], np.float) c = np.array([0, 0.5, 0.5]) b2 = c - a a3 = np.array([2, 1, 1], np.float) a1 = cross(b1, a3) a2 = cross(b2, a3) v211 = FaceCenteredCubic(directions=[a1, a2, a3], miller=(None, None, [2, 1, 1]), symbol='Pd', size=(1, 1, 2), debug=0) uc = v211.get_cell() uc[2][2] += 10.0 v211.set_cell(uc) plot_atoms(v211.repeat((2, 2, 1)))
a1=np.array([0,1,1]) d1=np.cross(a1,d3) a2=np.array([0,-1,1]) d2=np.cross(a2,d3) #create your slab slab =FaceCenteredCubic(directions=[d1,d2,d3], size=(2,1,2), symbol=('Pt'), latticeconstant=3.9) #add some vacuum to your slab uc = slab.get_cell() print(uc) uc[2] += [0,0,10] #there are ten layers of vacuum uc = slab.set_cell(uc,scale_atoms=False) #view the slab to make sure it is how you expect view(slab) #some positions needed to place the atom in the correct place x1 = 1.379 x2 = 4.137 x3 = 2.759 y1 = 0.0 y2 = 2.238 z1 = 7.165 z2 = 6.439 #Add the adatom to the list of atoms and set constraints of surface atoms. slab += Atoms('N', [ ((x2+x1)/2,y1,z1+1.5)])
def BM_LC_Calculator(self, EMT, PARAMETERS): # Return 0 is used when the method is not desired to be used # return 0 """ The method BM_LC_Calculator uses the EMT calculator to find the lattice constant which gives the lowest possible energy for a system of atoms and from a polynomial fit of the energy as a function of the lattice constant it calculates and returns the Bulk modulus, the volume of the system at the lowest possible energy and this energy """ # Three values for the lattice constant, a0, are chosen. The highest and lowest value is chosen so that it # is certain that these are to high/low respectively compared to the "correct" value. This is done by using the # experimental value of the lattice constant, a0_exp, as the middle value and to high/low values are then: # a0_exp +- a0_mod, a0_mod = a0_exp/10 a0_exp = numpy.sqrt(2) * beta * PARAMETERS[self.Element][1] * Bohr a0_mod = a0_exp * 0.10 a0_guesses = numpy.array([a0_exp - a0_mod, a0_exp, a0_exp + a0_mod]) # An atoms object consisting of atoms of the chosen element is initialized atoms = FaceCenteredCubic(size=(self.Size, self.Size, self.Size), symbol=self.Element) atoms.set_calculator(EMT) # An identity matrix for the system is saved to a variable IdentityMatrix = numpy.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) # An array for the energy for the chosen guesses for a0 is initialized: E_guesses = numpy.zeros(5) # The energies are calculated for i in range(3): # Changes the lattice constant for the atoms object atoms.set_cell(a0_guesses[i] * self.Size * IdentityMatrix, scale_atoms=True) # Calculates the energy of the system for the new lattice constant E_guesses[i] = atoms.get_potential_energy() # Bisection is used in order to find a small interval of the lattice constant for the minimum of the energy (an # abitrary interval length is chosen), This is possible because we are certian from theory that there is only # one minimum of the energy function in the interval of interest and thus we wont "fall" into a local minimum # and stay there by accident. while (a0_guesses[2] - a0_guesses[0]) >= self.Tol: if min([E_guesses[0], E_guesses[2]]) == E_guesses[0]: # A new guess for the lattice constant is introduced a0_new_guess = 0.67 * a0_guesses[1] + 0.33 * a0_guesses[2] # The energy for this new guess is calculated atoms.set_cell(a0_new_guess * self.Size * IdentityMatrix, scale_atoms=True) E_new_guess = atoms.get_potential_energy() # A check for changes in the energy minimum is made and the guesses for a0 and their corrosponding # energies are ajusted. if min(E_new_guess, min(E_guesses[0:3])) != E_new_guess: a0_guesses[2] = a0_new_guess E_guesses[2] = E_new_guess else: a0_guesses[0] = a0_guesses[1] a0_guesses[1] = a0_new_guess E_guesses[0] = E_guesses[1] E_guesses[1] = E_new_guess elif min([E_guesses[0], E_guesses[2]]) == E_guesses[2]: # A new guess for the lattice constant is introduced a0_new_guess = 0.33 * a0_guesses[0] + 0.67 * a0_guesses[1] # The energy for this new guess is calculated atoms.set_cell(a0_new_guess * self.Size * IdentityMatrix, scale_atoms=True) E_new_guess = atoms.get_potential_energy() # A check for changes in the energy minimum is made and the guesses for a0 and their corrosponding # energies are ajusted. if min(E_new_guess, min(E_guesses[0:3])) != E_new_guess: a0_guesses[0] = a0_new_guess E_guesses[0] = E_new_guess else: a0_guesses[2] = a0_guesses[1] a0_guesses[1] = a0_new_guess E_guesses[2] = E_guesses[1] E_guesses[1] = E_new_guess # An estimate of the minimum energy can now be found from a second degree polynomial fit through the three # current guesses for a0 and the corresponding values of the energy. Poly = numpyfit.polyfit(a0_guesses, E_guesses[0:3], 2) # The lattice constant corresponding to the lowest energy from the Polynomiel fit is found a0 = -Poly[1] / (2 * Poly[0]) # Now five guesses for a0 and the corresponding energy are evaluated from and around the current a0. a0_guesses = a0 * numpy.array([ 1 - 2 * self.Tol / 5, 1 - self.Tol / 5, 1, 1 + self.Tol / 5, 1 + 2 * self.Tol / 5 ]) for i in range(5): # Changes the lattice constant for the atoms object atoms.set_cell(a0_guesses[i] * self.Size * IdentityMatrix, scale_atoms=True) # Calculates the energy of the system for the new lattice constant E_guesses[i] = atoms.get_potential_energy() # The method EquationOfState is now used to find the Bulk modulus and the minimum energy for the system. # The volume of the sample for the given a0_guesses Vol = (self.Size * a0_guesses)**3 # The equilibrium volume, energy and bulk modulus are calculated (Vol0, E0, B) = EquationOfState(Vol.tolist(), E_guesses.tolist()).fit() return (Vol0, E0, B, Vol0**(1. / 3) / self.Size)
from asap3 import * from ase.lattice.cubic import FaceCenteredCubic import numpy as np set_verbose(1) #AsapThreads() n = 100 atoms = FaceCenteredCubic(symbol='Cu', size=(10,10,10)) atoms.set_calculator(EMT()) uc = atoms.get_cell() for i in range(n+1): factor = float(n - i) / n print "Squeeze factor", factor uc2 = np.array(uc) uc2[2,2] *= factor atoms.set_cell(uc2, scale_atoms=True) #nbl = NeighborList(10.0, atoms) print atoms.get_potential_energy()
from ase.lattice.cubic import FaceCenteredCubic from ase.calculators.emt import EMT from ase.utils.eos import EquationOfState from ase.db import connect db = connect('refs.db') metals = ['Al', 'Au', 'Cu', 'Ag', 'Pd', 'Pt', 'Ni'] for m in metals: atoms = FaceCenteredCubic(m) atoms.set_calculator(EMT()) e0 = atoms.get_potential_energy() a = atoms.cell[0][0] eps = 0.05 volumes = (a * np.linspace(1 - eps, 1 + eps, 9))**3 energies = [] for v in volumes: atoms.set_cell([v**(1. / 3)] * 3, scale_atoms=True) energies.append(atoms.get_potential_energy()) eos = EquationOfState(volumes, energies) v1, e1, B = eos.fit() atoms.set_cell([v1**(1. / 3)] * 3, scale_atoms=True) ef = atoms.get_potential_energy() db.write(atoms, metal=m, latticeconstant=v1**(1. / 3), energy_per_atom=ef / len(atoms))
print "Desired temperature reached!" lgv.set_temperature(T_goal * units.kB) for i in range(2): lgv.run(20) s = atoms.get_stress() p = -(s[0] + s[1] + s[2]) / 3.0 / units.GPa T = atoms.get_kinetic_energy() / (1.5 * atoms.get_number_of_atoms() * units.kB) print "Pressure is %f GPa, desired pressure is %f GPa (T = %.2f K)" % ( p, p_goal, T) dv = (p - p_goal) / bulk print "Adjusting volume by", dv cell = atoms.get_cell() atoms.set_cell(cell * (1.0 + dv / 3.0)) T = atoms.get_kinetic_energy() / (1.5 * atoms.get_number_of_atoms() * units.kB) print "Temperature is now %.2f K" % (T, ) stressstate = array([-2, -1, 0, 0, 0, 0]) * p_goal * units.GPa dyn = NPT(atoms, 5 * units.fs, T_goal * units.kB, stressstate, ttime * units.fs, (ptime * units.fs)**2 * bulk * units.GPa) traj = PickleTrajectory("NPT-atoms.traj", "w", atoms) #dyntraj = ParallelHooverNPTTrajectory("NPT-dyn-traj.nc", dyn, interval = 50) dyn.attach(traj, interval=50) #dyn.Attach(dyntraj) out = open(out1, "w")
from ase.calculators.emt import EMT from ase.eos import EquationOfState from ase.db import connect db = connect('refs.db') metals = ['Al', 'Au', 'Cu', 'Ag', 'Pd', 'Pt', 'Ni'] for m in metals: atoms = FaceCenteredCubic(m) atoms.calc = EMT() e0 = atoms.get_potential_energy() a = atoms.cell[0][0] eps = 0.05 volumes = (a * np.linspace(1 - eps, 1 + eps, 9))**3 energies = [] for v in volumes: atoms.set_cell([v**(1. / 3)] * 3, scale_atoms=True) energies.append(atoms.get_potential_energy()) eos = EquationOfState(volumes, energies) v1, e1, B = eos.fit() atoms.set_cell([v1**(1. / 3)] * 3, scale_atoms=True) ef = atoms.get_potential_energy() db.write(atoms, metal=m, latticeconstant=v1**(1. / 3), energy_per_atom=ef / len(atoms))
print "Test for Ticket #11: https://trac.fysik.dtu.dk/projects/Asap/ticket/11" atoms = FaceCenteredCubic(directions=[[1,0,0],[0,1,0],[0,0,1]], size=(6,6,6), symbol="Cu") atoms.set_calculator(EMT()) r = atoms.get_positions() print "Orig position", r[-1] uc = atoms.get_cell() print uc r[-1] = 1.51*uc[2] atoms.set_positions(r) print atoms.get_potential_energy() p1 = atoms.get_positions()[-1] print "p1:", p1 atoms.set_cell(uc, scale_atoms=True) print atoms.get_potential_energy() p2 = atoms.get_positions()[-1] print "p2:", p2 atoms.set_cell(uc, scale_atoms=False) print atoms.get_potential_energy() p3 = atoms.get_positions()[-1] print "p3:", p3 ReportTest("p2 equals p1", p2[2], p1[2], 1e-6) ReportTest("p3 equals p1", p3[2], p1[2], 1e-6) ReportTest.Summary()