def ceria(): a = 5.49 # Lattice constant CeO2 = Atoms('Ce4O8', scaled_positions=[(0., 0., 0.), (0., 0.5, 0.5), (0.5, 0., 0.5), (0.5, 0.5, 0.), (0.75, 0.25, 0.25), (0.25, 0.75, 0.75), (0.75, 0.75, 0.75), (0.25, 0.25, 0.25), (0.25, 0.25, 0.75), (0.75, 0.75, 0.25), (0.25, 0.75, 0.25), (0.75, 0.25, 0.75)], cell=[a, a, a], pbc=True) #(1,1,1) is the slab type. There are 2 unit cells along z direction slab = surface(CeO2, (1, 1, 1), 2) # Repeating the slab 5 unit cells in x and 5 unit cell in y directions # At the end the ceria slab is 10 by 10 # the Pd supercell mother is also 10 by 10 slab = slab.repeat((5, 5, 1)) slab.center(vacuum=10.0, axis=2) # clave the top layer O atoms del slab[[atom.index for atom in slab if atom.z > 15]] return slab
def get_ase_slab(pmg_struct, hkl=(1, 1, 1), min_thick=10, min_vac=10): """ takes in the intial structure as pymatgen Structure object uses ase to generate the slab returns pymatgen Slab object Args: pmg_struct: pymatgen structure object hkl: hkl index of surface of slab to be created min_thick: minimum thickness of slab in Angstroms min_vac: minimum vacuum spacing """ ase_atoms = AseAtomsAdaptor().get_atoms(pmg_struct) pmg_slab_gen = SlabGenerator(pmg_struct, hkl, min_thick, min_vac) h = pmg_slab_gen._proj_height nlayers = int(math.ceil(pmg_slab_gen.min_slab_size / h)) ase_slab = surface(ase_atoms, hkl, nlayers) ase_slab.center(vacuum=min_vac / 2, axis=2) pmg_slab_structure = AseAtomsAdaptor().get_structure(ase_slab) return Slab(lattice=pmg_slab_structure.lattice, species=pmg_slab_structure.species_and_occu, coords=pmg_slab_structure.frac_coords, site_properties=pmg_slab_structure.site_properties, miller_index=hkl, oriented_unit_cell=pmg_slab_structure, shift=0., scale_factor=None, energy=None)
def cut_slab_ase( bulk, facet, layers=6, vacuum=8, ): """Cut slab from bulk using ASE. Args: bulk: facet: """ # | - cut_slab_ase # facet = [1, 1, 0] # layers = 6 # vacuum = 8 out_file = "out_slab_ase.traj" # facet = [int(i) for i in facet] # atoms = io.read("qn.traj") # Bulk traj file (no vacuum) # atoms = io.read("init.cif") # Bulk traj file (no vacuum) slab = surface(bulk, facet, layers, vacuum) slab.set_pbc(True) # slab.write(out_file) return(slab)
def test_surface(): import numpy as np from ase import Atoms, Atom from ase.build import fcc111, fcc211, add_adsorbate, bulk, surface import math atoms = fcc211('Au', (3, 5, 8), vacuum=10.) assert len(atoms) == 120 atoms = atoms.repeat((2, 1, 1)) assert np.allclose(atoms.get_distance(0, 130), 2.88499566724) atoms = fcc111('Ni', (2, 2, 4), orthogonal=True) add_adsorbate(atoms, 'H', 1, 'bridge') add_adsorbate(atoms, Atom('O'), 1, 'fcc') add_adsorbate(atoms, Atoms('F'), 1, 'hcp') # The next test ensures that a simple string of multiple atoms cannot be used, # which should fail with a KeyError that reports the name of the molecule due # to the string failing to work with Atom(). failed = False try: add_adsorbate(atoms, 'CN', 1, 'ontop') except KeyError as e: failed = True assert e.args[0] == 'CN' assert failed # This test ensures that the default periodic behavior remains unchanged cubic_fcc = bulk("Al", a=4.05, cubic=True) surface_fcc = surface(cubic_fcc, (1,1,1), 3) assert list(surface_fcc.pbc) == [True, True, False] assert surface_fcc.cell[2][2] == 0 # This test checks the new periodic option cubic_fcc = bulk("Al", a=4.05, cubic=True) surface_fcc = surface(cubic_fcc, (1,1,1), 3, periodic=True) assert (list(surface_fcc.pbc) == [True, True, True]) expected_length = 4.05*3**0.5 #for FCC with a=4.05 assert math.isclose(surface_fcc.cell[2][2], expected_length)
def random_structure_on_substrate(symbols, amin, amax, dmin, model_file, Natt=RANDOM_ATTEMPTS): # returns random structure (ase Atoms) on substrate with lowest e_tot according to Megnet model substrate = read_vasp("POSCAR.substrate") adapt = AseAtomsAdaptor() model = MEGNetModel.from_file(model_file) e_tot_min = 1000. for i in range(Natt): s = surface(substrate, (0, 0, 1), 1, vacuum=0., tol=1e-10) cell = s.get_cell() cell[2][2] = CELL_Z s.set_cell(cell) amin = cell[0][0] amax = cell[0][0] struct = random_structure(symbols, amin, amax, dmin, iwrite=0) j = 0 atoms = struct.get_chemical_symbols() positions = struct.get_positions() for atom in atoms: at = Atom(atom) positions[j][2] = positions[j][2] + SURF_DIST pos = positions[j] at.position = pos s.append(at) j = j + 1 struct_pymatgen = adapt.get_structure(s) try: e_tot = model.predict_structure(struct_pymatgen) # print(e_tot) except: e_tot = 0. print("isolated molecule exception handled") if e_tot < e_tot_min: struct_out = s e_tot_min = e_tot print("e_tot min: ", e_tot_min) write(filename='best.in', images=struct_out, format="espresso-in") del model return struct_out
def slice(poscar, indices, vacuum, layer=1, name=''): ''' :param poscar: poscar'name :param indices: Miller indices :param vacuum: vacuum's length (A) :param layer: Number of equivalent layers of the slab :return: new poscar ''' if name == '': name = '%s_slab%s' % (poscar, str(indices)) else: pass POSCAR = poscar Atom = read(POSCAR) slab = surface(Atom, indices=indices, layers=layer, vacuum=vacuum) write_vasp(name, slab)
def generate(bulk_model, layers=2, facets=[(1, 1, 1)], supercell=(1, 1, 1), vacuum=10, save=False): ''' Function to create variety of different facets Parameters: bulk_model: Atoms object or string specify the unit cell of the bulk geometry, or element from which to construct default bulk layers: int specify the repeating layers along the direction defined in 'axis' of the 'center' function facets: list of array of ints specify the list of facets required as output supercell: array of ints specify the periodicity of the supercell; (x,y,z). # can this just be an int? - No, has to be an array # vacuum: float specifies the vacuum addition to the slab in the direction of 'axis-' of the 'center' function ''' from ase.build import surface slabs = [] #loop for all surfaces for face in facets: # cut the slab in face, last number is the number of layers slab = surface(bulk_model, (face), layers) # create a supercell and make it periodic as specified in the input slab.repeat(supercell) # introduce vaccum around the supercell in z direction slab.center(vacuum=vacuum, axis=2) # Add model to the list of slabs slabs.append(slab) # Now writes all files at the end if save: _save(facets, slabs) return facets, slabs
def test_surface_terminations(): from ase.build.surfaces_with_termination import surfaces_with_termination from ase.build import surface from ase.spacegroup import crystal a = 4.6 c = 2.95 # Rutile: rutile = crystal(['Ti', 'O'], basis=[(0, 0, 0), (0.3, 0.3, 0.0)], spacegroup=136, cellpar=[a, a, c, 90, 90, 90]) slb = surface(rutile, indices=(1,1,0), layers=4, vacuum=10) slb *= (1,2,1) def check_surf_composition(images, formula): for atoms in images: zmax = atoms.positions[:, 2].max() sym = atoms.symbols[abs(atoms.positions[:, 2] - zmax) < 1e-2] red_formula, _ = sym.formula.reduce() assert red_formula == formula images = surfaces_with_termination(rutile, indices=(1,1,0), layers=4, vacuum=10, termination='O') check_surf_composition(images, 'O') images = surfaces_with_termination(rutile, indices=(1,1,0), layers=4,vacuum=10, termination='TiO') check_surf_composition(images, 'TiO')
from ase.build import bulk, surface from lammps_interface.tools import put_molecules_on_slab, make_standard_input, write_lammps_data from ase.visualize import view iron_surface = surface('Fe', (1,0,0), layers = 4, vacuum = 10) iron_surface *= (2,2,1) hydrated_iron = put_molecules_on_slab(iron_surface, fluid_molecule = 'H2O', molar_density = 55.5556, offset = 1) view(hydrated_iron) make_standard_input(calculation_type = 'reaxff') write_lammps_data(hydrated_iron, filename = 'lmp.data', bonding = False)
#!/usr/bin/env python from ase.io import read, vasp from ase.build import sort, surface unitcell = sort(read('POSCAR')) slab = surface(unitcell, indices=(1, 1, 0), layers=4, vacuum=10) vasp.write_vasp('POSCAR_slab', sort(slab), vasp5=True, direct=True)
from ase.calculators.vasp import Vasp from ase.io import write from ase.io import read from ase.spacegroup import crystal from ase.visualize import view from ase.lattice.cubic import BodyCenteredCubic from ase.lattice.hexagonal import HexagonalClosedPacked import numpy as np from ase import Atoms Rubulk = bulk('Ru', 'hcp', covera=1.584, orthorhombic=True) cell = Rubulk.cell xscale = 6 yscale = 2 zscale = 2 bulk1 = Rubulk * (xscale, yscale, zscale) surf = surface(Rubulk, (1, 1, 5), 12) surf.center(vacuum=5, axis=2) surf = surf * (3, 3, 1) #cell[0,0] = 6.75 #cell[2,2] = 6.4152 for atom in bulk1: if atom.position[2] < 0.1: if atom.position[0] >= xscale * cell[0, 0] / 2: atom.position[2] = atom.position[2] + zscale * cell[2, 2] d = cell[2, 2] L = cell[0, 0] * xscale Lz = d * zscale alpha = np.arctan(d / L) for atom in bulk1: x1 = atom.position[0] * np.cos(alpha) + atom.position[2] * np.sin(alpha)
from ase.spacegroup import crystal from ase.visualize import view from ase.build import surface from ase.io import write #build the Pt crystal structure a = 3.859 #angstrom Pd = crystal(['Pd'], basis=[(0, 0, 0)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90]) #build the (111) surface slab Pd_111 = surface(Pd, (1, 1, 1), 2) Pd_111.center(vacuum=10, axis=2) #repeat slab Pd_111_repeat = Pd_111.repeat((2, 1, 1)) #(1,2,1) corresponds to repeat how many times in x,y,z direction #save .traj file write('Pd_111.traj', Pd_111_repeat) write('POSCAR', Pd_111_repeat) #in case the .traj file cannot be read view(Pd_111_repeat)
############################################################################### with open('models/slab_modeling_%03d_%03d.log' % (num_ini + 1, num_fin), 'w') as f: start_time = time.time() KPOINTS = Kpoints.from_file('KPOINTS_slab') for idx in range(num_ini, num_fin): formula = df_entries['formula'][idx] file_path = '%03d_%s/2nd/' % (idx + 1.0, formula) createFolder(file_path + 'surface') """ Slab modeling """ bulk_opt = read_vasp(file_path + 'CONTCAR') slab = surface(bulk_opt, (1, 0, 0), 3, vacuum=7.5) slab_super = make_supercell(slab, [[2, 0, 0], [0, 2, 0], [0, 0, 1]]) positions = slab_super.get_positions() layer_position = [] for i in range(len(positions)): # print('%4.3f' % positions[i][2],end = '\t') if positions[i][2] not in layer_position: layer_position.append(positions[i][2]) layer_position.sort() f.writelines( '%03d_%s\n\tN_atoms(before) : %d' % (idx + 1.0, formula, slab_super.get_global_number_of_atoms()))
''' FCC unit cell: atoms.set_cell([(0, b, b), (b, 0, b), (b, b, 0)]) ''' # a = 4.05 # Gold lattice constant a = 4.081 b = a / 2 fcc_atom = Atoms('Au', cell=[(0, b, b), (b, 0, b), (b, b, 0)], pbc=True) # s2 = surface('Au', (2, 1, 1), 9) # s2.center(vacuum=10, axis=2) # write('string_Au2.vasp', s2, format='vasp', vasp5=True) s1 = surface(fcc_atom, (2, 1, 1), 9) s1.center(vacuum=10, axis=2) print(s1) write('atom_________.vasp', s1, format='vasp', vasp5=True) # Mobulk = bulk('Mo', 'bcc', a=3.16, cubic=True) # s2 = surface(Mobulk, (3, 2, 1), 9) # s2.center(vacuum=10, axis=2) # view(s2) # a = 4.0 # Pt3Rh = Atoms('Pt3Rh', # scaled_positions=[(0, 0, 0), # (0.5, 0.5, 0), # (0.5, 0, 0.5), # (0, 0.5, 0.5)],
Pt = crystal(['Pt'], basis=[(0, 0, 0)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90]) h = 2.6 conv_dict = { 'energy': 1e-6, 'mixing': 0.05, 'mixing_mode': 'local-TF', 'maxsteps': 1000, 'diag': 'cg' } Pt_slab = surface(Pt, (1, 1, 1), 2) Pt_slab.center(vacuum=10, axis=2) CO_molecule = molecule('CO') CO_molecule.center(10) add_adsorbate(Pt_slab, CO_molecule, h, position=(2.5, 2.5)) constraint = FixAtoms( mask=[True, True, True, True, False, False, False, False]) Pt_slab.set_constraint(constraint) Pt_slab.calc = espresso(pw=current_pw, dw=current_pw * 10, kpts=(current_k, current_k, 1), xc='PBE', outdir='test_output',
from ase.spacegroup import crystal from ase.visualize import view from ase.build import surface from ase.build import bulk from ase.io import write #build the Pt crystal structure a = 3.859 #angstrom #Pd=crystal(['Pd'],basis=[(0,0,0)],spacegroup=225,cellpar=[a,a,a,90,90,90]) Pd_bulk = bulk('Pd', 'fcc', a, cubic=True) #build the (111) surface slab Pd_bulk_surface = surface(Pd_bulk, (1, 1, 1), 2) Pd_bulk_surface.center(vacuum=10, axis=2) #repeat slab Pd_111_repeat = Pd_bulk_surface.repeat((2, 1, 1)) #(1,2,1) corresponds to repeat how many times in x,y,z direction #save .traj file write('PdH2_adsorption/Pd_bulk_surface.traj', Pd_bulk_surface) write('PdH2_adsorption/POSCAR', Pd_111_repeat) #in case the .traj file cannot be read view(Pd_111_repeat)
from ase.optimize import QuasiNewton from ase.build import surface from ase.spacegroup import crystal from ase.io import read import sys current_pw = int(sys.argv[1]) current_k = int(sys.argv[2]) a = 3.923 #angstrom Pt = crystal(['Pt'], basis=[(0, 0, 0)], spacegroup=225, cellpar=[a, a, a, 90, 90, 90]) single_slab = surface(Pt, (1, 1, 1), 2) single_slab.center(vacuum=10, axis=2) single_slab.set_calculator(EMT()) constraint = FixAtoms( mask=[False, True, True, False, False, True, True, False]) single_slab.set_constraint(constraint) dyn = QuasiNewton(single_slab, trajectory='modified_slab.traj') dyn.run(fmax=1) modified_single_slab = read('modified_slab.traj') conv_dict = { 'energy': 1e-6, 'mixing': 0.05, 'mixing_mode': 'local-TF',
#edit space group, symbols, basis and cell parameters below and choose preferred surface plane and layers #You could get the above information by using the aflow online wrapper and using poscar to wyccar import sys from ase.spacegroup import crystal from ase.visualize import view from ase import Atoms from ase.build import surface from ase.io import write atoms = crystal(spacegroup=189, symbols=['N','Ta','Ta'], basis=[[0,0.3926,0],[0,0,0],[0.6667,0.3333,0.5]], cellpar=[5.2278,5.2278,2.9194,90.0,90.0,120.0]) s1 = surface(atoms, (0, 1, 1), 5) s1.center(vacuum=6, axis=2) write('POSCAR',s1,format='vasp')
parser.add_argument('-n', '--name', default='POSCAR') parser.add_argument('-v', '--vaccuum', type=float, default=15) parser.add_argument('-s', '--strict', action='store_true', help='if True cutoff at 1 else 0.999999') parser.add_argument('--nocut', action='store_true') # TODO: add argument to create several structures args = parser.parse_args() x_ref, y_ref, layers = args.supercell bulk = read(args.bulk) # TODO: create slabs with different heights slab = surface(bulk, args.miller, layers, args.vaccuum / 2) # add tags set_tags(slab) correct_z(slab) x_slab, y_slab, z_slab = len_supercell(slab) x_factor, y_factor, z_factor = (1, 1, 1) if x_ref != x_slab: x_factor = x_ref / x_slab if y_ref != y_slab: y_factor = y_ref / y_slab if layers != z_slab: z_factor = layers / z_slab # TODO: add procedure to expand cell
def generate_slab(miller_indices, layers): lattice = FaceCenteredCubic('Cu') return surface(lattice, miller_indices, layers, vacuum=15)
from sys import argv from ase.spacegroup import crystal from ase.build import surface, add_vacuum from ase.constraints import FixAtoms from ase.calculators.vasp import Vasp from ase.visualize import view from ase.io import write, read slab = read('TiO2.cif') slab = surface(slab, (1, 0, 1), 3, vacuum=6) slab = slab * (1, 2, 1) #extra_atoms = [] #for atom in slab: # if atom.z >= 12.50: # extra_atoms.append(atom.index) #del slab[extra_atoms] #extra_atoms = [] #for atom in slab: # if atom.z <= 12.05: # extra_atoms.append(atom.index) #del slab[extra_atoms] #slab.positions[:, 2] -= 6.0 write('TiO2_101surface.traj', slab) view(slab)
mnD = [1, 1] # step size (NYI) nLayersS = 3 #nLayersA=3 fVacuum = 10.0 #nDimA=1 # dimension of the "adsorbate": 1D, 2D or 3D fNumEPS = 1.0E-8 ### variables ### hkl = [0, 0, 0] mn = [0, 0] for hkl[0] in range(hkl0[0], hklF[0] + 1): for hkl[1] in range(hkl0[1], hklF[1] + 1): for hkl[2] in range(hkl0[2], hklF[1] + 1): print(hkl) s1 = surface(Surface1, (hkl[0], hkl[1], hkl[2]), nLayersS, fVacuum, fNumEPS) #s1 = oriented_surface(Surface1, (hkl[0],hkl[1],hkl[2]), nLayersS, fVacuum, fNumEPS) #s1.edit() for mn[0] in range(mn0[0], mnF[0] + 1): for mn[1] in range(mn0[1], mnF[1] + 1): print(mn) orient1 = cut(s1, a=(mn[0], mn[1], 0), b=(-mn[1], mn[0], 0), c=(0, 0, 1)) # Change unit cell to have the x-axis parallel with a surface vector # and z perpendicular to the surface: a1, a2, a3 = orient1.cell orient1.set_cell([ (norm(a1), 0, 0), (np.dot(a1, a2) / norm(a1),
b_r = 1.0 c = a * a_r / ( a_r + b_r) + b * b_r/ (a_r + b_r) print c #slab = fcc111('Ag', size=(1,1,4), a=c, vacuum=7.5, orthogonal=False) #slab = fcc100('Cu', size=(3,3,3), a=c, vacuum=10.0) #slab = fcc211('Cu', size=(3,4,3), a=a, vacuum=5.0, orthogonal=True) #a= 3.92 #slab = fcc111('Pt', size=(4,4,4), a=a, vacuum=7.5, orthogonal=True) #slab = fcc211('Pt', size=(6,5,3), a=a, vacuum=5.0, orthogonal=True) #a=4.08 #slab = fcc111('Au', size=(3,4,3), a=a, vacuum=7.5, orthogonal=True) #slab = fcc111('Au', size=(4,4,3), a=a, vacuum=7.5, orthogonal=True) Ag3Au = Atoms('Au3Ag', scaled_positions=[(0, 0, 0), (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5)], cell=[c, c, c], pbc=True) s3 = surface(Ag3Au, (1, 1, 1), 4) s3.center(vacuum=7.5, axis=2) Ag3Au.set_chemical_symbols('AuAgAu2') #s4 = surface(Pt3Rh, (2, 1, 1), 9) #s4.center(vacuum=10, axis=2) c = FixAtoms(mask=[x >2 for x in s3.get_tags()]) s3.set_constraint(c) write('POSCAR',s3,format='vasp',direct=True)
def cut_slab(cml): ''' ''' args = parse_cml_args(cml) primitive_cell = read(args.poscar) slab = surface(primitive_cell, args.hkl, layers=args.nlayer) pos_z = slab.positions.copy()[:, 'xyz'.index(args.ivacuum)] n_atomic_layers, natoms_per_layers, indices_for_layers = \ find_natoms_layers(pos_z, args.layer_thickness) print("{} atomic layers found!".format(n_atomic_layers)) if args.delete_atomic_layer: kept_atoms = [ ii for jj in range(n_atomic_layers) for ii in indices_for_layers[jj] if jj not in args.delete_atomic_layer ] slab = slab[kept_atoms] pos_z = slab.positions.copy()[:, 'xyz'.index(args.ivacuum)] n_atomic_layers, natoms_per_layers, indices_for_layers = \ find_natoms_layers(pos_z, args.layer_thickness) if args.fix_atomic_layers: C = FixAtoms(indices=[ ii for jj in range(n_atomic_layers) for ii in indices_for_layers[jj] if jj in args.fix_atomic_layers ]) slab.set_constraint(C) slab.center(args.vacuum / 2, axis='xyz'.index(args.ivacuum)) org_chem_symbols = np.array(slab.get_chemical_symbols()) org_atom_index = np.arange(len(slab), dtype=int) # Sort first by z-coordinates then by y and x. rpos = np.round(slab.positions, 4) new_atom_index = np.lexsort((rpos[:, 0], rpos[:, 1], rpos[:, 2])) slab = slab[new_atom_index] # New order of chemical symbols if args.new_sym_order: assert set(args.new_sym_order) == set(org_chem_symbols) chem_sym_order = args.new_sym_order else: # Just stick to the original order. chem_sym_order = [] for ss in primitive_cell.get_chemical_symbols(): if not ss in chem_sym_order: chem_sym_order.append(ss) # Re-arrange the atoms according to the new order of chemical symbols new_atom_index = [ ii for ss in chem_sym_order for ii in org_atom_index[slab.symbols == ss] ] slab = slab[new_atom_index] if args.out is None: outF = 'out_{}{}{}_{}.vasp'.format(args.hkl[0], args.hkl[1], args.hkl[2], args.nlayer) write(outF, slab, vasp5=True) else: outF = args.out write(outF, slab)
tags = atoms.get_chemical_symbols() mask = [i for i, tag in enumerate(tags) if tag==ele] return mask # read CONTCAR a = 15.865/4 xyz = a/2 #atoms = read('~/xcp2k/bulks/pt-relax/relax/') bulk = Atoms([Atom('Pt', (0.0, 0.0, 0.0)), Atom('Pt', (xyz, xyz, 0.0)), Atom('Pt', (xyz, 0.0, xyz)), Atom('Pt', (0.0, xyz, xyz))]) bulk.cell= a * np.array([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]) atoms = surface(bulk, (1, 1, 1), 4, vacuum=0.0) atoms.pbc = [True, True, True] constraint = FixAtoms(mask=[atom.position[2] < 3 for atom in atoms]) atoms.set_constraint(constraint) atoms.cell[2][2] = 25 atoms = sortz(atoms) #### ads = Atoms('CO') ads[0].position = atoms[-1].position ads[1].position = atoms[-1].position ads[0].z = ads[0].z + 1.80 ads[1].z = ads[0].z + 1.16
ene = tmpbulk.get_potential_energy() ene /= len(tmpbulk) #nat = surf.get_chemical_symbols().count(ielem) nat = bulk.get_chemical_symbols().count(ielem) e_bulk_component += ene * nat # formation energy of bulk alloy from its component e_form = e_bulk - e_bulk_component # # ------------------------ surface ------------------------ # # load lattice constant form bulk calculaiton database # # surface construction # surf = surface(bulk, face, nlayer, vacuum=vacuum) surf.translate([0, 0, -vacuum]) surf = sort_atoms_by_z(surf) # # setting tags for relax/freeze # natoms = len(surf.get_atomic_numbers()) one_surf = natoms // nlayer // repeat_bulk tag = np.ones(natoms, int) for i in range(natoms-1, natoms-nrelax*one_surf-1, -1): tag[i] = 0 surf.set_tags(tag) #
parameters = { 'pseudopotentials': mypseudo, 'calculation': 'relax', 'ecutwfc': 40.0, 'ecutrho': 320.0, 'occupations': 'smearing', 'degauss': 0.01, 'kpts': (4, 4, 1), 'queue': queue, 'debug': True, 'parallel': '-nk 4', } # Build the Pt (001) surface atoms = bulk('Pt') atoms = surface(atoms, (0, 0, 1), 2, vacuum=1) atoms.pbc = [True, True, True] atoms = atoms * [2, 2, 1] atoms.positions[:, 2] -= min(atoms.positions[:, 2]) - 0.01 atoms.cell[2][2] = max(atoms.positions[:, 2]) + 10 atoms = fix_layers(atoms, (0, 0, 1), 1.0, [0, 2]) # calc = Espresso( label='relax/001-221-Pt', **parameters, ) atoms.calc = calc calc.run(atoms=atoms) calc.read_results() atoms_opt = calc.results['atoms']
import cupy as cp import matplotlib.pyplot as plt from ase.build import bulk, surface from abtem import GridScan, Potential, Probe, AnnularDetector """ In this example, we parallelize over scan positions by partitioning the probe positions of the grid scan and calculating each partition on a different GPU. WARNING: The example is currently untested. """ NUM_GPUS = 2 atoms = bulk('Si', crystalstructure='diamond', cubic=True) atoms = surface(atoms, (1, 1, 0), 3) atoms.center(axis=2, vacuum=5) reps = (3, 4, 1) atoms *= reps atoms.wrap() potential = Potential(atoms, gpts=768, slice_thickness=1, projection='infinite', precalculate=False, device='gpu', parametrization='kirkland') probe = Probe(semiangle_cutoff=15, energy=300e3, device='gpu') probe.match_grid(potential)
# creates: s1.png s2.png s3.png s4.png general_surface.pdf from ase.build import surface s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) from ase.build import bulk Mobulk = bulk('Mo', 'bcc', a=3.16, cubic=True) s2 = surface(Mobulk, (3, 2, 1), 9) s2.center(vacuum=10, axis=2) a = 4.0 from ase import Atoms Pt3Rh = Atoms('Pt3Rh', scaled_positions=[(0, 0, 0), (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5)], cell=[a, a, a], pbc=True) s3 = surface(Pt3Rh, (2, 1, 1), 9) s3.center(vacuum=10, axis=2) Pt3Rh.set_chemical_symbols('PtRhPt2') s4 = surface(Pt3Rh, (2, 1, 1), 9) s4.center(vacuum=10, axis=2) from ase.io import write for atoms, name in [(s1, 's1'), (s2, 's2'), (s3, 's3'), (s4, 's4')]: write(name + '.pov', atoms, rotation='-90x', show_unit_cell=2,
import sys from ase.spacegroup import crystal from ase.visualize import view from ase import Atoms from ase.build import surface from ase.io import write atoms = crystal(spacegroup=136, symbols=['Ti', 'O'], basis=[[0, 0, 0], [0.305, 0.305, 0]], cellpar=[4.67, 4.67, 2.97, 90.0, 90.0, 90.0]) s1 = surface(atoms, (1, 1, 0), 10) s1.center(vacuum=7.5, axis=2) write('POSCAR', s1, format='vasp')
# creates: s1.png s2.png s3.png s4.png general_surface.pdf import os import shutil from pathlib import Path from ase import Atoms from ase.build import surface, bulk from ase.io import write s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) Mobulk = bulk('Mo', 'bcc', a=3.16, cubic=True) s2 = surface(Mobulk, (3, 2, 1), 9) s2.center(vacuum=10, axis=2) a = 4.0 Pt3Rh = Atoms('Pt3Rh', scaled_positions=[(0, 0, 0), (0.5, 0.5, 0), (0.5, 0, 0.5), (0, 0.5, 0.5)], cell=[a, a, a], pbc=True) s3 = surface(Pt3Rh, (2, 1, 1), 9) s3.center(vacuum=10, axis=2) Pt3Rh.set_chemical_symbols('PtRhPt2') s4 = surface(Pt3Rh, (2, 1, 1), 9) s4.center(vacuum=10, axis=2) for atoms, name in [(s1, 's1'), (s2, 's2'), (s3, 's3'), (s4, 's4')]: write(name + '.pov',
with open('models/slab_modeling_%03d_%03d.log' % (num_ini + 1, num_fin), 'w') as f: start_time = time.time() KPOINTS = Kpoints.from_file('KPOINTS_slab') for idx in range(num_ini, num_fin): formula = MO2_list[idx] file_path = '%02d_%s/opt/' % (idx + 1.0, formula) createFolder(file_path + 'surface') """ Slab modeling """ bulk_opt = read_vasp(file_path + 'CONTCAR') slab = surface(bulk_opt, (1, 1, 0), 5, vacuum=7.5) # view(slab) slab_super = make_supercell(slab, [[1, 0, 0], [0, 2, 0], [0, 0, 1]]) # view(slab_super) positions = slab_super.get_positions() layer_position = [] for i in range(len(positions)): if round(positions[i][2], 3) not in layer_position: layer_position.append(round(positions[i][2], 3)) layer_position.sort() f.writelines(