Ejemplo n.º 1
0
def create_atoms(n_a, n_b, n_c):
    unitcell = bulk('Ar', 'fcc', 1.5, orthorhombic=True)  # ===> epsilon unit
    atoms_a = unitcell
    for i in range(n_a - 1):
        atoms_a = stack(atoms_a, unitcell, axis=0)
    atoms_b = atoms_a
    for j in range(n_b - 1):
        atoms_b = stack(atoms_b, atoms_a, axis=1)
    all_atoms = atoms_b
    for k in range(n_c - 1):
        all_atoms = stack(all_atoms, atoms_b, axis=2)
    return all_atoms
Ejemplo n.º 2
0
def test_surface_stack():
    from ase.build.surface import _all_surface_functions
    from ase.build import stack
    from ase.calculators.calculator import compare_atoms


    # The purpose of this test is to test the stack() function and verify
    # that the various surface builder functions produce configurations
    # consistent with stacking.

    d = _all_surface_functions()
    exclude = {'mx2', 'graphene'}  # mx2 and graphene are not like the others

    for name in sorted(d):
        if name in exclude:
            continue

        func = d[name]

        def has(var):
            c = func.__code__
            return var in c.co_varnames[:c.co_argcount]

        for nlayers in range(1, 7):
            atoms = func('Au', size=(2, 2, nlayers), periodic=True, a=4.0)
            big_atoms = func('Au', size=(2, 2, 2 * nlayers), periodic=True, a=4.0)
            stacked_atoms = stack(atoms, atoms)

            changes = compare_atoms(stacked_atoms, big_atoms, tol=1e-11)
            if not changes:
                print('OK', name, nlayers)
                break
        else:
            assert 0, 'Unstackable surface {}'.format(name)
Ejemplo n.º 3
0
def construct_db_clean():
    db = connect(DB_NAME)
    for rep in range(1, 12):
        mgsi = get_mgsi() * (1, 1, rep)
        al = get_al() * (1, 1, rep)
        merged = stack(al, mgsi, axis=2)
        db.write(merged, surface=1)
Ejemplo n.º 4
0
def construct_db_mixed():
    db = connect(DB_NAME)
    for rep in range(9, 12):
        mgsi = get_mgsi() * (rep, 1, 1)
        al = get_al() * (rep, 1, 1)
        merged = stack(al, mgsi, axis=0)
        db.write(merged, surface=0)
Ejemplo n.º 5
0
def construct_db_mgsi():
    db = connect(DB_NAME)
    for rep in range(1, 12):
        mgsi = get_mgsi() * (1, 1, rep)
        mgsi2 = get_mgsi()
        mgsi2.rotate(90, "x")
        mgsi2.wrap()
        mgsi2 *= (1, 1, rep)
        merged = stack(mgsi, mgsi2, axis=2)
        db.write(merged, surface=2)
Ejemplo n.º 6
0
    def merge_2D_slabs(b):
        global view, view_2, struc1, struc2, s1, s2, slabgen1, slabgen2, s3, view_3, pressed
        pressed = 1
        a1_tmp = (s2.cell.lengths()[0] / (s1.cell.lengths()[0]))
        a2_tmp = (s2.cell.lengths()[1] / (s1.cell.lengths()[1]))
        a1 = 1
        b1 = 1
        a2 = 1
        b2 = 1
        if (a1_tmp >= 1):
            a1 = int(np.round(a1))
        else:
            b1 = int(np.round(1 / a1))

        if (a2_tmp >= 1):
            a2 = int(np.round(a1))
        else:
            b2 = int(np.round(1 / a1))

        s1 = s1.repeat((a1, a2, 1))
        s2 = s2.repeat((b1, b2, 1))

        if (substrate_slide.value == 1):
            cell_final = s1.cell.copy()
            fix_val = 0
        else:
            cell_final = s2.cell.copy()
            fix_val = 1

        vac = gap_slide.value / 2
        s1.center(vacuum=vac, axis=2)
        s2.center(vacuum=vac, axis=2)

        s3, s1_strain, s2_strain = stack(s1,
                                         s2,
                                         axis=2,
                                         fix=0,
                                         cell=cell_final,
                                         maxstrain=None,
                                         distance=None,
                                         output_strained=True)

        strain1 = np.sqrt(((s1_strain.cell - s1.cell).sum(axis=0)**2).sum())
        strain2 = np.sqrt(((s2_strain.cell - s2.cell).sum(axis=0)**2).sum())

        view_3 = nglview.show_ase(s3)
        view_3.add_representation('unitcell')
        view_3.background = 'black'
        view_3.camera = "orthographic"

        with output_1:
            output_1.clear_output()
            print("Strain on cell of Material 1 is", strain1)
            print("Strain on cell of Material 2 is", strain2)
            display(view_3)
Ejemplo n.º 7
0
def create_atoms(n_a, n_b, n_c):
    unitcell = bulk(
        'Ar', 'fcc', np.power(2, (2. / 3)),
        cubic=True)  #,orthorhombic=True)  # ===>  1.122 sigma (from geometry)
    # unitcell = bulk('Ar', 'fcc', 5.4, orthorhombic=True)
    # visualize.view(unitcell)
    # print unitcell.get_cell()
    atoms_a = unitcell
    for i in range(n_a - 1):
        atoms_a = stack(atoms_a, unitcell, axis=0)
    atoms_b = atoms_a
    for j in range(n_b - 1):
        atoms_b = stack(atoms_b, atoms_a, axis=1)
    all_atoms = atoms_b
    for k in range(n_c - 1):
        all_atoms = stack(all_atoms, atoms_b, axis=2)
    # print all_atoms.get_cell()
    print("The cell is= ", all_atoms.get_cell())
    # visualize.view(all_atoms)
    return all_atoms
def mgsi(interface):
    atoms = bulk('Al', cubic=True)
    mgsi = atoms.copy()

    miller = (0, 0, 1)
    if interface == SILICON or interface == MAGNESIUM:
        miller = (1, 0, 0)

    tags, levels = get_layers(mgsi, miller)
    for i, atom in enumerate(mgsi):
        if interface == SILICON or interface == ALTERNATING:
            if tags[i] % 2 == 0:
                atom.symbol = 'Mg'
            else:
                atom.symbol = 'Si'
        elif interface == MAGNESIUM:
            if tags[i] % 2 == 0:
                atom.symbol = 'Si'
            else:
                atom.symbol = 'Mg'

    # Tag all atoms to -1
    for atom in mgsi:
        atom.tag = -1

    mgsi = mgsi * (4, 4, 4)
    matrix = atoms.copy()
    for atom in matrix:
        atom.tag = -1
    matrix = matrix * (4, 4, 4)
    active_area = atoms.copy()
    active_area = active_area * (4, 4, 4)
    tags, layers = get_layers(active_area, (1, 0, 0))
    for t, atom in zip(tags, active_area):
        atom.tag = t

    # Stack togeter
    atoms = stack(mgsi, active_area, axis=0)
    atoms = stack(atoms, matrix, axis=0)
    atoms = wrap_and_sort_by_position(atoms)
    write(f"data/mgsi_active_matrix_{interface}_interface.xyz", atoms)
Ejemplo n.º 9
0
cell = a_0 * identity(3)
atoms.set_cell(cell, scale_atoms=True)
unitCell = atoms.get_cell()

atomsLeft = Atoms(atoms)
atomsRight = Atoms(atoms)
atomsRight.rotate((0, 0, np.pi / 12), rotate_cell=True)

print atomsLeft.get_positions()
print atomsRight.get_positions()
print atomsLeft.get_cell()
print atomsRight.get_cell()

stackedAtoms = stack(atomsLeft,
                     atomsLeft,
                     axis=0,
                     cell=None,
                     fix=0,
                     maxstrain=None)
stackedAtoms = stack(stackedAtoms,
                     atomsLeft,
                     axis=0,
                     cell=None,
                     fix=0,
                     maxstrain=None)
stackedAtoms = stack(stackedAtoms,
                     atomsRight,
                     axis=0,
                     cell=None,
                     fix=0,
                     maxstrain=None)
stackedAtoms = stack(stackedAtoms,
Ejemplo n.º 10
0
    def __call__(self, pot="test.set", X="Ni"):
        """
        Objective function for fitting a single element (Ni) eam.
            Arguments:
            pot (str)   : Name of the relevant potential file.
            X (str)     : Element name.
        """
        # Starting points for lattice params
        # Every lammps command needs to define a pair_style and corresponding potential.
        cmds0 = ["pair_style eam/alloy", "pair_coeff * * {} {}".format(pot, X)]

        r = 3  # Supercell size
        # FCC structure properties.
        Ni_fcc_prim = bulk(X, "fcc", cubic=True, a=self.a_fcc)
        Ni_fcc = make_supercell(Ni_fcc_prim, r * np.eye(3))
        N_fcc = Ni_fcc.get_global_number_of_atoms()
        # Initial cell relaxation
        # cmds = cmds0 +\
        #     ["fix 1 all box/relax iso 0.0 vmax 0.001",
        #     "min_style cg",
        #     "minimize 1e-12 1e-8 10000 100000"] # minimize etol ftol maxiter maxeval
        # lammps = LAMMPSlibExt(lmpcmds=cmds,log_file="test_fcc_0.log",keep_alive=True)
        # Ni_fcc.calc = lammps
        # E_fcc = Ni_fcc.get_total_energy()
        # a = convert(Ni_fcc.calc.lmp.extract_variable("a",None,0),"distance",Ni_fcc.calc.units,"ASE")
        # b = convert(Ni_fcc.calc.lmp.extract_variable("b",None,0),"distance",Ni_fcc.calc.units,"ASE")
        # c = convert(Ni_fcc.calc.lmp.extract_variable("c",None,0),"distance",Ni_fcc.calc.units,"ASE")
        # a_fcc = (a+b+c)/3.
        # Ni_fcc.set_cell([a,a,a],scale_atoms=True) # Update cell to optimal structure.
        # Bulk modulus
        # cmds = cmds0 +\
        #     ["min_style cg",
        #     "minimize 1e-12 1e-8 10000 100000"]

        # Geometry optimisation
        lammps_inst = LAMMPSlibExt(lmpcmds=cmds0,
                                   log_file="test_fcc.log",
                                   keep_alive=True)
        Ni_fcc.calc = lammps_inst
        try:
            (a_fcc, b_fcc, c_fcc), E_fcc = geometry_opt(Ni_fcc, tol=1.e-6)
        except Exception:
            return 1.e8 * np.ones(self.n_out)
        Ni_fcc.set_cell([a_fcc, a_fcc, a_fcc],
                        scale_atoms=True)  # Update cell to optimal structure.
        # Bulk modulus
        lammps_inst = LAMMPSlibExt(lmpcmds=cmds0,
                                   log_file="test_fcc_B.log",
                                   keep_alive=True)
        Ni_fcc.calc = lammps_inst
        eos = calculate_eos(Ni_fcc, npoints=12, eps=0.3)
        eos.eos_string = "birchmurnaghan"  # Consistent with CASTEP
        try:
            v, e, B = eos.fit()
        except:
            Ni_fcc_prim = bulk(X, "fcc", cubic=True, a=self.a_fcc_0)
            Ni_fcc = make_supercell(Ni_fcc_prim, r * np.eye(3))
            Ni_fcc.calc = lammps_inst
            eos = calculate_eos(Ni_fcc, npoints=12, eps=0.2)
            eos.eos_string = "birchmurnaghan"  # Consistent with CASTEP
            try:
                v, e, B = eos.fit()
            except:
                return 1.e8 * np.ones(self.n_out)
        # Check if something has gone wrong.
        if v < 0. or v == np.nan or v == None:
            return 1.e8 * np.ones(self.n_out)
        elif np.abs(
                v**(1 / 3) / r - a_fcc / r
        ) > 1.5 or a_fcc / r > 2.5 * self.a_fcc_0 or a_fcc / r < self.a_fcc_0 / 2.:
            return 1.e8 * np.ones(self.n_out)
        # Calculate bulk modulus
        B_fcc = B / kJ * 1.e24
        #a_fcc = v**(1/3)
        #E_fcc = e
        Ni_fcc.set_cell([a_fcc, a_fcc, a_fcc],
                        scale_atoms=True)  # Update cell to optimal structure.
        # Elastic constants
        elastic_consts = calculate_elastic_cubic(Ni_fcc, 5)
        C11, C12, C44 = elastic_consts.fit_consts()
        C11_fcc = C11 / kJ * 1.e24
        C12_fcc = C12 / kJ * 1.e24
        C44_fcc = C44 / kJ * 1.e24

        # HCP structure properties.
        a_hcp_guess = self.a_hcp * a_fcc / r / self.a_fcc
        Ni_hcp_prim = bulk(X,
                           "hcp",
                           a=a_hcp_guess,
                           c=self.c2a_hcp * a_hcp_guess)
        Ni_hcp = make_supercell(Ni_hcp_prim, r * np.eye(3))
        N_hcp = Ni_hcp.get_global_number_of_atoms()
        # Initial cell relaxation
        # cmds = cmds0 +\
        #     ["fix 1 all box/relax iso 0.0 vmax 0.001",
        #     "min_style cg",
        #     "minimize 1e-8 1e-8 10000 100000"]
        # lammps = LAMMPSlibExt(lmpcmds=cmds,log_file="test_fcc_0.log",keep_alive=True)
        # Ni_hcp.calc = lammps
        # E_hcp = Ni_hcp.get_total_energy()
        # a = convert(Ni_hcp.calc.lmp.extract_variable("a",None,0),"distance",Ni_hcp.calc.units,"ASE")
        # b = convert(Ni_hcp.calc.lmp.extract_variable("b",None,0),"distance",Ni_hcp.calc.units,"ASE")
        # c = convert(Ni_hcp.calc.lmp.extract_variable("c",None,0),"distance",Ni_hcp.calc.units,"ASE")
        # a_hcp = (a+b)/2
        lammps_inst = LAMMPSlibExt(lmpcmds=cmds0,
                                   log_file="test_hcp.log",
                                   keep_alive=True)
        Ni_hcp.calc = lammps_inst
        try:
            (a_hcp, b_hcp, c_hcp), E_hcp = geometry_opt(Ni_hcp, tol=1.e-3)
        except Exception:
            return 1.e8 * np.ones(self.n_out)
        c2a_hcp = c_hcp / a_hcp

        # DHCP structure properties.
        Ni_hcp_r = Ni_hcp.copy()
        p0 = Ni_hcp.get_positions()
        R = np.array([[-0.5, np.sqrt(3) / 2, 0], [np.sqrt(3) / 2, 0.5, 0],
                      [0, 0, 1]])  # Householder reflection matrix for v=a-b
        Ni_hcp_r.set_positions(p0 @ R.T)
        Ni_dhcp = stack(Ni_hcp_r, Ni_hcp, axis=2)
        N_dhcp = Ni_dhcp.get_global_number_of_atoms()
        # Initial cell relaxation
        # cmds = cmds0 +\
        #     ["fix 1 all box/relax iso 0.0 vmax 0.001",
        #     "min_style cg",
        #     "minimize 1e-8 1e-8 10000 100000"]
        # lammps = LAMMPSlibExt(lmpcmds=cmds,log_file="test_fcc_0.log",keep_alive=True)
        lammps_inst = LAMMPSlibExt(lmpcmds=cmds0,
                                   log_file="test_dhcp.log",
                                   keep_alive=True)
        Ni_dhcp.calc = lammps_inst
        try:
            (a_dhcp, b_dhcp, c_dhcp), E_dhcp = geometry_opt(Ni_dhcp, tol=1.e-3)
        except Exception:
            return 1.e8 * np.ones(self.n_out)
        c2a_dhcp = 0.5 * c_dhcp / a_dhcp

        # Extrinsic properties
        E_fcc /= N_fcc
        E_hcp /= N_hcp
        E_dhcp /= N_dhcp
        a_fcc /= r
        a_hcp /= r
        a_dhcp /= r

        # Set parameters that belong to self.
        self.a_fcc = a_fcc
        self.a_hcp = a_hcp
        self.a_dhcp = a_dhcp
        self.c2a_hcp = c2a_hcp
        self.c2a_dhcp = c2a_dhcp

        return np.array([
            E_fcc, E_hcp, E_dhcp,
            (4 * (E_hcp + 2 * E_dhcp - 3 * E_fcc) / a_fcc**2) * 1.6021773e4,
            a_fcc, a_hcp, c2a_hcp, a_dhcp, c2a_dhcp, B_fcc, C11_fcc, C12_fcc,
            C44_fcc
        ])
Ejemplo n.º 11
0
from numpy import identity
from ase import Atoms
from ase import Atom
import ase
from ase.build import stack

#Define BZ unit cell, with lattice parameter
atoms = Atoms('BaZrOOO', [(0.5, 0.5, 0.5), (0, 0, 0), (0.5, 0, 0), (0, 0.5, 0), (0, 0, 0.5)])
a_0 = 4.1972899437
cell = a_0*identity(3)
atoms.set_cell(cell, scale_atoms=True)


write("BZ1011.vasp", atoms)

atomsLeft = Atoms(atoms)
atomsRight = Atoms(atoms)
#atomsRight.rotate((0, 0, np.pi/6), rotate_cell=True)



atomsStacked = stack(atomsLeft, atomsRight, axis=0, cell=None, fix=0.5, maxstrain=None)
atomsStacked = stack(atomsStacked, atomsStacked, axis=0, cell=None, fix=0.5, maxstrain=None)
atomsStackRotated = Atoms(atomsStacked)
#Rotation about the center of the unit cell
atomsStackRotated.rotate((0, 0, np.pi/6), center=(0,0,0))
#print atomsStackRotated.get_positions()
superStack = stack(atomsStacked, atomsStackRotated, axis=0, cell=None, fix=0.5, maxstrain=None)

write("BZ_rotated.vasp", superStack)
Ejemplo n.º 12
0
from ase.calculators.calculator import compare_atoms

# The purpose of this test is to test the stack() function and verify
# that the various surface builder functions produce configurations
# consistent with stacking.

d = _all_surface_functions()
exclude = {'mx2'}  # mx2 is not like the others

for name in sorted(d):
    if name in exclude:
        continue

    func = d[name]

    def has(var):
        c = func.__code__
        return var in c.co_varnames[:c.co_argcount]

    for nlayers in range(1, 7):
        atoms = func('Au', size=(2, 2, nlayers), periodic=True, a=4.0)
        big_atoms = func('Au', size=(2, 2, 2 * nlayers), periodic=True, a=4.0)
        stacked_atoms = stack(atoms, atoms)

        changes = compare_atoms(stacked_atoms, big_atoms, tol=1e-11)
        if not changes:
            print('OK', name, nlayers)
            break
    else:
        assert 0, 'Unstackable surface {}'.format(name)
Ejemplo n.º 13
0
n_unitcell = int(args.n_unitcell)
if a_repeat == b_repeat == c_repeat == 1:
    a_repeat = b_repeat = c_repeat = n_unitcell
# latt const https://aip.scitation.org/doi/10.1063/1.1726009   ==>> angstrom
# Ar = bulk('Ar', 'fcc',5.3118)
# =======
unitcell = bulk('Ar', 'fcc', 1.5, orthorhombic=True)  #===> epsilon unit
from ase import visualize
from ase.build import stack
from ase.io import write
import numpy as np
# Ars= Atoms(bulk, size=(10,10,10))

atoms_a = unitcell
for i in range(a_repeat - 1):
    atoms_a = stack(atoms_a, unitcell, axis=0)
atoms_b = atoms_a
for j in range(b_repeat - 1):
    atoms_b = stack(atoms_b, atoms_a, axis=1)
all_atoms = atoms_b
for k in range(c_repeat - 1):
    all_atoms = stack(all_atoms, atoms_b, axis=2)

# write("initial_positions.xyz", all_atoms, format='xyz', parallel=True, append=False)
pos_ = all_atoms.get_positions()

# visualize.view(all_atoms)
# print("the cell is=",all_atoms.get_cell())
cell_ = np.array([[
    all_atoms.get_cell()[0][0],
    all_atoms.get_cell()[1][1],
Ejemplo n.º 14
0
    def generate_interface(self):
        """
        main function to generate interface from two cut_cells.
        Returns .True. if an error occured, otherwise returns .False.
        """

        # set up the output file so we can put the error messages
        # in the output file
        file = self.input.dict['output_file']

        # copy over the atom units so that cut_cells are unchanged
        unit_cell_a = self.cut_cell_a.copy()
        unit_cell_b = self.cut_cell_b.copy()

        # remove small numbers from computer error
#        unit_cell_a.cell = self.check_zero_diag(unit_cell_a.cell)
#        unit_cell_a = self.check_cell_rotation(unit_cell_a, unit_cell_b)

        # =====Debug=====
        if (self.input.dict['print_debug'] != 'False'):
            printx("========Starting Cell 1========")
            printx(str(unit_cell_a.cell))
            printx("atoms = " + str(len(unit_cell_a)))
            printx("========Starting Cell 2========")
            printx(str(unit_cell_b.cell))
            printx("atoms = " + str(len(unit_cell_b)))

        # replicate the unit cells so that periodicity is always preserved
        periodic_cell_a, max_coeff_a = self.protect_periodicity(unit_cell_a)
        periodic_cell_b, max_coeff_b = self.protect_periodicity(unit_cell_b)

        # populate the new cell using cookie cutter method on generated lattice
        try:
            self.super_cell1 = self.populate_new_cell(
                unit_cell_a, periodic_cell_a, max_coeff_a)
            self.super_cell2 = self.populate_new_cell(
                unit_cell_b, periodic_cell_b, max_coeff_b)
        except Exception as err:
            [printx(x) for x in err.args]
            raise Exception("Too many atoms, skipping to next step")

        # =====Debug=====
        if (self.input.dict['print_debug'] != 'False'):
            printx("========Ortho Cell 1========")
            printx(str(self.super_cell1.cell))
            printx("atoms = " + str(len(self.super_cell1)))
            printx("========Ortho Cell 2========")
            printx(str(self.super_cell2.cell))
            printx("atoms = " + str(len(self.super_cell2)))

        # calculate the smallest supercells needed to minimize
        # stress in the interface
        P_list, R_list = self.generate_interface_transform(
            self.super_cell1, self.super_cell2)
        P_tuple = tuple(P_list + [int(self.input.dict['crys_a_layers'])])
        R_tuple = tuple(R_list + [int(self.input.dict['crys_b_layers'])])
        # generate new supercells
        try:
            self.super_cell1 *= P_tuple
        except Exception as err:
            raise Exception(
                "Error in generating supercell_a in interface step")
        try:
            self.super_cell2 *= R_tuple
        except Exception as err:
            raise Exception(
                "Error in generating supercell_b in interface step")

        # =====Debug=====
        if (self.input.dict['print_debug'] != 'False'):
            printx("Replication A = " + str(P_tuple))
            printx("Replication B = " + str(R_tuple))

        # check that total size isn't too big before we continue
        total = len(self.super_cell1) + len(self.super_cell2)
        if (total >= int(self.input.dict['max_atoms'])):
            raise Exception("Error: interface is too large: " + str(total))

        # tag the two supercells so that they can be separated later
        self.super_cell1.set_tags(1)
        self.super_cell2.set_tags(2)


        # add a vacuum between the layers.
        if (self.distance is not None):
            self.super_cell1.cell[2, 2] += self.distance

        # =====Debug=====
        if (self.input.dict['print_debug'] != 'False'):
            printx("========Super Cell 1========")
            printx(str(self.super_cell1.cell))
            printx("atoms = " + str(len(self.super_cell1)))
            printx("========Super Cell 2========")
            printx(str(self.super_cell2.cell))
            printx("atoms = " + str(len(self.super_cell2)))

        # stack the supercells on top of each other and set pbc to xy-slab
        try:
            self.interface, self.super_cell1, self.supercell2 = stack(
                self.super_cell1, self.super_cell2,
                output_strained=True, maxstrain=None)
        except Exception as err:
            raise Exception(
                "Error in generating interface during the stack step")

        # set pbc to infinite slab or fully periodic setting
        if (self.input.dict['full_periodicity'] != 'False'):
            self.interface.pbc = [1, 1, 1]
        else:
            self.interface.pbc = [1, 1, 0]

        #add explicit vacuum above and below 
        if (self.input.dict['z_axis_vacuum'] != '0.0'):
            self.interface = self.z_insert_vacuum(self.interface)

        # use merge sort to identify and remove duplicate atoms.
        if (self.input.dict['remove_duplicates'] != 'False'):
            try:
                self.remove_duplicates(self.interface)
            except Exception as err:
                raise Exception("Error in checking for atom overlaps")

        return