Пример #1
0
def optimize_wrapper(cl, ise, add=0, show_fit=1, params=None):
    #wrapper for optimization function

    up_res = 'up1'
    readfiles = 1
    check_job = 1
    id_res = (cl.id[0] + '.su', ise, 100)

    if add:
        add_loop(*cl.id,
                 ise_new=ise,
                 up='up2',
                 calc_method='uniform_scale',
                 scale_region=(-4, 4),
                 input_st=cl.end,
                 show='',
                 run=0,
                 inherit_option='inherit_xred',
                 it_folder=cl.sfolder + '/scaled/',
                 params=params)
    else:

        if show_fit:
            res_loop(*id_res[0:2],
                     list(range(0 + 1, 0 + 8)) + [100],
                     up=up_res,
                     readfiles=readfiles,
                     analys_type='fit_a',
                     show='fitfo')
        else:
            res_loop(*id_res, up=up_res, show='fo', check_job=check_job)
Пример #2
0
def run_wrapper(sts, ise = None, add = 0, cl = None, suf = 'w',  it_folder = None, ngkpt = None, acc = None, ise1= None, acc2 = None, ise2 = None):
    """
    Add Several  structures
    """
    folder = suf.replace('.', '')
    # print(folder)
    # sys.exit()
    if ise1 is None:
        ise1 = ise

    for i, st in enumerate(sts): 

        itn = cl.id[0]+suf+ str(i)
        # del header.struct_des[itn]
        # continue
        if add:
            add_loop(itn, ise, 1, show = 'fo', up = 'up2', input_st = st,  ngkpt = ngkpt, it_folder = cl.sfolder+'/'+folder+'/', ) #
        else:
            ''
            
            if acc:
                if acc2:
                    db[itn+'.ifc', ise1, 1].run(ise2, show = 'fo', iopt = 'full_chg', add  = 0, up = 'up2', ngkpt = ngkpt)

                else:
                    db[itn, ise, 1].run(ise1, show = 'fo', iopt = 'full_chg', add  = 0, up = 'up2', ngkpt = ngkpt)
            else:
                res_loop(itn, ise, 1, up = 'up2')



    return
Пример #3
0
def calc_bulk_list(data_list,
                   spacegroup='',
                   ise_nomag='8',
                   ise_mag='8m',
                   status=None,
                   up=None,
                   corenum=1):
    """
    function can add or res for set of bulk calculations
    
    data_list = read_pmg_info() of some csv file

    ise  - set of calculation. Usually use '8' for nonmag calc and '8m' for mag calc
    status = add or res
    """

    spacegroup = '.' + spacegroup

    for i in data_list:
        st = get_matproj_st(i)

        if float(i['total_magnetization']):
            mag_flag = 1
            ise = ise_mag
        else:
            mag_flag = 0
            ise = ise_nomag

        if status == 'add':
            add_loop(i['pretty_formula'] + spacegroup,
                     ise,
                     1,
                     it_folder='bulk',
                     input_st=st,
                     corenum=corenum)
        if status == 'res':

            try:

                res_loop(i['pretty_formula'] + spacegroup,
                         ise,
                         1,
                         it_folder='bulk',
                         up=up)

            except KeyError:
                print(i['total_magnetization'])
Пример #4
0
def run_wrapper(sts,
                ise=None,
                add=0,
                cl=None,
                suf='w',
                it_folder=None,
                cls=None,
                ngkpt=None,
                acc=None,
                ise1=None,
                acc2=None,
                ise2=None,
                params=None):
    """
    Add Several  structures

    params - pass to add_loop


    if add == 0:
        read results

    RETURN
    cl with lowest energy

    """

    if params is None:
        params = {}

    folder = suf.replace('.', '')
    # print(folder)
    # sys.exit()
    if ise1 is None:
        ise1 = ise

    if cls is None:
        cls = [cl] * len(sts)
    energies = []
    for i, st, cl_i in zip(range(len(sts)), sts, cls):

        itn = cl_i.id[0] + suf + str(i)
        # del header.struct_des[itn]
        # continue
        if add:
            # add_loop(itn, ise, 1, show = 'fo', up = 'up2', input_st = st,  ngkpt = ngkpt, it_folder = cl.sfolder+'/'+folder+'/', **params ) #
            add_loop(itn,
                     ise,
                     1,
                     show='fo',
                     up='up2',
                     input_st=st,
                     ngkpt=ngkpt,
                     it_folder=cl.sfolder,
                     **params)  #

        else:
            ''

            if acc:
                if acc2:
                    db[itn + '.ifc', ise1, 1].run(ise2,
                                                  show='fo',
                                                  iopt='full_chg',
                                                  add=0,
                                                  up='up1',
                                                  ngkpt=ngkpt)
                    cln = db[itn + '.ifc.ifc', ise2, 1]

                else:
                    # db[itn, ise, 1].run(ise1, show = 'fo', iopt = 'full_chg', add  = 0, up = 'up1', ngkpt = ngkpt)
                    cln = db[itn + '.ifc', ise1, 1]
                    cln.res(choose_outcar=0, show='fo')
                    suf_acc = '.ifc'
            else:
                suf_acc = ''

                res_loop(itn, ise, 1, up='up1')
                cln = db[itn, ise, 1]

            if hasattr(cln, 'e0'):
                energies.append(cln.e0)

    for i, e in enumerate(energies):
        print(i, e)

    if not add and len(energies) > 0:
        i_min = energies.index(min(energies))
        print('Minimum energy is for ', i_min, energies[i_min])
        itn = cl.id[0] + suf + str(i_min) + suf_acc
        db[itn, ise, 1].res()

        return db[itn, ise, 1]
    else:
        return None
Пример #5
0
def make_defect(cl,
                el,
                st_type='end',
                option='vac',
                pos=None,
                ise=None,
                opt_vol=0,
                suf='',
                it_folder=None,
                el_rep='',
                pos_rep=1,
                pos_rep2=None,
                polaron_pos=None,
                occ_matrix=None,
                up=0,
                fit=0,
                outcar=None,
                only_read=0,
                Eref=0,
                compat1=False,
                add_loop_arg={}):
    """
    Function allow to create point defects and run them
	previous name: make_vacancy()


    cl - starting Calculation 
    st_type - starting structure of cl: 'init' or 'end' 
    el - element to be removed or replaced
    
    option -
        'vac'  - make vacancy
        'rep'  - replace one atom with 'el_rep', 
        'pair' - make vacancy -Ti complex for V-Ti project 

    pos - unique position of el if non-eqivalent atoms exist - for vac
    pos_rep - number of position to replace from 0

    ise - new set
    opt_vol (bool) - optimize volume

    suf (str) - mannually added suffix
    it_folder - mannually provided it_folder

    up (bool) - [ 0, 1 ] update current calculation
    fit = 0,  outcar = None, only_read = 0 - flow control as usual

    polaron_pos - choose polaron position
    occ_matrix - list of lists see format in classes


    compat1 - compatability with previous calculations, which were used for Na2FePO4F project


    Eref - reference energy for solution energy

    TODO: rename to ?_point_defects()
    """

    from siman.project_funcs import e_bind

    if pos == None:
        pos = ''

    if polaron_pos == None:
        pol_suf = ''
    else:
        pol_suf = '.p' + str(polaron_pos)  # polaron suffix

    ssuf = el + str(pos) + el_rep + pol_suf + suf
    if 'su' in cl.id[0] and not 'su.' in cl.id[0]:
        it_new = cl.id[0].replace('su', option) + ssuf
    else:
        it_new = cl.id[0] + option + ssuf

    if compat1:  # no element in name
        it_new = cl.id[0].replace('su', 'vac') + str(pos)

    id_new, st, it_folder = prepare(it_new, opt_vol, it_folder, ise, cl,
                                    st_type, option)
    occfile = None
    if not only_read and (up or id_new not in calc):
        # it_new

        if 'vac' in option:
            st_del1, i_del = remove_one_atom(st, el, pos)
            st_vis = st.replace_atoms([i_del], 'U')
            st_vis.name = it_new + '_visual'
            st_vis.write_xyz()

            #possible polaron positions
            tr = st.get_transition_elements(fmt='z')
            i_tr = st.get_transition_elements(fmt='n')
            # dist = []
            max_d = 0
            i_max_d = None
            for i in i_tr:
                d1, d2 = image_distance(st.xcart[i], st.xcart[i_del],
                                        st.rprimd)
                # print(i+1, d1, d2)
                if d1 < d2:
                    if d1 > max_d:
                        max_d = d1
                        i_max_d = i
            if i_max_d is not None:
                print(
                    'The longest distance to transition metal in current supercell is ',
                    max_d, 'A for atom', i_max_d + 1,
                    st.get_elements()[i_max_d])

            numb = st.nn(i_del, from_one=0, n=len(tr) + 5,
                         only=list(set(tr)))['numbers'][1:]

            printlog(
                'Choose polaron position starting from 1 using *polaron_pos*',
                imp='y')
            if polaron_pos:
                i_pol = numb[polaron_pos - 1]
                printlog('atom',
                         i_pol + 1,
                         st.get_elements()[i_pol],
                         'is chosen',
                         imp='y')
                # print(numb)
                # sys.exit()
                #take_occupation matrices from cl
                print('substitution occupation matrix of atom', i_pol + 1)
                occ_matrices = copy.deepcopy(cl.occ_matrices)
                occ_matrices[i_pol] = occ_matrix
                # print(pd.DataFrame(cl.occ_matrices[i_pol]))
                occfile = write_occmatrix(occ_matrices, cl.dir + '/occ/')
                # print(occfile)

                # sys.exit()
            else:
                occfile = None

        elif 'rep' in option:
            st_del1 = st.replace_atoms([pos_rep], el_rep)
            print(
                'Atom',
                str(pos_rep),
                st.get_elements()[pos_rep],
                ' replaced with',
                el_rep,
            )
            print(st_del1.get_elements()[pos_rep])
            st_del1.name = it_new

        elif 'pair' in option:
            st_del1 = st.replace_atoms([1], el_rep)
            if 'pair2' in option:
                st_del1 = st_del1.replace_atoms([pos_rep2], el_rep)

            st_del1 = remove_one_atom(st_del1, el, pos)
            print('Atom 1 replaced with', el, 'and atom removed')
            st_del1.name = it_new

        st_del1.write_xyz()

        if opt_vol:
            it = add_loop(it_new,
                          ise,
                          1,
                          calc_method='uniform_scale',
                          scale_region=(-4, 4),
                          inherit_option='inherit_xred',
                          input_st=st_del1,
                          it_folder=it_folder,
                          params={'occmatrix': occfile},
                          **add_loop_arg)
        else:
            it = add_loop(it_new,
                          ise,
                          1,
                          input_st=st_del1,
                          it_folder=it_folder,
                          params={'occmatrix': occfile},
                          **add_loop_arg)

    else:
        if opt_vol and fit:
            res_loop(it_new + '.su',
                     ise,
                     list(range(1, 8)) + [100],
                     analys_type='fit_a',
                     show='fitfo',
                     up='2',
                     choose_outcar=outcar)
        else:
            res_loop(*id_new, up='2', choose_outcar=outcar, show='fo')
            # calc[it_new+'.su', ise, 100].end.jmol()

        cl_v = calc[id_new]
        if '4' not in cl.state:
            cl.res()
        if not hasattr(cl_v, 'e0'):
            printlog('Warning', cl_v.id, 'is bad')
            return
        calc_redox(cl_v, cl)
        # print(cl_v.end.vol, cl.end.vol)
        dE = None

        if option == 'vac':
            cl_v.res()
            cl.res()
            print('Evac = {:3.2f} eV'.format(cl_v.e0 - cl.e0 / cl.end.natom *
                                             cl_v.end.natom))

        elif option == 'rep':
            diffE, diffV = matrix_diff(cl_v, cl)

            print('Esol = {:3.2f} eV'.format(diffE - Eref))

        elif 'pair' in option:
            ''
            cl_bulk = cl
            cl_pair = cl_v
            it = cl.id[0]
            if 'V54' in it:
                it = it.replace('.su', '.')
            id_vac = (it + 'vacV', cl.id[1], 1)
            id_sol = (it + 'repTi', cl.id[1], 1)
            cl_vac = calc[id_vac]
            cl_sol = calc[id_sol]

            # print(id_vac, id_sol)

            # if  option == 'pair':
            dE = e_bind(cl_bulk, cl_vac, cl_sol, cl_pair)
            print('Ecomplex = {:3.2f} eV'.format(dE))

            # elif '2' in option:

        return {'dE': dE, 'N': cl_v.end.natom, 'Name': cl.id}
Пример #6
0
def create_segregation_cases(it,
                             ise,
                             verlist,
                             dist_gb,
                             gbpos=None,
                             ise_new=None,
                             option=None,
                             precip_folder=None,
                             use_init=False,
                             precision=None):
    """
    Written for Ti-Fe project.
    Allows to create segregation by substituting atoms;
    dist_gb - distance from gb inside which the atoms are included
    

    option = 'precip'- adding additional impurities to the already existing at gb. Please use 'precip_folder'
    use_init - allows to use initial structure.


    !Warning PBC are not used in determination of seg positions 

    """

    # hstring = ("%s    #on %s"% (traceback.extract_stack(None, 2)[0][3],   datetime.date.today() ) )
    # try:
    #     if hstring != header.history[-1]: header.history.append( hstring  )
    # except:
    #     header.history.append( hstring  )
    def write_local(cl, it_new, it_new_path, el_sub, main_path):
        cl.version = v
        # it_new_path

        cl.name = it_new
        cl.des = 'Obtained from end state of ' + str(
            (it, ise, v)
        ) + ' by substitution of one atom near gb with ' + el_sub + ' impurity '
        path_new_geo = it_new_path + "/" + it_new + "/" + it_new + '.imp.' + el_sub + '.' + str(
            cl.version) + '.' + 'geo'
        cl.init.name = it_new + ".init." + str(cl.version)
        xyzpath = it_new_path + "/" + it_new
        cl.path["input_geo"] = path_new_geo
        print(path_new_geo)
        cl.write_geometry("init", cl.des, override=1)
        write_xyz(cl.init, xyzpath)
        return it_new_path

    if 0:
        res_loop(it, ise, verlist, up=0)

    cl = header.calc[(it, ise, verlist[0])]

    znucl_sub = 3  #atom to be added
    """1. Create list of atoms near gb to substitue"""
    cl.gbpos = gbpos
    # print cl.gbpos
    seg_pos_list = []  # numbers of segregation positions

    if use_init:
        st = cl.init
    else:
        st = cl.end

    # print(st.xcart)
    if len(st.xcart) == 0:
        print(
            'Warning!, xcart is empty',
            cl.id,
        )
    for i, x in enumerate(st.xcart):
        z_cur = st.znucl[st.typat[i] - 1]
        print('z_cur', z_cur)
        if z_cur == znucl_sub:
            printlog('Skipping znucl_sub atom\n')
            continue
        if abs(x[0] - gbpos) < dist_gb:
            print('adding possible seg position')
            seg_pos_list.append(i)
    """2. Substitue"""
    el_sub = invert(znucl_sub)
    base_name = it
    main_path = header.struct_des[it].sfolder
    based_on = it + '.' + ise
    des_list = []
    add_list = []

    cl_list = []
    sumr_list = []

    i = 0
    # print(seg_pos_list)
    for j, replace_atom in enumerate(seg_pos_list):  #

        v = verlist[0]  # the first version from list is used
        cl = calc[(it, ise, v)]
        cl.gbpos = gbpos

        new = copy.deepcopy(cl)
        if use_init:
            new.end = new.init
        else:
            new.init = new.end  #replace init structure by the end structure

        if 1:  #atom substitution !make function; see TODO

            if znucl_sub not in new.init.znucl:
                new.init.znucl.append(znucl_sub)
                new.init.ntypat += 1
                new.init.typat[replace_atom] = new.init.ntypat
            else:
                ind = new.init.znucl.index(znucl_sub)
                new.init.typat[replace_atom] = ind + 1
            new.init.nznucl = []
            for typ in range(1, new.init.ntypat + 1):
                new.init.nznucl.append(new.init.typat.count(typ))
            printlog("Impurity with Z=" + str(znucl_sub) +
                     " has been substituted in " + new.name + "\n\n")

            it_new = base_name + el_sub + 'is' + str(
                i + 1)  #interface substitution

            if option == 'precip':
                it_new_path = precip_folder

            else:
                it_new_path = main_path + '/' + base_name + '_segreg'

        #Check if configuration is unique
        add = 1
        # for cl in cl_list:
        st = new.end
        st_replic = replic(st, (2, 2, 2))
        st_replic = replic(st_replic, (2, 2, 2),
                           -1)  #replic in negative direction also
        sumr = local_surrounding(
            st.xcart[replace_atom], st_replic,
            n_neighbours=6)  # sum of distances to surrounding atoms
        print("sumr", sumr)
        for ad_sumr in sumr_list:
            if abs(ad_sumr - sumr) < precision:
                add = 0
                printlog("The void is non-equivalent; skipping\n")

        if add:
            i += 1
            sumr_list.append(sumr)
            # cl_list.append(new)
            write_local(new, it_new, it_new_path, el_sub, main_path)
            for v in verlist[1:]:  #write files; versions are scaled
                cl = calc[(it, ise, v)]
                rprimd_scaled = cl.end.rprimd
                new_scaled = copy.deepcopy(new)
                new_scaled.init.rprimd = copy.deepcopy(rprimd_scaled)
                new_scaled.init.xred2xcart()
                write_local(new_scaled, it_new, it_new_path, el_sub, main_path)
            #create names
            des_list.append(
                "struct_des['{0:s}'] = des('{1:s}', 'segregation configurations; made from {2:s}'   )"
                .format(it_new, it_new_path, based_on))
            add_list.append("add_loop('" + it_new + "','" + ise_new + "'," +
                            "range(1,6)" + ", up = 'up1', it_folder = '" +
                            it_new_path + "')")

    for d in des_list:
        print(d)

    for d in add_list:
        print(d)

    return
Пример #7
0
def process_modified(cl,
                     mod_dic=None,
                     scale_region=(-4, 4),
                     opt_vol=1,
                     fit=0,
                     st_type='end',
                     name=None,
                     el_new=None,
                     run=0,
                     ise=None,
                     it_folder=None,
                     mode=None,
                     add_loop_arg=None):
    """
    inherited from create_charges - functionality is extended
    The utility allows to (contrlolled by mode parameter):
    1) create charged cells by removing specific atoms provided in del_dic
    2) replace specific atoms 

    add_loop
    res_loop


    mode - 
        delete
        remove
        None

    mod_dic - dic of configurations with atom numbers starting from 1

    """
    # if not del_dic:
    if add_loop_arg == None:
        add_loop_arg = {}

    if mod_dic == None:
        mod_dic = {1: 1}

    for key in mod_dic:
        mod_pos = mod_dic[key]
        if mode:
            mod_pos = [p - 1 for p in mod_pos]

        if mode:
            suf = '.' + mode[0] + str(key)
        else:
            suf = ''

        it_new = cl.id[0] + suf

        id_new, stA, it_folder = prepare(it_new, opt_vol, it_folder, ise, cl,
                                         st_type, mode)

        if run:
            if mode == 'delete':
                st = stA.remove_atoms(mod_pos)
            elif mode == 'replace':
                st = stA.replace_atoms(atoms_to_replace=mod_pos, el_new=el_new)
            else:
                st = stA

            st.name += suf
            st.write_xyz()
            # sys.exit()
            if opt_vol:
                add_loop(it_new,
                         id_new[1],
                         1,
                         calc_method='uniform_scale',
                         scale_region=scale_region,
                         inherit_option='inherit_xred',
                         input_st=st,
                         it_folder=it_folder,
                         **add_loop_arg)
            else:
                add_loop(it_new,
                         id_new[1],
                         1,
                         input_st=st,
                         it_folder=it_folder,
                         **add_loop_arg)

        else:
            if 'check_job' in add_loop_arg:
                cj = add_loop_arg['check_job']
            else:
                cj = None
            if opt_vol and fit:
                # res_loop(id_new[0], id_new[1], list(range(1,8))+[100], analys_type = 'fit_a', show = 'fitfo', up = '2', choose_outcar = None)
                res_loop(id_new[0],
                         id_new[1],
                         list(range(1, 8)) + [100],
                         analys_type='fit_a',
                         show='fitfo',
                         up='2',
                         choose_outcar=None,
                         check_job=cj)
            else:
                res_loop(*id_new, up='1', choose_outcar=None, show='fo')

    return
Пример #8
0
def run_wrapper(sts,
                ise=None,
                add=0,
                cl=None,
                suf='w',
                it_folder=None,
                cls=None,
                ngkpt=None,
                acc=None,
                ise1=None,
                acc2=None,
                ise2=None,
                params=None):
    """
    Add Several  structures

    params - pass to add_loop

    """

    if params is None:
        params = {}

    folder = suf.replace('.', '')
    # print(folder)
    # sys.exit()
    if ise1 is None:
        ise1 = ise

    if cls is None:
        cls = [cl] * len(sts)

    for i, st, cl in zip(range(len(sts)), sts, cls):

        itn = cl.id[0] + suf + str(i)
        # del header.struct_des[itn]
        # continue
        if add:
            add_loop(itn,
                     ise,
                     1,
                     show='fo',
                     up='up2',
                     input_st=st,
                     ngkpt=ngkpt,
                     it_folder=cl.sfolder + '/' + folder + '/',
                     **params)  #

        else:
            ''

            if acc:
                if acc2:
                    db[itn + '.ifc', ise1, 1].run(ise2,
                                                  show='fo',
                                                  iopt='full_chg',
                                                  add=0,
                                                  up='up2',
                                                  ngkpt=ngkpt)

                else:
                    db[itn, ise, 1].run(ise1,
                                        show='fo',
                                        iopt='full_chg',
                                        add=0,
                                        up='up2',
                                        ngkpt=ngkpt)
            else:
                res_loop(itn, ise, 1, up='up2')

    return
Пример #9
0
def calc_suf_stoich_mat(self,
                        ise='9sm',
                        bulk_cl_name=None,
                        it_folder='bulk/',
                        status='create',
                        suf_list=None,
                        min_slab_size=12,
                        only_stoich=1,
                        corenum=4,
                        cluster='cee',
                        conv=1,
                        create=1,
                        reset_old_polar=0,
                        reset_old_nonpolar=0,
                        suffix=None,
                        polar=1,
                        nonpolar=1):
    from siman.header import db
    from siman.geo import create_surface2, stoichiometry_criteria, stoichiometry_criteria2, symmetry_criteria, calc_k_point_mesh
    from siman.calc_manage import add_loop, res_loop

    if not bulk_cl_name:
        bulk_cl_name = ['it', 'ise', '1']

    if not suf_list:
        suf_list = [[1, 1, 0], [1, 1, 1]]

    st_bulk = db[self.bulk_cl_scale].end.get_conventional_cell()

    # if conv:
    #     st_bulk = st_bulk.get_conventional_cell()

    st_name = '.'.join(
        [self.pretty_formula, self.sg_crystal_str, self.sg_symbol])
    st_name = st_name.replace('/', '_')
    # st_bulk.printme()

    try:
        # print(self.suf)
        self.suf_pol.keys()
    except AttributeError:
        self.suf_pol = {}
        self.suf_pol_status = {}
    try:
        # print(self.suf)
        self.suf_nonpol.keys()
    except AttributeError:
        self.suf_nonpol = {}
        self.suf_nonpol_status = {}

    try:
        self.suf_pol_cl.keys()
    except AttributeError:
        self.suf_pol_cl = {}
    try:
        self.suf_nonpol_cl.keys()
    except AttributeError:
        self.suf_nonpol_cl = {}

    try:
        self.suf_en_pol.keys()
    except AttributeError:
        self.suf_en_pol = {}
    try:
        self.suf_en_nonpol.keys()
    except AttributeError:
        self.suf_en_nonpol = {}

    if reset_old_polar:
        self.suf_pol = {}
        self.suf_pol_status = {}
        self.suf_pol_cl = {}
        self.suf_en_pol = {}

    if reset_old_nonpolar:
        self.suf_nonpol = {}
        self.suf_nonpol_status = {}
        self.suf_nonpol_cl = {}
        self.suf_en_nonpol = {}

    ##################### create slab
    if status == 'create':

        try:
            for surface in suf_list:
                print(surface)

                if self.suf_pol == {} or ''.join(
                    [str(surface[0]),
                     str(surface[1]),
                     str(surface[2])]) not in self.suf_pol.keys():

                    ###############polar
                    if polar:
                        print('Polar_suf')
                        slabs_polar = create_surface2(
                            st_bulk,
                            miller_index=surface,
                            min_slab_size=min_slab_size,
                            min_vacuum_size=15,
                            surface_i=0,
                            symmetrize=0,
                            lll_reduce=1,
                            primitive=1)
                        for sl_i in slabs_polar:
                            st = st_bulk
                            sl = st.update_from_pymatgen(sl_i)
                            print(' Stoichoimetry:',
                                  stoichiometry_criteria2(st, sl),
                                  ' Eqvuivalent:',
                                  sl_i.have_equivalent_surfaces())

                    ############nonpolar
                    if nonpolar:
                        print('Nonpolar_suf')
                        slabs_nonpolar = create_surface2(
                            st_bulk,
                            miller_index=surface,
                            min_slab_size=min_slab_size,
                            min_vacuum_size=15,
                            surface_i=0,
                            symmetrize=1,
                            lll_reduce=1,
                            primitive=1)
                        for sl_i in slabs_nonpolar:
                            st = st_bulk
                            sl = st.update_from_pymatgen(sl_i)

                            print(' Stoichoimetry:',
                                  stoichiometry_criteria2(st, sl),
                                  ' Eqvuivalent:',
                                  sl_i.have_equivalent_surfaces())

                    if create:

                        ###############polar
                        if polar:
                            if len(slabs_polar):
                                s_i = 0
                                n = 0
                                for sl_i in slabs_polar:
                                    st = st_bulk
                                    sl = st.update_from_pymatgen(sl_i)
                                    if stoichiometry_criteria2(
                                            st, sl
                                    ) and sl_i.have_equivalent_surfaces(
                                    ) == False:
                                        # if sl.natom < 31:
                                        suf_name = str(surface[0]) + str(
                                            surface[1]) + str(
                                                surface[2]) + '.' + str(s_i)

                                        # if self.suf_pol_status == 'Zero slabs constructed':
                                        #     self.suf_pol_status = {}

                                        self.suf_pol[suf_name] = sl
                                        self.suf_pol_status[
                                            suf_name] = 'created'
                                        n += 1

                                    s_i += 1
                                print(st_name + ' Polar\n', surface, n,
                                      ' from ', len(slabs_polar), ' slabs\n',
                                      sl.natom, ' atoms\n')

                            else:
                                suf_name = str(surface[0]) + str(
                                    surface[1]) + str(
                                        surface[2]) + '.' + str(0)
                                self.suf_pol_status[
                                    suf_name] = 'Zero slabs constructed'
                                print('\nWarning!  Zero slabs constructed!\n')

                        ###############nonpolar
                        if nonpolar:
                            if len(slabs_nonpolar):
                                s_i = 0
                                n = 0
                                for sl_i in slabs_nonpolar:
                                    st = st_bulk
                                    sl = st.update_from_pymatgen(sl_i)
                                    if stoichiometry_criteria2(
                                            st, sl
                                    ) and sl_i.have_equivalent_surfaces(
                                    ) == True:

                                        # if sl.natom < 31:
                                        suf_name = str(surface[0]) + str(
                                            surface[1]) + str(
                                                surface[2]) + '.' + str(s_i)

                                        # if self.suf_nonpol_status == 'Zero slabs constructed':
                                        #     self.suf_nonpol_status = {}

                                        self.suf_nonpol[suf_name] = sl
                                        self.suf_nonpol_status[
                                            suf_name] = 'created'

                                        n += 1
                                    s_i += 1
                                print(st_name + ' Nonolar\n', surface, n,
                                      ' from ', len(slabs_nonpolar),
                                      ' slabs\n', sl.natom, ' atoms\n')

                            else:
                                suf_name = str(surface[0]) + str(
                                    surface[1]) + str(
                                        surface[2]) + '.' + str(0)

                                self.suf_nonpol_status[
                                    suf_name] = 'Zero slabs constructed'
                                print('\nWarning!  Zero slabs constructed!\n')

        except AttributeError:
            self.suf_pol_status = 'Bulk calculation has some problems'
            self.suf_nonpol_status = 'Bulk calculation has some problems'
            print('\nWarning!  Bulk calculation of {} has some problems!!\n'.
                  format(st_name))

    ##################### add slab calc

    if status == 'add':
        for suf_name in self.suf_pol_status.keys():
            if self.suf_pol_status[suf_name] != 'Zero slabs constructed':
                suffix = '.polar'

                if self.suf_pol_status[suf_name] in ['created']:
                    sl = self.suf_pol[suf_name]

                    if only_stoich:

                        if stoichiometry_criteria2(sl, st_bulk):
                            print(sl.rprimd)
                            ngkpt = calc_k_point_mesh(sl.rprimd, kspacing=0.2)
                            ngkpt = ngkpt[:2] + (1, )
                            add_loop(st_name + '.sl.' + suf_name + suffix,
                                     ise,
                                     1,
                                     ngkpt=ngkpt,
                                     input_st=sl,
                                     it_folder='slabs_new/' + st_name,
                                     up='up2',
                                     cluster=cluster,
                                     corenum=corenum)
                            self.suf_pol_status[suf_name] = 'added'
                            self.suf_pol_cl[suf_name] = '.'.join([
                                st_name + '.sl.' + suf_name + suffix, ise, '1'
                            ])

                        else:
                            print('Non-stoichiometric slab')

                    else:
                        None
                else:
                    print('\nThis slab hasn\'t been created yet!\n')
                    print(self.suf_pol_status[suf_name])

            print(self.suf_nonpol_status)
        for suf_name in self.suf_nonpol_status.keys():
            if self.suf_nonpol_status[suf_name] != 'Zero slabs constructed':
                suffix = '.nonpolar'

                if self.suf_nonpol_status[suf_name] in ['created']:
                    sl = self.suf_nonpol[suf_name]

                    if only_stoich:

                        if stoichiometry_criteria2(sl, st_bulk):
                            # print(st_name+'.sl.'+ suf_name, ise, 1, suf_name)
                            ngkpt = calc_k_point_mesh(sl.rprimd, kspacing=0.2)
                            ngkpt = ngkpt[:2] + (1, )
                            add_loop(st_name + '.sl.' + suf_name + suffix,
                                     ise,
                                     1,
                                     ngkpt=ngkpt,
                                     input_st=sl,
                                     it_folder='slabs_new/' + st_name,
                                     up='up2',
                                     cluster=cluster,
                                     corenum=corenum)
                            self.suf_nonpol_status[suf_name] = 'added'
                            self.suf_nonpol_cl[suf_name] = '.'.join([
                                st_name + '.sl.' + suf_name + suffix, ise, '1'
                            ])

                        else:
                            print('Non-stoichiometric slab')

                    else:
                        None
                else:
                    print('\nThis slab hasn\'t been created yet!\n')
                    print(self.suf_nonpol_status[suf_name])

    ##################### res slab calc

    if status == 'res':
        #     # print('1111')
        print(self.suf_pol.keys(), self.suf_pol_status)
        suffix = '.polar'
        for suf_name in self.suf_pol.keys():
            s_hkl = suf_name.split('.')[0]
            #         # print(s_hkl)
            key = []
            delta = 0
            for i in range(0, 3):
                i += delta
                if s_hkl[i] != '-':
                    key.append(int(s_hkl[i]))
                else:
                    key.append(-int(s_hkl[i + 1]))
                    delta = 1
            # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])]
            hkl = key
            if self.suf_pol_status[suf_name] in ['added', 'calculated'
                                                 ] and hkl in suf_list:

                try:
                    try:

                        res_loop(st_name + '.sl.' + suf_name + suffix,
                                 ise,
                                 1,
                                 up='up2')
                    except ValueError:
                        self.suf_pol_status[suf_name] = 'Error'
                        self.suf_en_pol[suf_name] = 'Error'
                        break
                except KeyError:
                    break

                self.suf_pol_status[suf_name] = 'calculated'

                from siman.analysis import suf_en

                try:
                    print(self.suf_pol_cl[suf_name])
                except KeyError:
                    self.suf_pol_cl[suf_name] = '.'.join(
                        [st_name + '.sl.' + suf_name, ise, '1'])

                try:
                    e = '-'
                    if db[self.suf_pol_cl[suf_name]]:  # in db.keys():
                        e = suf_en(db[self.suf_pol_cl[suf_name]],
                                   db[self.bulk_cl_scale])
                    # self.suf_en = {}
                    try:
                        self.suf_en_pol[suf_name] = round(float(e), 3)

                    except ValueError:
                        self.suf_en_pol[suf_name] = e
                except AttributeError:
                    self.suf_en_pol[suf_name] = 'Error'

        if self.suf_pol_status == 'Zero slabs constructed':
            self.suf_en_pol = 'Zero slabs constructed'

        print(self.suf_nonpol.keys(), self.suf_nonpol_status)
        suffix = '.nonpolar'
        for suf_name in self.suf_nonpol.keys():
            s_hkl = suf_name.split('.')[0]
            #         # print(s_hkl)
            key = []
            delta = 0
            for i in range(0, 3):
                i += delta
                if s_hkl[i] != '-':
                    key.append(int(s_hkl[i]))
                else:
                    key.append(-int(s_hkl[i + 1]))
                    delta = 1
            # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])]
            hkl = key
            if self.suf_nonpol_status[suf_name] in ['added', 'calculated'
                                                    ] and hkl in suf_list:

                try:
                    try:

                        res_loop(st_name + '.sl.' + suf_name + suffix,
                                 ise,
                                 1,
                                 up='up2')
                    except ValueError:
                        self.suf_nonpol_status[suf_name] = 'Error'
                        self.suf_en_nonpol[suf_name] = 'Error'
                        break
                except KeyError:
                    break

                self.suf_nonpol_status[suf_name] = 'calculated'

                from siman.analysis import suf_en

                try:
                    print(self.suf_nonpol_cl[suf_name])
                except KeyError:
                    self.suf_nonpol_cl[suf_name] = '.'.join(
                        [st_name + '.sl.' + suf_name, ise, '1'])

                try:
                    e = '-'
                    if db[self.suf_nonpol_cl[suf_name]]:  # in db.keys():
                        e = suf_en(db[self.suf_nonpol_cl[suf_name]],
                                   db[self.bulk_cl_scale])
                    # self.suf_en = {}
                    try:
                        self.suf_en_nonpol[suf_name] = round(float(e), 3)

                    except ValueError:
                        self.suf_en_nonpol[suf_name] = e

                except AttributeError:
                    self.suf_en_nonpol[suf_name] = 'Error'

        if self.suf_nonpol_status == 'Zero slabs constructed':
            self.suf_en_nonpol = 'Zero slabs constructed'
Пример #10
0
def calc_suf_mat(self,
                 ise='9sm',
                 bulk_cl_name=None,
                 it_folder='bulk/',
                 status='create',
                 suf_list=None,
                 min_slab_size=12,
                 only_stoich=1,
                 symmetrize=True,
                 corenum=4,
                 cluster='cee',
                 conv=1,
                 create=1,
                 reset_old=0,
                 suffix=None):
    '''
    '''
    from siman.header import db
    from siman.geo import create_surface2, stoichiometry_criteria, stoichiometry_criteria2
    from siman.calc_manage import add_loop, res_loop

    if not bulk_cl_name:
        bulk_cl_name = ['it', 'ise', '1']

    if not suf_list:
        suf_list = [[1, 1, 0], [1, 1, 1]]

    st_bulk = db[self.bulk_cl_scale].end

    if conv:
        st_bulk = st_bulk.get_conventional_cell()

    st_name = '.'.join(
        [self.pretty_formula, self.sg_crystal_str, self.sg_symbol])
    st_name = st_name.replace('/', '_')
    # st_bulk.printme()
    try:
        # print(self.suf)
        self.suf.keys()
    except AttributeError:
        self.suf = {}
        self.suf_status = {}

    try:
        self.suf_cl.keys()
    except AttributeError:
        self.suf_cl = {}

    try:
        self.suf_en.keys()
    except AttributeError:
        self.suf_en = {}

    if reset_old:
        self.suf = {}
        self.suf_status = {}
        self.suf_cl = {}
        self.suf_en = {}

    ##################### create slab
    if status == 'create':

        try:
            for surface in suf_list:
                print(surface)

                if self.suf == {} or ''.join(
                    [str(surface[0]),
                     str(surface[1]),
                     str(surface[2])]) not in self.suf.keys():

                    slabs = create_surface2(st_bulk,
                                            miller_index=surface,
                                            min_slab_size=min_slab_size,
                                            min_vacuum_size=15,
                                            surface_i=0,
                                            symmetrize=symmetrize,
                                            lll_reduce=1,
                                            primitive=1)
                    for sl_i in slabs:
                        st = st_bulk
                        sl = st.update_from_pymatgen(sl_i)
                        stoichiometry_criteria2(st, sl)
                    s_i = 0
                    if create:
                        if len(slabs):
                            for sl_i in slabs:
                                st = st_bulk
                                sl = st.update_from_pymatgen(sl_i)
                                stoichiometry_criteria2(st, sl)
                                suf_name = str(surface[0]) + str(
                                    surface[1]) + str(
                                        surface[2]) + '.' + str(s_i)

                                if self.suf_status == 'Zero slabs constructed':
                                    self.suf_status = {}

                                self.suf[suf_name] = sl
                                self.suf_status[suf_name] = 'created'
                                print(st_name + '\n', surface, s_i + 1,
                                      ' from ', len(slabs), ' slabs\n',
                                      sl.natom, ' atoms')

                                s_i += 1

                        else:
                            self.suf_status = 'Zero slabs constructed'
                            print('\nWarning!  Zero slabs constructed!\n')

        except AttributeError:
            self.suf_status = 'Bulk calculation has some problems'
            print('\nWarning!  Bulk calculation of {} has some problems!!\n'.
                  format(st_name))

    ##################### add slab calc

    if status == 'add':
        # for surface in suf_list:
        for suf_name in self.suf_status.keys():
            if self.suf_status[suf_name] in ['created']:
                sl = self.suf[suf_name]

                if only_stoich:

                    if stoichiometry_criteria2(sl, st_bulk):
                        # print(st_name+'.sl.'+ suf_name, ise, 1, suf_name)

                        add_loop(st_name + '.sl.' + suf_name + suffix,
                                 ise,
                                 1,
                                 input_st=sl,
                                 it_folder='slabs_new/' + st_name,
                                 up='up2',
                                 cluster=cluster,
                                 corenum=corenum)
                        self.suf_status[suf_name] = 'added'
                        self.suf_cl[suf_name] = '.'.join(
                            [st_name + '.sl.' + suf_name, ise, '1'])

                    else:
                        print('Non-stoichiometric slab')

                else:
                    None
            else:
                print('\nThis slab hasn\'t been created yet!\n')
                print(self.suf_status[suf_name])

    ##################### res slab calc

    if status == 'res':
        # print('1111')
        print(self.suf.keys(), self.suf_status)
        for suf_name in self.suf.keys():
            s_hkl = suf_name.split('.')[0]
            # print(s_hkl)
            key = []
            delta = 0
            for i in range(0, 3):
                i += delta
                if s_hkl[i] != '-':
                    key.append(int(s_hkl[i]))
                else:
                    key.append(-int(s_hkl[i + 1]))
                    delta = 1
            # hkl = [int(s_hkl[0]), int(s_hkl[1]), int(s_hkl[2])]
            hkl = key
            if self.suf_status[suf_name] in ['added', 'calculated'
                                             ] and hkl in suf_list:

                try:
                    try:
                        res_loop(st_name + '.sl.' + suf_name + suffix,
                                 ise,
                                 1,
                                 up='up2')
                    except ValueError:
                        self.suf_status[suf_name] = 'Error'
                        self.suf_en[suf_name] = 'Error'
                        break
                except KeyError:
                    break

                self.suf_status[suf_name] = 'calculated'

                from siman.analysis import suf_en

                try:
                    print(self.suf_cl[suf_name])
                except KeyError:
                    self.suf_cl[suf_name] = '.'.join(
                        [st_name + '.sl.' + suf_name, ise, '1'])

                try:
                    e = '-'
                    if self.suf_cl[suf_name] in db.keys():
                        e = suf_en(db[self.suf_cl[suf_name]],
                                   db[self.bulk_cl_scale])
                    # self.suf_en = {}
                    self.suf_en[suf_name] = e
                except AttributeError:
                    self.suf_en[suf_name] = 'Error'

        if self.suf_status == 'Zero slabs constructed':
            self.suf_en = 'Zero slabs constructed'

    return
Пример #11
0
def calc_suf_list_sg(data_list, sg, suf_list, flag=0):
    """
    to run a set of slabs for every str from matproj data_list
    sg - 'spacegroup.symbol'
    """

    # print('start')
    for i in data_list:

        if i['spacegroup.symbol'] == sg:
            print(i['spacegroup.symbol'])
            st_name = i['pretty_formula'] + '.' + i['spacegroup.crystal_system']
            print(st_name)

            if float(i['total_magnetization']):
                mag_flag = 1
                ise = '9sm'
                st_bulk = db[st_name, '8m', 1].end
            else:
                mag_flag = 0
                ise = '9s'
                st_bulk = db[st_name, '8', 1].end

            try:
                for surface in suf_list:
                    slabs = create_surface2(st_bulk,
                                            miller_index=surface,
                                            min_slab_size=10,
                                            min_vacuum_size=10,
                                            surface_i=0,
                                            symmetrize=True)

                    s_i = 0
                    if len(slabs):
                        for sl_i in slabs:
                            st = st_bulk
                            sl = st.update_from_pymatgen(sl_i)

                            if stoichiometry_criteria(sl, st_bulk):

                                if flag == 'add':
                                    add_loop(
                                        st_name + '.cubic.' +
                                        i['spacegroup.symbol'] + '.' +
                                        str(surface[0]) + str(surface[1]) +
                                        str(surface[2]) + '.' + str(s_i),
                                        ise,
                                        1,
                                        input_st=sl,
                                        it_folder='slab/' + st_name +
                                        '.cubic.' + i['spacegroup.symbol'],
                                        up='up2')
                                elif flag == 'res':
                                    res_loop(st_name + '.cubic.' +
                                             i['spacegroup.symbol'] + '.' +
                                             str(surface[0]) +
                                             str(surface[1]) +
                                             str(surface[2]) + '.' + str(s_i),
                                             ise,
                                             1,
                                             up='up2')
                                else:
                                    print(st_name + '\n', surface, s_i + 1,
                                          ' from ', len(slabs), ' slabs\n',
                                          sl.natom, ' atoms')
                                s_i += 1
                                if s_i == 3: break

                            else:
                                print('Non-stoichiometric slab')

                    else:
                        print('\nWarning!  Zero slabs constructed!\n')

            except AttributeError:
                print(
                    '\nWarning!  Bulk calculation of {} has some problems!!\n'.
                    format(st_name))