def surfer(mpid='', vacuum=15, layers=2, mat=None, max_index=1, write_file=True): """ ASE surface bulder Args: vacuum: vacuum region mat: Structure object max_index: maximum miller index min_slab_size: minimum slab size Returns: structures: list of surface Structure objects """ if mat == None: with MPRester() as mp: mat = mp.get_structure_by_material_id(mpid) if mpid == '': print('Provide structure') sg_mat = SpacegroupAnalyzer(mat) mat_cvn = sg_mat.get_conventional_standard_structure() mat_cvn.sort() indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index) ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn) structures = [] pos = Poscar(mat_cvn) try: pos.comment = str('sbulk') + str('@') + str('vac') + str(vacuum) + str( '@') + str('layers') + str(layers) except: pass structures.append(pos) if write_file == True: mat_cvn.to(fmt='poscar', filename=str('POSCAR-') + str('cvn') + str('.vasp')) for i in indices: ase_slab = surface(ase_atoms, i, layers) ase_slab.center(vacuum=vacuum, axis=2) slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab) slab_pymatgen.sort() surf_name = '_'.join(map(str, i)) pos = Poscar(slab_pymatgen) try: pos.comment = str("Surf-") + str(surf_name) + str('@') + str( 'vac') + str(vacuum) + str('@') + str('layers') + str(layers) except: pass if write_file == True: pos.write_file(filename=str('POSCAR-') + str("Surf-") + str(surf_name) + str('.vasp')) structures.append(pos) return structures
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 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 surfer(vacuum=15, layers=2, mat=None, max_index=1, write_file=True): """ ASE surface bulder Args: vacuum: vacuum region mat: Structure object max_index: maximum miller index min_slab_size: minimum slab size Returns: structures: list of surface Structure objects """ if mat == None: print("Provide structure") sg_mat = SpacegroupAnalyzer(mat) mat_cvn = sg_mat.get_conventional_standard_structure() mat_cvn.sort() indices = get_symmetrically_distinct_miller_indices(mat_cvn, max_index) ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn) structures = [] pos = Poscar(mat_cvn) try: pos.comment = (str("sbulk") + str("@") + str("vac") + str(vacuum) + str("@") + str("layers") + str(layers)) except: pass structures.append(pos) if write_file == True: mat_cvn.to(fmt="poscar", filename=str("POSCAR-") + str("cvn") + str(".vasp")) for i in indices: ase_slab = surface(ase_atoms, i, layers) ase_slab.center(vacuum=vacuum, axis=2) slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab) slab_pymatgen.sort() surf_name = "_".join(map(str, i)) pos = Poscar(slab_pymatgen) try: pos.comment = (str("Surf-") + str(surf_name) + str("@") + str("vac") + str(vacuum) + str("@") + str("layers") + str(layers)) except: pass if write_file == True: pos.write_file(filename=str("POSCAR-") + str("Surf-") + str(surf_name) + str(".vasp")) structures.append(pos) return structures
def build_tilt_sym_frac(self, bp=[-1,1,12], v=[1,1,0], c_space=None): bpxv = [(bp[1]*v[2]-v[1]*bp[2]),(bp[2]*v[0]-bp[0]*v[2]),(bp[0]*v[1]- v[0]*bp[1])] grain_a = BodyCenteredCubic(directions = [bpxv, bp, v], size = (1,1,1), symbol='Fe', pbc=(1,1,1), latticeconstant = 2.85) n_grain_unit = len(grain_a) n = 2 # Slightly different from slabmaker since in the fracture # Simulations we want the grainboundary plane to be normal to y. while(grain_a.get_cell()[1,1] < 120.0): grain_a = BodyCenteredCubic(directions = [bpxv, bp, v], size = (1,n,2), symbol='Fe', pbc=(1,1,1), latticeconstant = 2.85) n += 1 print '\t {0} repeats in z direction'.format(n) grain_b = grain_a.copy() grain_c = grain_a.copy() print '\t', '{0} {1} {2}'.format(v[0],v[1],v[2]) print '\t', '{0} {1} {2}'.format(bpxv[0],bpxv[1],bpxv[2]) print '\t', '{0} {1} {2}'.format(bp[0], bp[1], bp[2]) if c_space==None: s1 = surface('Fe', (map(int, bp)), n) c_space = s1.get_cell()[2,2]/float(n) #-s1.positions[:,2].max() s2 = surface('Fe', (map(int, v)), 1) x_space = s2.get_cell()[0,0] #-s1.positions[:,2].max() s3 = surface('Fe', (map(int, bpxv)), 1) y_space = s3.get_cell()[1,1] #-s1.positions[:,2].max() print '\t Interplanar spacing: ', x_space.round(2), y_space.round(2), c_space.round(2), 'A' # Reflect grain b in z-axis (across mirror plane): print grain_a.get_cell()[1,1]-grain_a.positions[:,1].max() grain_b.positions[:,1] = -1.0*grain_b.positions[:,1] grain_c.extend(grain_b) grain_c.set_cell([grain_c.get_cell()[0,0], 2*grain_c.get_cell()[1,1], grain_c.get_cell()[2,2]]) grain_c.positions[:,1] += abs(grain_c.positions[:,1].min()) pos = [grain.position for grain in grain_c] pos = sorted(pos, key= lambda x: x[2]) dups = get_duplicate_atoms(grain_c) # now center fracture cell with plenty of vacuum grain_c.center(vacuum=10.0,axis=1) return grain_c
def get_ase_surf(s=[], miller=(0, 0, 1), layers=1): strt = center_struct(s) ase_atoms = AseAtomsAdaptor().get_atoms(strt) ase_slab = surface(ase_atoms, miller, layers) ase_slab.center(axis=2) tmp = AseAtomsAdaptor().get_structure(ase_slab) range_z = rangexyz(strt) # print ('rz',abs(strt.lattice.matrix[2][2]),range_z) if abs(strt.lattice.matrix[2][2] - range_z) <= 6.0: ase_slab.center(axis=2, vacuum=12.0) else: ase_slab.center(axis=2) slab_pymatgen = AseAtomsAdaptor().get_structure(ase_slab) slab_pymatgen.sort() print("Surface") print(Poscar(slab_pymatgen)) return slab_pymatgen
import sys from ase.lattice.surface import surface from ase.io import read from ase.visualize import view # facet = sys.argv[1] try: layers = int(sys.argv[2]) except: layers = 1 try: vacuum = float(sys.argv[3]) except: vacuum = 9 # facet = [int(i) for i in facet] facet = [1, 1, 1] atoms = read(sys.argv[1]) #Bulk traj file (no vacuum) atoms = surface(atoms, facet, layers, vacuum) atoms.set_pbc(True) view(atoms)
a = 3.6 bulk = FaceCenteredCubic('Fe', directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], latticeconstant=a) #bulk = Atoms('Fe4', scaled_positions=[ (0.5,0.5,0), (0.5, 0, 0.5), (0, 0.5, 0.5), (0,0,0)], # magmoms=[5,5,-5,-5], cell=[a,a,a], pbc=(1,1,1)) a = bulk.copy() bulk = bulk * (1, 2, 1) bulk.set_initial_magnetic_moments([5, 5, 5, 5, -5, -5, -5, -5]) s1 = surface(bulk, (1, 2, 1), 6) s1 = s1 * (1, 2, 1) mask = [atom.position[2] < 0.5 or atom.position[2] > 10.0 for atom in s1] constraint = FixAtoms(mask=mask) s1.set_constraint(constraint) atoms = s1 view(s1) os.system('mkdir result') # pts = ibz_points['cubic'] pts = get_special_points('cubic', a.cell) print pts
#!/usr/bin/python import ase from ase import Atoms from ase.lattice.surface import surface from ase.io import * ice = read("0000_Ih_bulk.POSCAR") sf = surface(ice, (0, 0, 1), 1) sf.center(vacuum=0, axis=2) write("Ih_SF_001.POSCAR", sf)
from ase.lattice.surface import surface from ase.io import write # Au(211) with 9 layers s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) write('images/Au-211.png', s1.repeat((3,3,1)), rotation='-30z,90x', # change the orientation for viewing show_unit_cell=2)
a = 3.5574 fcc = FaceCenteredCubic('Fe', directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], latticeconstant=a, pbc=True) fcc.set_calculator(calc) n = fcc.get_number_of_atoms() p = fcc.get_potential_energy() / n v = fcc.get_volume() / n print n, p, v slab1 = surface(fcc, (1, 1, 1), 3) slab1 = slab1 * (1, 1, 1) slab1.set_calculator(calc) n = slab1.get_number_of_atoms() p = slab1.get_potential_energy() / n v = slab1.get_volume() / n print n, p, v slab2 = fcc111('Fe', size=(4, 4, 20), a=a, orthogonal=False) slab2.set_pbc([True, True, True]) view(slab2)
from ase.io import read, write from ase.visualize import view from ase.lattice.surface import surface cut = (1, 0, 0) atoms = read('POSCAR_SiO2') surf = surface(atoms, cut, 3, 10) write('POSCAR_orig', surf) view(atoms)
def save( filename, arg ): f = open(filename, 'a+t') f.write('{0} \n'.format(arg)) f.close() a = 3.5349 bulk = FaceCenteredCubic('Fe', directions=[[1,0,0],[0,1,0],[0,0,1]], latticeconstant=a) #bulk = Atoms('Fe4', scaled_positions=[ (0.5,0.5,0), (0.5, 0, 0.5), (0, 0.5, 0.5), (0,0,0)], # magmoms=[5,5,-5,-5], cell=[a,a,a], pbc=(1,1,1)) bulk = bulk*(1,2,1) bulk.set_initial_magnetic_moments([5,5,5,5,-5,-5,-5,-5]) s1 = surface(bulk, (1,2,1), 3) s1 = s1*(1,2,1) # view(s1) s2 = s1.copy() s2.translate(s2.get_cell()[2]) cell = s1.get_cell() # cell[1] = cell[1]*8./7. cell[1] = cell[1]*24./23. s2.set_cell(cell, scale_atoms=True) s1 = s1+s2 #s2.set_cell([0,1,0], scale_atoms=True)
#!/usr/bin/env python from ase.db import connect from jasp import * from ase.lattice.surface import surface, add_adsorbate from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io import write, read catadb = connect("~/datas/catadb/catadb.db") bulk = catadb.get_atoms(name='pto-fm3m-relax') atoms = surface(bulk, (1, 1, 1), 4, vacuum=10.0) for atom in atoms: if atom.symbol=='Pt': atom.symbol='O' elif atom.symbol=='O': atom.symbol='Pt' constraint = FixAtoms(mask=[atom.z < 17.5 for atom in atoms]) atoms.set_constraint(constraint) with jasp('surfaces/pto-100-224-relax', xc='PBE', kpts=[5, 5, 1], lreal='auto', encut=450, ibrion=2, nsw=500, ediff=1e-5, atoms=atoms) as calc: print atoms.get_potential_energy()
def smart_surf(strt=None, parameters=None, layers=3, tol=0.5): """ Function to get all surface energies Args: strt: Structure object parameters: parameters with LAMMPS inputs layers: starting number of layers tol: surface energy tolerance for convergence Returns: surf_list: list of surface energies surf_header_list: list of surface names """ parameters["control_file"] = input_nobox #'/users/knc6/inelast_nobox.mod' sg_mat = SpacegroupAnalyzer(strt) mat_cvn = sg_mat.get_conventional_standard_structure() mat_cvn.sort() layers = 3 indices = get_symmetrically_distinct_miller_indices(mat_cvn, 1) ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn) for i in indices: ase_slab = surface(ase_atoms, i, layers) ase_slab.center(vacuum=15, axis=2) if len(ase_slab) < 50: layers = 3 surf_arr = [] surf_done = True try: surf = surfer(mat=strt, layers=layers) surf_list = [100000 for y in range(len(surf) - 1)] print("in smart_surf :surf,surf_list=", surf, surf_list) except: print("Failed at s1", os.getcwd()) pass while surf_done: layers = layers + 1 indices = get_symmetrically_distinct_miller_indices(mat_cvn, 1) ase_atoms = AseAtomsAdaptor().get_atoms(mat_cvn) for i in indices: ase_slab = surface(ase_atoms, i, layers) ase_slab.center(vacuum=15, axis=2) # if len(ase_slab) > 100: # surf_done=True # if (ase_slab.get_cell()[2][2]) > 40: # surf_done=True try: surf = surfer(mat=strt, layers=layers) except: print("Failed at s2", os.getcwd()) pass if surf not in surf_arr: surf_arr.append(surf) try: surf_list2, surf_header_list = surf_energy( surf=surf, parameters=parameters ) print("in smart_surf :surf2,surf_list2=", surf_list2, surf_header_list) diff = matrix(surf_list) - matrix(surf_list2) print( "in smart_surf :surf3,surf_list3=", matrix(surf_list), matrix(surf_list2), ) diff_arr = np.array(diff).flatten() except: print("Failed for s_3", os.getcwd()) pass if len(ase_slab) > 50: surf_done = True break # print ("layersssssssssssssssssssssssss",layers,surf_done) break if any(diff_arr) > tol: # for el in diff_arr: # if abs(el)>tol : # print ("in smart_surf :abs el=",abs(el)) surf_done = True surf_list = surf_list2 else: surf_done = False return surf_list, surf_header_list
# creates: s1.png s2.png s3.png s4.png general_surface.pdf from ase.lattice.surface import surface s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) from ase.lattice 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,
#!/usr/bin/python import ase from ase import Atoms from ase.lattice.surface import surface from ase.io import * ice = read("0000_Ic_SC_6x4x4.POSCAR") sf = surface(ice, (-3,8,2), 20) sf.center(vacuum=10, axis=2) write("test.POSCAR", sf)
from ase.lattice.surface import surface from ase.io import write # Au(211) with 9 layers s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) write('images/Au-211.png', s1.repeat((3, 3, 1)), rotation='-30z,90x', # change the orientation for viewing show_unit_cell=2)
from ase.constraints import FixAtoms from ase import Atoms, Atom from ase.io import write, read bulk = read('bulk/pt-relax/CONTCAR') fix_layers = [1, 2, 3, 4, 5, 6] relax_layers = [1, 2, 3, 4, 5, 6] energies=[] vac = 10.0 for fl in fix_layers: for rl in relax_layers: tl = fl + rl ssur = surface(bulk, (1, 1, 1), tl, vacuum=vac) # fix bottom atoms constraint = FixAtoms(mask=[atom.position[2] < ((ssur.cell[2][2] - vac*2)*fl/tl+vac+0.5) for atom in ssur]) ssur.set_constraint(constraint) # add adsorbate CO co = Atoms('CO') co[0].z = ssur[tl-1].z + 1.6 co[1].z = co[0].z + 1.14 ssur = ssur + co write('images/pt-111-co-ontop-{0}-{1}.png'.format(fl, rl), ssur, show_unit_cell=2) with jasp('surfaces/pt-111-114-co-ontop/relax-{0}-{1}'.format(fl, rl), xc='PBE', kpts=[7, 7, 1], encut=450, ibrion=2,
from ase.io import write, read from ase.visualize import view from multiprocessing import Pool import numpy as np def sortz(atoms): tags = atoms.positions[:,2] deco = sorted([(tag, i) for i, tag in enumerate(tags)]) indices = [i for tag, i in deco] return atoms[indices] bulk = read('~/vasp/bulk/ceo2-relax-u/CONTCAR') #bulk[0].z = bulk[0].z + bulk.cell[2][2] #bulk.positions[:,2] -= min(bulk.positions[:,2]) #view(bulk) atoms = surface(bulk, (1, 1, 1), 3, vacuum=0.0) atoms = sortz(atoms) atoms_2o = atoms.copy() atoms_o = atoms.copy() atoms_ce = atoms.copy() atoms_2o.cell[2][2] += 10.0 constraint = FixAtoms(mask=[atom.position[2] < 3.3 for atom in atoms_2o]) atoms_2o.set_constraint(constraint) atoms_2o.write('ceo2-111-2o.in') for i in range(-4, 0): atoms_o[i].z -= atoms_o.cell[2][2] + (atoms_o[-8].z - atoms_o[-9].z)
sigma=0.05, # very small smearing factor for a molecule ispin=2, isif=3, ibrion=2, nsw=200, nelm=100, lreal='auto', atoms=bulk) as calc: print('energy = {0} eV'.format(bulk.get_potential_energy())) print(bulk.get_forces()) print calc bulk = read('bulk/' + sysname + '/CONTCAR') surf = surface(bulk, (1, 1, 1), 5, vacuum = 10) #print(s3.positions[3]) t1 = np.array([0,0,surf.positions[0][2]]) surf.positions = surf.positions - t1 #view(s3, repeat=(1, 1, 1)) #write('surface_ceo2.png', bulk, show_unit_cell=2) constraint = FixAtoms(mask=[atom.tag >= 3 for atom in surf]) surf.set_constraint(constraint) with jasp('surfaces/' + sysname + '-slab-relaxed', xc='PBE', # the exchange-correlation functional encut=400, # planewave cutoff kpts=(3, 3, 1), ismear=0, # Methfessel-Paxton smearing
# creates: s1.png s2.png s3.png s4.png general_surface.pdf from ase.lattice.surface import surface s1 = surface('Au', (2, 1, 1), 9) s1.center(vacuum=10, axis=2) from ase.lattice 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, transparent=False,