예제 #1
0
 def create_interface(self):
     """
     add params that you want to vary
     """
     structure = self.input_structure.copy()
     iface = Interface(structure,
                       hkl=self.system['hkl'],
                       ligand=Ligand.from_dict(self.system['ligand']),
                       from_ase=self.from_ase)
     iface.sort()
     sd = self.set_sd_flags(iface, n_layers=2)
     # if there are other paramters that are being varied
     # change the comment accordingly
     comment = self.system['hkl'] + self.system['ligand']['name']
     return Poscar(iface, comment=comment, selective_dynamics=sd)
예제 #2
0
 def create_interface(self):
     """
     add params that you want to vary
     """
     structure = self.input_structure.copy()
     iface = Interface(structure,
                       hkl=self.system['hkl'],
                       ligand = Ligand.from_dict(self.system['ligand']),
                       from_ase=self.from_ase)
     iface.sort()
     sd = self.set_sd_flags(iface, n_layers=2)
     #if there are other paramters that are being varied
     #change the comment accordingly
     comment = self.system['hkl']+self.system['ligand']['name']
     return Poscar(iface, comment=comment,
                   selective_dynamics=sd)
예제 #3
0
def upload_file():
    stamp = ""
    if request.method == 'POST':
        #request.environ['REMOTE_ADDR']
        if request.environ.get('HTTP_X_FORWARDED_FOR') is None:
            ip = request.environ['REMOTE_ADDR']
        else:
            ip = request.environ['HTTP_X_FORWARDED_FOR']  # if behind a proxy
        #substrate information#
        f1 = request.files['POSCAR_sub']
        stamp = time.strftime("%Y%m%d-%H%M%S") + '-' + ip
        poscar_sub = stamp + '-' + f1.filename
        f1.save(upload_dir + os.sep + secure_filename(poscar_sub))
        h_sub = int(request.form["h_sub"])
        k_sub = int(request.form["k_sub"])
        l_sub = int(request.form["l_sub"])
        nlayers_substrate = int(request.form["nlayers_substrate"])
        min_thick_sub = float(request.form["min_thick_sub"])
        min_vac_sub = float(request.form["min_vac_sub"])
        #is_primitive      = request.form.get["is_primitive"]
        hkl_sub = [h_sub, k_sub, l_sub]

        #2d information#
        f2 = request.files['POSCAR_2d']
        poscar_2d = stamp + '-' + f2.filename
        f2.save(upload_dir + os.sep + secure_filename(poscar_2d))
        h_2d = int(request.form["h_2d"])
        k_2d = int(request.form["k_2d"])
        l_2d = int(request.form["l_2d"])
        nlayers_2d = int(request.form["nlayers_2d"])
        hkl_2d = [h_2d, k_2d, l_2d]

        #General information#
        separation = float(request.form["separation"])
        max_area = float(request.form["max_area"])
        max_mismatch = float(request.form["max_mismatch"])
        max_angle_diff = float(request.form["max_angle_diff"])

        #Matching#
        try:
            substrate_bulk = pymatgen.Structure.from_file(upload_dir + os.sep +
                                                          poscar_sub)
            sa_sub = pymatgen.symmetry.analyzer.SpacegroupAnalyzer(
                substrate_bulk)
            substrate_bulk = sa_sub.get_conventional_standard_structure()
            substrate_slab = Interface(substrate_bulk,
                                       hkl=hkl_sub,
                                       min_thick=min_thick_sub,
                                       min_vac=min_vac_sub,
                                       primitive=False,
                                       from_ase=True)

            mat2d_slab = utils.slab_from_file(hkl_2d,
                                              upload_dir + os.sep + poscar_2d)
            operation_dir = "static" + os.sep + "operations" + os.sep + stamp
            if not os.path.exists(operation_dir):
                os.makedirs(operation_dir)
            mat2d_slab.to(fmt="poscar",
                          filename=operation_dir + "POSCAR_mat2d_slab.vasp")
            sd_flags = CalibrateSlab.set_sd_flags(interface=substrate_slab,
                                                  n_layers=nlayers_substrate,
                                                  top=True,
                                                  bottom=False)
            poscar = pymatgen.io.vasp.inputs.Poscar(
                substrate_slab, selective_dynamics=sd_flags)
            poscar.write_file(filename=operation_dir + os.sep +
                              "POSCAR_substrate_slab.vasp")
            substrate_slab_aligned, mat2d_slab_aligned, mismatch = transformations.get_aligned_lattices(
                substrate_slab,
                mat2d_slab,
                max_area=max_area,
                max_mismatch=max_mismatch,
                max_angle_diff=max_angle_diff,
                r1r2_tol=0.01)
            substrate_slab_aligned.to(fmt="poscar",
                                      filename=operation_dir + os.sep +
                                      "POSCAR_substrate_aligned.vasp")
            mat2d_slab_aligned.to(fmt="poscar",
                                  filename=operation_dir + os.sep +
                                  "POSCAR_mat2d_aligned.vasp")
            hetero_interfaces = transformations.generate_all_configs(
                mat2d_slab_aligned, substrate_slab_aligned, nlayers_2d,
                nlayers_substrate, separation)
            for i, iface in enumerate(hetero_interfaces):
                sd_flags = CalibrateSlab.set_sd_flags(interface=iface,
                                                      n_layers=nlayers_2d +
                                                      nlayers_substrate,
                                                      top=True,
                                                      bottom=False)
                poscar = pymatgen.io.vasp.inputs.Poscar(
                    iface, selective_dynamics=sd_flags)
                poscar.write_file(filename=operation_dir + os.sep +
                                  'POSCAR_final_{}.vasp'.format(i))

                p = Poscar.from_file(operation_dir + os.sep +
                                     'POSCAR_final_{}.vasp'.format(i))
                w = CifWriter(p.structure)
                w.write_file(operation_dir + os.sep +
                             'POSCAR_final_{}.cif'.format(i))


#                st = pychemia.code.vasp.read_poscar(operation_dir+os.sep+'POSCAR_final_{}.vasp'.format(i))
#rf = open("testing")
#rf.write("reading succesful")
#rf.close()
#                pychemia.io.cif.save(structure=st,filename=operation_dir+os.sep+'POSCAR_final_{}.xyz'.format(i))
        except:
            #redirect(url_for("error",_id="matching",stamp=stamp))
            return ("Error")

        return redirect(url_for('result', stamp=stamp))
    return render_template("matching.html",
                           _id="matching",
                           test_var="test",
                           stamp=stamp)
예제 #4
0
# slab thickness and vacuum set manual for now to converged values, surface coverage fixed at 0.014 ligand/sq.Angstrom 
#for consistency, best ligand spacing at the coverage 
min_thick= 19
min_vac= 12
surface_coverage= 0.014
#hkl of facet to reproduce
hkl= [1,0,0]
# specify the species on slab to adsorb over 
slab_species= 'Pb'
# specify the species onb ligand serving as the bridge atom 
adatom_on_ligand= 'O' 
#initial adsorption distance in angstrom
ads_distance = 3.0 
# create the interface
iface = Interface(strt, hkl=hkl, min_thick=min_thick, min_vac=min_vac,
                      supercell=supercell, surface_coverage=surface_coverage,
                      ligand=DMF, displacement=ads_distance, adatom_on_lig= adatom_on_ligand, adsorb_on_species= slab_species, primitive= True)
iface.create_interface()
iface.sort()
#separate slab 
iface_slab = iface.slab
iface_slab.sort()
#set selective dynamics flags as required
true_site= [1, 1, 1]
false_site= [0, 0, 0]
sd_flag_iface= []
j= 0
sd_flag_slab= []
for i in iface.sites:
	sd_flag_iface.append(false_site)
for i in iface_slab.sites:
예제 #5
0
    # firework 4 firetask1: convergence of thickness and vacuum
    slab_firetasks = []
    slab_fireworks = []
    #NOTE: This should be the CONTCAR file under the directory BulkRelax/CONTCAR
    #for testing purposes this is the same bulk structure pulled from matproj
    slab = Interface(bulk,
                     hkl=[1, 0, 0],
                     min_thick=10,
                     min_vac=10,
                     supercell=[1, 1, 1],
                     name=None,
                     adsorb_on_species='Pb',
                     adatom_on_lig='O',
                     ligand=None,
                     displacement=3.0,
                     surface_coverage=0.01,
                     scell_nmax=10,
                     coverage_tol=0.25,
                     solvent="amine",
                     start_from_slab=False,
                     validate_proximity=False,
                     to_unit_cell=False,
                     coords_are_cartesian=False,
                     primitive=True,
                     from_ase=True,
                     x_shift=0,
                     y_shift=0)

    slab_firetasks.append(get_calibration_task(structure=slab, \
                                              turn_knobs={'VACUUM':[400,500,600],
                                                          'THICKNESS':range(5,20)}))
예제 #6
0
    mol = Molecule(mol_struct.species, mol_struct.cart_coords)
    hydrazine = Ligand([mol])
    supercell = [1, 1, 1]
    hkl = [1, 1, 1]
    min_thick = 10
    min_vac = 12
    surface_coverage = 0.01
    adsorb_on_species = 'S'
    adatom_on_lig = 'Pb'
    displacement = 3.0
    iface = Interface(strt,
                      hkl=hkl,
                      min_thick=min_thick,
                      min_vac=min_vac,
                      supercell=supercell,
                      surface_coverage=0.01,
                      ligand=hydrazine,
                      displacement=displacement,
                      adatom_on_lig=adatom_on_lig,
                      adsorb_on_species=adsorb_on_species,
                      primitive=False,
                      coverage_tol=0.5)
    iface.create_interface()
    iface.sort()

    incarparams = {
        'System': 'test',
        'ENCUT': 400,
        'ISMEAR': 1,
        'SIGMA': 0.1,
        'EDIFF': 1E-6
    }
예제 #7
0
    adatom_on_lig = 'N'

    # ligand displacement from the slab surface along the surface normal
    # i.e adatom_on_lig will be displced by this amount from the
    # adsorb_on_species atom
    # on the slab
    # in Angstrom
    displacement = 3.0

    # here we create the interface
    iface = Interface(strt,
                      hkl=hkl,
                      min_thick=min_thick,
                      min_vac=min_vac,
                      supercell=supercell,
                      surface_coverage=0.01,
                      ligand=hydrazine,
                      displacement=displacement,
                      adatom_on_lig='N',
                      adsorb_on_species='Pb',
                      primitive=False)
    iface.create_interface()
    iface.sort()
    # extract bare slab
    iface_slab = iface.slab
    iface_slab.sort()
    # set selective dynamics flags as required
    true_site = [1, 1, 1]
    false_site = [0, 0, 0]
    sd_flag_iface = []
    sd_flag_slab = []
예제 #8
0
    
    #atom on ligand that will be attached to the slab surface
    adatom_on_lig='N'
    
    #ligand displacement from the slab surface along the surface normal
    #i.e adatom_on_lig will be displced by this amount from the
    #adsorb_on_species atom
    #on the slab
    #in Angstrom
    displacement = 3.0

    #here we create the adsorbate slab Interface
    iface = Interface(strt, hkl=hkl, min_thick=min_thick,
                      min_vac=min_vac, supercell=supercell,
                      surface_coverage=surface_coverage,
                      ligand=hydrazine, displacement=displacement,
                      adatom_on_lig=adatom_on_lig, 
                      adsorb_on_species= adsorb_on_species,
                      primitive= False, from_ase=True)
    iface.create_interface()
    iface.sort()
    energy=iface.calc_energy()
    iface.to('poscar','POSCAR_interface.vasp')
    interfaces= coloumb_configured_interface(iface, random=True,
                                             translations= None,
                                             rotations=None,
                                             samples=20, lowest=5,
                                             ecut=energy)
    for i, iface in enumerate(interfaces): 
       print ("Coloumb Energy")
       print (i, iface[0])
예제 #9
0
def coloumb_configured_interface(iface, random=True,
                                 translations=None,
                                 rotations=None,
                                 samples=10, lowest=5, ecut=None):
    """
    Creates Ligand Slab interfaces of user specified translations 
    and rotations away from the initial guess of binding site 
    configuration, returns lowest energy structure according to 
    Coulomb model
    
    Args:
         Interface: Interface object: initial interface object 
         random: True for using Gaussian sampled random numbers for 
                 rotations and translations 
         translations: list of [x,y,z] translations to be performed
         rotation: list of [a,b,c] rotations to be performed w.r.t 
                   Ligand axis
         samples: number of interfaces to create
         lowest: number of structures to return according to order of 
                 minimum energies

    Returns: 
         list of lowest energy interface objects 
    """
    ifaces = []
    transform = []
    for i in range(samples):
        if random:
            x = np.random.normal()  # shift along x direction
            y = np.random.normal()  # shift along y direction
            z = np.random.normal()  # shift aling z direction
            a = SymmOp.from_axis_angle_and_translation(axis=[1, 0, 0], \
                                                       angle=np.random.normal(0, 180))
            b = SymmOp.from_axis_angle_and_translation(axis=[0, 1, 0], \
                                                       angle=np.random.normal(0, 180))
            c = SymmOp.from_axis_angle_and_translation(axis=[0, 0, 1], \
                                                       angle=np.random.normal(0, 180))
            ligand = iface.ligand
            ligand.apply_operation(a)
            ligand.apply_operation(b)
            ligand.apply_operation(c)

        # check if created interface maintains the ligand adsorbed
        # over the surface 
        for j in iface.top_atoms:
            if not iface.cart_coords[j][2] + iface.displacement > \
                    min(ligand.cart_coords[:, 2]):
                transform.append(True)
        if all(transform):
            iface = Interface(iface.strt, hkl=iface.hkl,
                              min_thick=iface.min_thick,
                              min_vac=iface.min_vac,
                              supercell=iface.supercell,
                              surface_coverage=iface.surface_coverage,
                              ligand=iface.ligand, displacement=z,
                              adatom_on_lig=iface.adatom_on_lig,
                              adsorb_on_species=iface.adsorb_on_species,
                              primitive=False, from_ase=True,
                              x_shift=x, y_shift=y)
            iface.create_interface()
            energy = iface.calc_energy()
            iface.sort()
            if energy < ecut:
                ifaces.append((energy, iface))
                # ifaces.zip(energy, iface)
    return ifaces
예제 #10
0
import sys

from pymatgen.core import Structure
from pymatgen.io.vasp.inputs import Poscar

from mpinterfaces.interface import Interface

 
if __name__=='__main__':
    # input structure file: bulk
    fin = 'POSCAR.bulk'
    # output file name
    fout = 'POSCAR'
    hkl = [0,0,1] # hkl wrt the input structure
    min_thick = 15 # angstroms
    min_vac = 30 # angstroms
    #use ase to create an orthogonal slab
    bulk = Structure.from_file(fin) 
    iface = Interface(bulk, hkl=hkl, 
                      min_thick=min_thick, min_vac=min_vac,
                      primitive= False, from_ase = True)
    iface.create_interface()
    iface.sort()
    #set selective dynamics flags
    # 1 --> T and 0 --> F
    sd_flags = [[1,1,1]  for i in iface.sites]
    iface_poscar = Poscar(iface, selective_dynamics= sd_flags)
    #write to file
    iface_poscar.write_file(fout)
예제 #11
0
    workflows.append(get_workflow(lig_fireworks, name='Ligand'))
    #######################################################################################



    ################# THIRD WORKFLOW: SLAB Convergence #####################################
    # construct slab from relaxation firework CONTCAR of firework 2 
    # firework 4 firetask1: convergence of thickness and vacuum 
    slab_firetasks = [] 
    slab_fireworks = [] 
    #NOTE: This should be the CONTCAR file under the directory BulkRelax/CONTCAR
    #for testing purposes this is the same bulk structure pulled from matproj
    slab = Interface(bulk, hkl=[1,0,0], min_thick=10, min_vac=10,
                 supercell=[1,1,1], name=None, adsorb_on_species='Pb',
                 adatom_on_lig='O', ligand=None, displacement=3.0,
                 surface_coverage=0.01, scell_nmax=10, coverage_tol=0.25,
                 solvent="amine", start_from_slab=False, validate_proximity=False,
                 to_unit_cell=False, coords_are_cartesian=False, primitive = True,
                 from_ase=True, x_shift= 0, y_shift= 0)

    slab_firetasks.append(get_calibration_task(structure=slab, \
                                              turn_knobs={'VACUUM':[400,500,600],
                                                          'THICKNESS':range(5,20)}))

    slab_fireworks.append(Firework(slab_firetasks[0], name='slab_convergence'))

    workflows.append(get_workflow(slab_fireworks, name='Slab'))

    #########################################################################################

예제 #12
0
    # atom on ligand that will be attached to the slab surface
    adatom_on_lig = 'N'

    # ligand displacement from the slab surface along the surface normal
    # i.e adatom_on_lig will be displced by this amount from the
    # adsorb_on_species atom
    # on the slab
    # in Angstrom
    displacement = 3.0

    # here we create the adsorbate slab Interface
    iface = Interface(strt, hkl=hkl, min_thick=min_thick,
                      min_vac=min_vac, supercell=supercell,
                      surface_coverage=surface_coverage,
                      ligand=hydrazine, displacement=displacement,
                      adatom_on_lig=adatom_on_lig,
                      adsorb_on_species=adsorb_on_species,
                      primitive=False, from_ase=True)
    iface.create_interface()
    iface.sort()
    energy = iface.calc_energy()
    iface.to('poscar', 'POSCAR_interface.vasp')
    interfaces = coloumb_configured_interface(iface, random=True,
                                              translations=None,
                                              rotations=None,
                                              samples=20, lowest=5,
                                              ecut=energy)
    for i, iface in enumerate(interfaces):
        print("Coloumb Energy")
        print(i, iface[0])
substrate_bulk = Structure.from_file(bulk_filename)

analyzer = SpacegroupAnalyzer(substrate_bulk)
substrate_bulk_conv = analyzer.get_conventional_standard_structure()

writer = CifWriter(substrate_bulk_conv)
writer.write_file("conv_" + bulk_filename)

#| - Loop over all surface surface_cuts

for surface_cut in surface_cuts:

    substrate_slab = Interface(
        substrate_bulk_conv,
        hkl=surface_cut,
        min_thick=10,
        min_vac=25,
        primitive=False,
        from_ase=True,
    )

    if strain_sys == "support":
        lower_mat = mat2d_slab
        upper_mat = substrate_slab
    elif strain_sys == "overlayer":
        lower_mat = substrate_slab
        upper_mat = mat2d_slab

    # mat2d_slab_aligned, substrate_slab_aligned = get_aligned_lattices(
    lower_mat_aligned, upper_mat_aligned = get_aligned_lattices(
        lower_mat,
        upper_mat,
    substrate_bulk = Structure.from_file('POSCAR.mp-2534_GaAs')
    mat2d_bulk = Structure.from_file('POSCAR.mp-406_CdTe')    

    # initialize the substrate and 2d material slabs, constructed
    # from the respective bulk unit cells
    # notes:
    #      ase backend used to ensure that the generated slabs have
    #      orthogonal z axis
    #      2d material vacuum spacing = 0
    #      keep in mind that the 2d material will be put on top of
    #      the subtrate in the substrate's vacuum space.
    #      So ensure that the substrate vacuum spacing is sufficietly
    #      large enough to contain the 2d material
    substrate = Interface(substrate_bulk,
                          hkl = [1,1,0],
                          min_thick = 10,
                          min_vac = 25,
                          primitive = False, from_ase = True)
    mat2d = Interface(mat2d_bulk,
                      hkl = [1,1,0],
                      min_thick = 2,
                      min_vac = 0,
                      primitive = False, from_ase = True)
    substrate.to(fmt='poscar', filename='POSCAR_substrate_initial.vasp')
    mat2d.to(fmt='poscar', filename='POSCAR_mat2d_initial.vasp')        

    # get the matching substrate and 2D material lattices
    uv_substrate, uv_mat2d = get_matching_lattices(substrate, mat2d,
                                             max_area = 200,
                                             max_mismatch = 0.01,
                                             max_angle_diff = 1,
예제 #15
0
def coloumb_configured_interface(iface, random=True,
                                 translations= None,
                                 rotations=None,
                                 samples=10, lowest=5, ecut=None):
    """
    Creates Ligand Slab interfaces of user specified translations 
    and rotations away from the initial guess of binding site 
    configuration, returns lowest energy structure according to 
    Coulomb model
    
    Args:
         Interface: Interface object: initial interface object 
         random: True for using Gaussian sampled random numbers for 
                 rotations and translations 
         translations: list of [x,y,z] translations to be performed
         rotation: list of [a,b,c] rotations to be performed w.r.t 
                   Ligand axis
         samples: number of interfaces to create
         lowest: number of structures to return according to order of 
                 minimum energies

    Returns: 
         list of lowest energy interface objects 
    """
    ifaces= []
    transform= []
    for i in range(samples): 
        if random: 
            x = np.random.normal() # shift along x direction  
            y = np.random.normal() # shift along y direction 
            z = np.random.normal() # shift aling z direction 
            a= SymmOp.from_axis_angle_and_translation(axis=[1,0,0],\
                              angle=np.random.normal(0,180))
            b= SymmOp.from_axis_angle_and_translation(axis=[0,1,0],\
                              angle=np.random.normal(0,180))
            c= SymmOp.from_axis_angle_and_translation(axis=[0,0,1],\
                              angle=np.random.normal(0,180))
            ligand=iface.ligand
            ligand.apply_operation(a)
            ligand.apply_operation(b)
            ligand.apply_operation(c)
               
        # check if created interface maintains the ligand adsorbed
        # over the surface 
        for j in iface.top_atoms: 
            if not iface.cart_coords[j][2] + iface.displacement > \
                               min(ligand.cart_coords[:,2]):
                transform.append(True)
        if all(transform): 
            iface= Interface(iface.strt, hkl=iface.hkl,
                             min_thick=iface.min_thick,
                             min_vac=iface.min_vac,
                             supercell=iface.supercell,
                             surface_coverage=iface.surface_coverage,
                             ligand=iface.ligand, displacement=z,
                             adatom_on_lig=iface.adatom_on_lig, 
                             adsorb_on_species=iface.adsorb_on_species,
                             primitive= False, from_ase=True,
                             x_shift=x, y_shift=y)
            iface.create_interface()
            energy= iface.calc_energy()
            iface.sort()
            if energy<ecut:
                ifaces.append((energy,iface))
           # ifaces.zip(energy, iface)
    return ifaces 
예제 #16
0
def get_entry(args):
    # return -1 ran with an error
    # return 0 ran with no error
    # return 1 match was not found
    # return 2 skiped because radioactive
    # return 3 skipped because noble gas
    # return 4 skipped because atomic number greater than 83 
    _id = args[0]
    counter = args[1]
    mat2d_slab = args[2]
    if counter % 1000 ==0 :
        print("Reached entry number {}".format(counter))
    radioactive_elemets = ["U","Ra","Th","Rn","Po","Pu","Tc","Np","Fr","Cm","Pm","Hs","Re"]
    noble_gases = ["He","Ne","Ar","Kr","Xe","Rn"]
    client = pymongo.MongoClient()
    entries = client.PyChemiaDB_OQMD12.pychemia_entries
    entry = entries.find_one({'_id':_id})
    if len(entry['init_structure']) != 0 :
        st_dict = entry['init_structure']
    elif len(entry['structure']) !=0 : 
        st_dict = entry['structure']
    else :
        print("Structure {} was not found".format(_id))
        return -1
    substrate_bulk = pymatgen.core.Structure(lattice=st_dict["cell"],
                                             species=st_dict['symbols'],coords=st_dict['positions'],coords_are_cartesian=True)
    for element in substrate_bulk.symbol_set : 
        if element in radioactive_elemets : 
            
            return 2
        elif element in noble_gases : 
            return  3
        elif pymatgen.core.Element(element).number > 83 :
            return 4
    sa_sub = pymatgen.symmetry.analyzer.SpacegroupAnalyzer(substrate_bulk)
    try :
        substrate_bulk = sa_sub.get_conventional_standard_structure()
    except :
        return -1
    spg = sa_sub.get_space_group_number()
                
    directions = [ [1,0,0],[0,1,0],[0,0,1],
                  [1,1,0],[0,1,1],[1,0,1],
                  [1,1,1]]
    formula = substrate_bulk.composition.hill_formula

    data = {}
    data[formula] = {}
    data[formula]["space_group_pymatgen"] = spg
    data[formula]["space_group_oqmd"] = entry['properties']['oqmd']['spacegroup_number']
    data[formula]["_id"] = _id

                
    found_one = False
    for direction in directions : 
        data[formula][str(direction)] = {}
        substrate_slab = Interface(substrate_bulk,
                                   hkl=direction,
                                   min_thick=10,
                                   min_vac=15,
                                   primitive=False, from_ase=True)

        try :
            substrate_slab_aligned, mat2d_slab_aligned,mismatch = transformations.get_aligned_lattices(substrate_slab,
                                                                                  mat2d_slab           ,
                                                                                  max_area       = 20 ,
                                                                                  max_mismatch   = 0.05,
                                                                                  max_angle_diff = 1,
                                                                                  r1r2_tol       = 0.01)
        except :    
            print("Except error Matching {} ,id : {}".format(formula,_id))
            continue
            
        if substrate_slab_aligned == None or mat2d_slab_aligned == None :
            continue            
        else :
            data[formula][str(direction)]["mismatch"] = mismatch
          
            if any(mismatch) : 
                found_one = True
    if found_one :
        wf = open("results"+os.sep+str(spg)+'-'+_id+".json",'w')
        json.dump(data,wf,sort_keys=True,indent=4,separators=(',',': '))
        wf.close()
        return 0
    else :
        return 1
예제 #17
0
    strt = Structure.from_file("POSCAR.mp-21276_PbS")
    mol_struct = Structure.from_file("POSCAR_diacetate")
    mol = Molecule(mol_struct.species, mol_struct.cart_coords)
    hydrazine = Ligand([mol])
    supercell = [1, 1, 1]
    hkl = [1, 1, 1]
    min_thick = 10
    min_vac = 12
    surface_coverage = 0.01
    adsorb_on_species = 'S'
    adatom_on_lig = 'Pb'
    displacement = 3.0
    iface = Interface(strt, hkl=hkl, min_thick=min_thick,
                      min_vac=min_vac,
                      supercell=supercell, surface_coverage=0.01,
                      ligand=hydrazine, displacement=displacement,
                      adatom_on_lig=adatom_on_lig,
                      adsorb_on_species=adsorb_on_species,
                      primitive=False, coverage_tol=0.5)
    iface.create_interface()
    iface.sort()

    incarparams = {'System': 'test',
                   'ENCUT': 400,
                   'ISMEAR': 1,
                   'SIGMA': 0.1,
                   'EDIFF': 1E-6}
    incar = Incar(params=incarparams)
    poscar = Poscar(iface)
    potcar = Potcar(symbols=poscar.site_symbols, functional='PBE',
                    sym_potcar_map=None)
예제 #18
0
def get_grain_boundary_interface(structure=None, hkl_pair= {'hkl': [[1,0,0],[1,1,0]],\
                                 'thickness':[10,10]}, twist = 0, tilt = 0, separation=0):
    """
    Args:
        structure: pymatgen structure to create grain boundary in
        hkl_pair:  dict of {'hkl':thickness}
        twist:     twist in degrees
        tilt:      tilt in degrees
    """

    structure = get_struct_from_mp(structure, MAPI_KEY="")
    sa = SpacegroupAnalyzer(structure)
    structure_conventional = sa.get_conventional_standard_structure()
    structure = structure_conventional.copy()
    structure.sort()

    #creation of lower part of grain boundary
    lower= Interface(structure,\
    hkl = hkl_pair['hkl'][0],
    min_thick = hkl_pair['thickness'][0],
    min_vac = separation+hkl_pair['thickness'][1],
    primitive = False, from_ase = True, center_slab=False)

    lower.to(fmt="poscar", filename="POSCAR_lower.vasp")

    #creation of upper part of grain boundary
    upper= Interface(structure,\
    hkl = hkl_pair['hkl'][1],
    min_thick = hkl_pair['thickness'][1],
    min_vac = 0,
    primitive = False, from_ase = True)

    #find top atoms reference of lower part of gb
    substrate_top_z = np.max(np.array([site.coords for site in lower])[:, 2])

    # define twist and tilt vectors
    twist_shift_normal = lower.lattice.matrix[2,:]/\
                         np.linalg.norm(lower.lattice.matrix[2,:])
    tilt_normal = upper.lattice.matrix[1,:]/\
                  np.linalg.norm(upper.lattice.matrix[2,:])

    #define twist operation SymmOp object
    twist_op = SymmOp.from_axis_angle_and_translation(axis= twist_shift_normal,\
                angle=twist, angle_in_radians=False,translation_vec=(0, 0, 0))
    #define tilt operation SymmOp object
    tilt_op = SymmOp.from_axis_angle_and_translation(axis= tilt_normal,\
                angle=tilt, angle_in_radians=False,translation_vec=(0, 0, 0))
    upper.apply_operation(twist_op)
    upper.to(fmt="poscar", filename="POSCAR_upper.vasp")
    upper.apply_operation(tilt_op)

    #define shift separation along twist vector normal to upper plane
    shift = -1 * twist_shift_normal / np.linalg.norm(
        twist_shift_normal) * separation
    #define origin to shift w.r.t top of the lower grain
    origin = np.array([0, 0, substrate_top_z])
    #shift sites in upper
    for site in upper:
        new_coords = site.coords - origin + shift
        lower.append(site.specie, new_coords, coords_are_cartesian=True)
    return lower
예제 #19
0
from mpinterfaces import get_struct_from_mp
from mpinterfaces.interface import Interface
from mpinterfaces.transformations import *
from mpinterfaces.utils import *

seperation = 3  # in angstroms
nlayers_2d = 2
nlayers_substrate = 2

substrate_bulk = Structure.from_file('POSCAR_substrate')
#substrate_bulk = get_struct_from_mp('Ag')
sa_sub = SpacegroupAnalyzer(substrate_bulk)
substrate_bulk = sa_sub.get_conventional_standard_structure()
substrate_slab = Interface(substrate_bulk,
                           hkl=[1, 1, 1],
                           min_thick=10,
                           min_vac=25,
                           primitive=False,
                           from_ase=True)
#substrate_slab = slab_from_file([0,0,1], 'POSCAR_substrate')
mat2d_slab = slab_from_file([0, 0, 1], 'POSCAR_2D')
# get the in-plane lattice aligned slabs
#substrate_slab.to(fmt='poscar', filename='POSCAR_substrate_slab.vasp')
mat2d_slab.to(fmt='poscar', filename='POSCAR_mat2d_slab.vasp')
# selective dynamics flag
sd_flags = CalibrateSlab.set_sd_flags(interface=substrate_slab,
                                      n_layers=nlayers_substrate,
                                      top=True,
                                      bottom=False)
poscar = Poscar(substrate_slab, selective_dynamics=sd_flags)
poscar.write_file(filename='POSCAR_substrate_slab.vasp')
# get aligned lattices
예제 #20
0
from pymatgen.core import Structure
from pymatgen.io.vasp.inputs import Poscar

from mpinterfaces.interface import Interface

if __name__ == '__main__':
    # input structure file: bulk
    fin = 'POSCAR.bulk'
    # output file name
    fout = 'POSCAR'
    hkl = [0, 0, 1]  # hkl wrt the input structure
    min_thick = 15  # angstroms
    min_vac = 30  # angstroms
    # use ase to create an orthogonal slab
    bulk = Structure.from_file(fin)
    iface = Interface(bulk,
                      hkl=hkl,
                      min_thick=min_thick,
                      min_vac=min_vac,
                      primitive=False,
                      from_ase=True)
    iface.create_interface()
    iface.sort()
    # set selective dynamics flags
    # 1 --> T and 0 --> F
    sd_flags = [[1, 1, 1] for i in iface.sites]
    iface_poscar = Poscar(iface, selective_dynamics=sd_flags)
    # write to file
    iface_poscar.write_file(fout)
예제 #21
0
        for direction in data[key]:
            if ('_' not in direction) and (len(data[key][direction]) != 0):
                directions.append(json.loads(direction))
        dir_name = "matched_poscars" + os.sep + str(spg) + '-' + _id
        if not os.path.exists(dir_name):
            os.mkdir(dir_name)
        substrate_bulk.to(fmt='poscar',
                          filename=dir_name + os.sep +
                          item.replace('json', 'vasp'))
        for direction in directions:
            address = dir_name + os.sep + str(direction)
            if not os.path.exists(address):
                os.mkdir(address)
            substrate_slab = Interface(substrate_bulk,
                                       hkl=direction,
                                       min_thick=10,
                                       min_vac=15,
                                       primitive=False,
                                       from_ase=True)
            sd_flags = CalibrateSlab.set_sd_flags(interface=substrate_slab,
                                                  n_layers=nlayers_substrate,
                                                  top=True,
                                                  bottom=False)

            substrate_slab_aligned, mat2d_slab_aligned, mismatch = transformations.get_aligned_lattices(
                substrate_slab,
                mat2d_slab,
                max_area=40,
                max_mismatch=0.05,
                max_angle_diff=20,
                r1r2_tol=0.01)
            substrate_slab_aligned.to(fmt='poscar',
예제 #22
0
    substrate_bulk = Structure.from_file('POSCAR.mp-2534_GaAs')
    mat2d_bulk = Structure.from_file('POSCAR.mp-406_CdTe')

    # initialize the substrate and 2d material slabs, constructed
    # from the respective bulk unit cells
    # notes:
    #      ase backend used to ensure that the generated slabs have
    #      orthogonal z axis
    #      2d material vacuum spacing = 0
    #      keep in mind that the 2d material will be put on top of
    #      the subtrate in the substrate's vacuum space.
    #      So ensure that the substrate vacuum spacing is sufficietly
    #      large enough to contain the 2d material
    substrate = Interface(substrate_bulk,
                          hkl=[1, 1, 0],
                          min_thick=10,
                          min_vac=25,
                          primitive=False,
                          from_ase=True)
    mat2d = Interface(mat2d_bulk,
                      hkl=[1, 1, 0],
                      min_thick=2,
                      min_vac=0,
                      primitive=False,
                      from_ase=True)
    substrate.to(fmt='poscar', filename='POSCAR_substrate_initial.vasp')
    mat2d.to(fmt='poscar', filename='POSCAR_mat2d_initial.vasp')

    # get the matching substrate and 2D material lattices
    uv_substrate, uv_mat2d = get_matching_lattices(substrate,
                                                   mat2d,
                                                   max_area=200,
예제 #23
0
from mpinterfaces.interface import Interface
from mpinterfaces.utils import get_run_cmmnd

MAPI_KEY = os.environ.get("MAPI_KEY", "")
# get structure from materialsproject, use your own key
strt = get_struct_from_mp('PbS', MAPI_KEY=MAPI_KEY)
# convert from fcc primitive to conventional cell
# the conventional unit cell is used to create the slab
# this is important becasue the hkl specification for the required slab
# is wrt the provided unit cell
sa = SpacegroupAnalyzer(strt)
structure_conventional = sa.get_conventional_standard_structure()
strt = structure_conventional.copy()
# create slab
iface = Interface(strt, hkl=[1, 1, 1],
                  min_thick=10, min_vac=10,
                  supercell=[1, 1, 1])
# sort structure into groups of elements atoms for Potcar mapping 
iface.sort()
# vasp input
incar_dict = {
    'SYSTEM': 'test',
    'ENCUT': 500,
    'ISIF': 2,
    'IBRION': 2,
    'ISMEAR': 1,
    'EDIFF': 1e-06,
    'NPAR': 8,
    'SIGMA': 0.1,
    'NSW': 100,
    'PREC': 'Accurate'
예제 #24
0
def create_heterostructure(
    bulk_structure=None,
    slab_structure=None,

    strain_sys="overlayer",  # 'support' or 'overlayer'

    surface_cut=[0, 0, 1],
    separation=3,
    nlayers_2d=1,
    nlayers_substrate=4,

    # Lattice matching algorithm parameters
    max_area=40,
    max_mismatch=1,
    max_angle_diff=0.1,
    r1r2_tol=0.01,
    ):
    """

    bulk_structure:
        ase atoms object for the support material
    slab_structure:
        overlayer material

    strain_sys:
    surface_cut:
    separation:
    nlayers_2d:
    nlayers_substrate:
    max_area:
    max_mismatch:
    max_angle_diff:
    r1r2_tol:

    """
    #| - create_heterostructure

    #| - Generate Heterostructures
    # substrate_bulk = Structure.from_file(bulk_filename)

    substrate_slab = Interface(
        bulk_structure,
        # substrate_bulk,
        hkl=surface_cut,
        min_thick=20,
        min_vac=30,
        primitive=False,
        from_ase=True,
        )

    # mat2d_slab = slab_from_file([0, 0, 1], graphene_filename)
    mat2d_slab = slab_structure

    if strain_sys == "support":
        lower_mat = mat2d_slab
        upper_mat = substrate_slab
    elif strain_sys == "overlayer":
        lower_mat = substrate_slab
        upper_mat = mat2d_slab

    # mat2d_slab_aligned, substrate_slab_aligned = get_aligned_lattices(
    lower_mat_aligned, upper_mat_aligned = get_aligned_lattices(
        lower_mat,
        upper_mat,
        max_area=max_area,
        max_mismatch=max_mismatch,
        max_angle_diff=max_angle_diff,
        r1r2_tol=r1r2_tol,
        )

    if strain_sys == "support":
        mat2d_slab_aligned = lower_mat_aligned
        substrate_slab_aligned = upper_mat_aligned
    elif strain_sys == "overlayer":
        mat2d_slab_aligned = upper_mat_aligned
        substrate_slab_aligned = lower_mat_aligned


    # Writing hetero_interfaces to pickle file
    with open('aligned_latt_materials.pickle', 'wb') as fle:
        pickle.dump((substrate_slab_aligned, mat2d_slab_aligned), fle)

    substrate_slab_aligned.to(filename='00_substrate_opt.POSCAR')
    mat2d_slab_aligned.to(filename='00_graphene_opt.POSCAR')

    # merge substrate and mat2d in all possible ways
    hetero_interfaces = generate_all_configs(
        mat2d_slab_aligned,
        substrate_slab_aligned,
        nlayers_2d,
        nlayers_substrate,
        separation,
        )

    # Writing hetero_interfaces to pickle file
    with open('hetero_interfaces.pickle', 'wb') as fle:
        pickle.dump(hetero_interfaces, fle)
    #__|

    return(hetero_interfaces)
예제 #25
0
def get_grain_boundary_interface(structure=None, hkl_pair= {'hkl': [[1,0,0],[1,1,0]],\
                                 'thickness':[10,10]}, twist = 0, tilt = 0, separation=0):
    """
    Args:
        structure: pymatgen structure to create grain boundary in
        hkl_pair:  dict of {'hkl':thickness}
        twist:     twist in degrees
        tilt:      tilt in degrees
    """


    structure = get_struct_from_mp(structure, MAPI_KEY="")
    sa = SpacegroupAnalyzer(structure)
    structure_conventional = sa.get_conventional_standard_structure()
    structure = structure_conventional.copy()
    structure.sort()

    #creation of lower part of grain boundary
    lower= Interface(structure,\
    hkl = hkl_pair['hkl'][0],
    min_thick = hkl_pair['thickness'][0],
    min_vac = separation+hkl_pair['thickness'][1],
    primitive = False, from_ase = True, center_slab=False)

    lower.to(fmt="poscar", filename="POSCAR_lower.vasp")

    #creation of upper part of grain boundary
    upper= Interface(structure,\
    hkl = hkl_pair['hkl'][1],
    min_thick = hkl_pair['thickness'][1],
    min_vac = 0,
    primitive = False, from_ase = True)

    #find top atoms reference of lower part of gb
    substrate_top_z = np.max(np.array([site.coords for site in lower])[:,2])

    # define twist and tilt vectors
    twist_shift_normal = lower.lattice.matrix[2,:]/\
                         np.linalg.norm(lower.lattice.matrix[2,:])
    tilt_normal = upper.lattice.matrix[1,:]/\
                  np.linalg.norm(upper.lattice.matrix[2,:])

    #define twist operation SymmOp object
    twist_op = SymmOp.from_axis_angle_and_translation(axis= twist_shift_normal,\
                angle=twist, angle_in_radians=False,translation_vec=(0, 0, 0))
    #define tilt operation SymmOp object
    tilt_op = SymmOp.from_axis_angle_and_translation(axis= tilt_normal,\
                angle=tilt, angle_in_radians=False,translation_vec=(0, 0, 0))
    upper.apply_operation(twist_op)
    upper.to(fmt="poscar", filename="POSCAR_upper.vasp")
    upper.apply_operation(tilt_op)

    #define shift separation along twist vector normal to upper plane
    shift = -1*twist_shift_normal/np.linalg.norm(twist_shift_normal) * separation
    #define origin to shift w.r.t top of the lower grain 
    origin = np.array([0,0, substrate_top_z])
    #shift sites in upper 
    for site in upper:
        new_coords = site.coords - origin  +  shift
        lower.append(site.specie, new_coords, coords_are_cartesian=True)
    return lower 
예제 #26
0
    adsorb_on_species = 'Pb'

    # atom on ligand that will be attached to the slab surface
    adatom_on_lig = 'N'

    # ligand displacement from the slab surface along the surface normal
    # i.e adatom_on_lig will be displced by this amount from the
    # adsorb_on_species atom
    # on the slab
    # in Angstrom
    displacement = 3.0

    # here we create the interface
    iface = Interface(strt, hkl=hkl,
                      min_thick=min_thick, min_vac=min_vac,
                      supercell=supercell, surface_coverage=0.01,
                      ligand=hydrazine, displacement=displacement,
                      adatom_on_lig='N', adsorb_on_species='Pb',
                      primitive=False)
    iface.create_interface()
    iface.sort()
    # extract bare slab
    iface_slab = iface.slab
    iface_slab.sort()
    # set selective dynamics flags as required
    true_site = [1, 1, 1]
    false_site = [0, 0, 0]
    sd_flag_iface = []
    sd_flag_slab = []
    # selective dynamics flags for the interface
    for i in iface.sites:
        sd_flag_iface.append(false_site)
    # ligand displacement from the slab surface along the surface normal
    # i.e adatom_on_lig will be displced by this amount from the
    # adsorb_on_species atom
    # on the slab
    # in Angstrom
    displacement = 3.0

    # here we create the interface
    iface = Interface(
        strt,
        hkl=hkl,
        min_thick=min_thick,
        min_vac=min_vac,
        supercell=supercell,
        surface_coverage=0.01,
        ligand=hydrazine,
        displacement=displacement,
        adatom_on_lig="N",
        adsorb_on_species="Pb",
        primitive=False,
    )
    iface.create_interface()
    iface.sort()
    # extract bare slab
    iface_slab = iface.slab
    iface_slab.sort()
    # set selective dynamics flags as required
    true_site = [1, 1, 1]
    false_site = [0, 0, 0]
    sd_flag_iface = []