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
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)
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)
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)
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)
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)
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)
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,
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 ])
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)
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)
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],
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