Beispiel #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)
Beispiel #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
Beispiel #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'])
Beispiel #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
Beispiel #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}
Beispiel #6
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
Beispiel #7
0
def add_neb(starting_calc=None,
            st=None,
            st_end=None,
            it_new=None,
            ise_new=None,
            i_atom_to_move=None,
            up='up2',
            search_type='vacancy_creation',
            images=None,
            r_impurity=None,
            calc_method=['neb'],
            inherit_option=None,
            mag_config=None,
            i_void_start=None,
            i_void_final=None,
            atom_to_insert=None,
            atom_to_move=None,
            rep_moving_atom=None,
            end_pos_types_z=None,
            replicate=None,
            it_new_folder=None,
            it_folder=None,
            inherit_magmom=False,
            x_start=None,
            xr_start=None,
            x_final=None,
            xr_final=None,
            upload_vts=False,
            center_on_moving=True,
            run=False,
            add_loop_dic=None,
            old_behaviour=None,
            params=None):
    """
    Prepare needed files for NEB
    Provides several regimes controlled by *search_type* flag:
        - existing_voids - search for voids around atom and use them as a final position 
        - vacancy_creation - search for neighbors of the same type and make a vacancy as a start position
        - interstitial_insertion - search for two neighboring voids; use them as start and final positions
                                    by inserting atom *atom_to_insert*
        - None - just use st and st2 as initial and final

    ###INPUT:
        - starting_calc (Calculation) - Calculation object with structure
        - st (Structure) - structure, can be used instead of Calculation
            - it_new (str) - name for calculation
        - st_end (Structure) - final structure

        - i_atom_to_move (int) - number of atom for moving starting from 0;
        - *mag_config* (int ) - choose magnetic configuration - allows to obtain different localizations of electron
        - *replicate* (tuple 3*int) - replicate cell along rprimd
        - i_void_start,  i_void_final (int) - position numbers of voids (or atoms) from the suggested lists
        - atom_to_insert  (str) - element name of atom to insert
        - atom_to_move (str) - element name of atom to move
        - it_new_folder or it_folder  (str) - section folder
        - inherit_option (str) - passed only to add_loop
        - inherit_magmom (bool) - if True than magmom from starting_calc is used, else from set

        - end_pos_types_z (list of int) - list of Z - type of atoms, which could be considered as final positions in vacancy creation mode

        - calc_method (list)
            - 'neb'
            - 'only_neb' - run only footer

        - x_start, x_final (array) - explicit xcart coordinates of moving atom for starting and final positions, combined with atom_to_insert
        - xr_start, xr_final (array) - explicit xred
        - rep_moving_atom (str)- replace moving atom by needed atom - can be useful than completly different atom is needed. 

        - upload_vts (bool) - if True upload Vasp.pm and nebmake.pl to server
        - run (bool)  - run on server

        - old_behaviour (str) - choose naming behavior before some date in the past for compatibility with your projects
            '020917'
            '261018' - after this moment new namig convention applied if end_pos_types_z is used

        - add_loop_dic - standart parameters of add()
        - params (dic) - provide additional parameters to add() # should be removed

    ###RETURN:
        None

    ###DEPENDS:

    ###TODO
    1. Take care of manually provided i_atom_to_move in case of replicate flag using init_numbers 
    2. For search_type == None x_m and x_del should be determined for magnetic searching and for saving their coordinates
    to struct_des; now their just (0,0,0) 


    """
    naming_conventions209 = True  # set False to reproduce old behavior before 2.09.2017
    if old_behaviour == '020917':
        naming_conventions209 = False  #

    # print('atom_to_insert', atom_to_insert)
    # sys.exit()

    calc = header.calc
    struct_des = header.struct_des
    varset = header.varset

    if not add_loop_dic:
        add_loop_dic = {}

    if not end_pos_types_z:
        end_pos_types_z = []
        end_pos_types_z = sorted(end_pos_types_z)

    if not hasattr(calc_method, '__iter__'):
        calc_method = [calc_method]

    if starting_calc and st:
        printlog(
            'Warning! both *starting_calc* and *st* are provided. I use *starting_calc*'
        )
        st = copy.deepcopy(starting_calc.end)

    elif starting_calc:
        st = copy.deepcopy(starting_calc.end)
        printlog('I use *starting_calc*')

    elif st:
        ''
        printlog('I use *st*')

    else:
        printlog(
            'Error! no input structure. Use either *starting_calc* or *st*')

    corenum = add_loop_dic.get('corenum')
    # print(corenum)
    # sys.exit()

    if corenum == None:
        if images == 3:
            corenum = 15
        elif images == 5:
            corenum = 15
        elif images == 7:
            corenum = 14
        else:
            printlog('add_neb(): Error! number of images', images,
                     'is unknown to me; please provide corenum!')

    # print(corenum)
    # sys.exit()

    # print(atom_to_insert)
    # sys.exit()

    if corenum:
        # header.corenum = corenum
        ''
    else:
        corenum = header.CORENUM

    if corenum % images > 0:
        print_and_log(
            'Error! Number of cores should be dividable by number of IMAGES',
            images, corenum)

    if not ise_new:
        ise_new = starting_calc.id[1]
        printlog('I use', ise_new, 'as ise_new', imp='y')

    name_suffix = ''
    st_pores = []

    name_suffix += 'n' + str(images)
    """Replicate cell """
    if replicate:
        print_and_log('You have chosen to replicate the structure by',
                      replicate)

        st = replic(st, mul=replicate)
        name_suffix += str(replicate[0]) + str(replicate[1]) + str(
            replicate[2])

    printlog('Search type is ', search_type)
    if search_type == None:

        if st_end == None:
            printlog(
                'Error! You have provided search_type == None, st_end should be provided!'
            )

        st1 = st
        st2 = st_end

        x_m = (0, 0, 0)
        x_del = (0, 0, 0)

    else:
        """1. Choose  atom (or insert) for moving """

        if is_list_like(xr_start):
            x_start = xred2xcart([xr_start], st.rprimd)[0]
            # print('atom_to_insert', atom_to_insert)
            # sys.exit()

            st1, i_m = st.add_atoms([x_start], atom_to_insert, return_ins=1)
            x_m = x_start
            # i_m = st1.find_atom_num_by_xcart(x_start)
            # print(st1.get_elements()[i_m])
            # sys.exit()

            if i_atom_to_move:
                nn = str(i_atom_to_move + 1)
            else:
                nn = str(i_void_start)

            name_suffix += atom_to_insert + nn
            write_xyz(st1, file_name=st.name + '_manually_start')
            printlog('Start position is created manually by adding xr_start',
                     xr_start, x_start)
            type_atom_to_move = atom_to_insert
            el_num_suffix = ''

        else:

            atoms_to_move = []
            atoms_to_move_types = []

            # print('d', i_atom_to_move)
            # sys.exit()

            if i_atom_to_move:
                typ = st.get_elements()[i_atom_to_move]
                printlog('add_neb(): atom', typ, 'will be moved', imp='y')
                atoms_to_move.append(
                    [i_atom_to_move, typ, st.xcart[i_atom_to_move]])
                atoms_to_move_types.append(typ)

                if naming_conventions209:
                    name_suffix += typ + str(i_atom_to_move + 1)

            else:
                #try to find automatically among alkali - special case for batteries
                for i, typ, x in zip(range(st.natom), st.get_elements(),
                                     st.xcart):
                    if typ in ['Li', 'Na', 'K', 'Rb', 'Mg']:
                        atoms_to_move.append([i, typ, x])
                        if typ not in atoms_to_move_types:
                            atoms_to_move_types.append(typ)

            if atoms_to_move:
                # print(atom_to_move)
                # sys.exit()
                if not atom_to_move:
                    atom_to_move = atoms_to_move_types[
                        0]  # taking first found element
                    if len(atoms_to_move_types) > 1:
                        printlog(
                            'Error! More than one type of atoms available for moving detected',
                            atoms_to_move_types,
                            'please specify needed atom with *atom_to_move*')

                type_atom_to_move = atom_to_move  #atoms_to_move[0][1]

                # printlog('atom ', type_atom_to_move, 'will be moved', imp ='y')

                if i_atom_to_move:
                    printlog('add_neb(): *i_atom_to_move* = ',
                             i_atom_to_move,
                             'is used',
                             imp='y')
                    numbers = [[i_atom_to_move]]
                    i_void_start = 1
                else:
                    printlog('add_neb(): determine_symmetry_positions ...',
                             imp='y')

                    numbers = determine_symmetry_positions(st, atom_to_move)

                # print(numbers)
                # sys.exit()
                if len(numbers) > 0:
                    printlog('Please choose position using *i_void_start* :',
                             [i + 1 for i in range(len(numbers))],
                             imp='y')
                    printlog('*i_void_start* = ', i_void_start)
                    i_m = numbers[i_void_start - 1][0]
                    printlog('Position',
                             i_void_start,
                             'chosen, atom:',
                             i_m + 1,
                             type_atom_to_move,
                             imp='y')

                else:
                    i_m = numbers[0][0]

                x_m = st.xcart[i_m]

                el_num_suffix = type_atom_to_move + str(i_m + 1)
                atom_to_insert = atom_to_move

                st1 = st
            # elif atom_to_replace:
            #     num = st.get_specific_elements(atom_to_replace)

            #     if len(n)>0:
            #         printlog('Please choose position using *i_void_start* :', [i+1 for i in range(len(num))],imp = 'y' )
            #         printlog('*i_void_start* = ', i_void_start)
            #         i_m = num[i_void_start-1]
            #         printlog('Position',i_void_start,'chosen, atom to replace:', i_m+1, atom_to_replace, imp = 'y' )
            #         sys.exit()

            else:

                print_and_log(
                    'No atoms to move found, you probably gave me deintercalated structure',
                    important='y')

                st_pores, sums, avds = determine_voids(st,
                                                       r_impurity,
                                                       step_dec=0.1,
                                                       fine=2)

                insert_positions = determine_unique_voids(st_pores, sums, avds)

                print_and_log(
                    'Please use *i_void_start* to choose the void for atom insertion from the Table above:',
                    end='\n',
                    imp='Y')

                if i_void_start == None:
                    sys.exit()
                if atom_to_insert == None:
                    printlog('Error! atom_to_insert = None')

                st = st.add_atoms([
                    insert_positions[i_void_start],
                ], atom_to_insert)

                name_suffix += 'i' + str(i_void_start)

                i_m = st.natom - 1
                x_m = st.xcart[i_m]

                search_type = 'existing_voids'
                type_atom_to_move = atom_to_insert
                el_num_suffix = ''

                st1 = st
        """2. Choose final position"""

        if is_list_like(xr_final):
            x_final = xred2xcart([xr_final], st.rprimd)[0]

            #old
            #check if i_atom_to_move should be removed
            # st2 = st1.del_atom(i_m)
            # st2 = st2.add_atoms([x_final], atom_to_insert)

            #new
            st2 = st1.mov_atoms(i_m, x_final)

            # st1.printme()
            # st2.printme()
            # sys.exit()

            x_del = x_final
            search_type = 'manual_insertion'
            name_suffix += 'v' + str(i_void_final)
            write_xyz(st2, file_name=st.name + '_manually_final')
            printlog('Final position is created manually by adding xr_final',
                     xr_final, x_del)

        elif search_type == 'existing_voids':
            #Search for voids around choosen atoms

            if not st_pores:
                st_pores, sums, avds = determine_voids(st, r_impurity)

            sur = determine_unique_final(st_pores, sums, avds, x_m)

            print_and_log('Please choose *i_void_final* from the Table above:',
                          end='\n',
                          imp='Y')

            if i_void_final == None:
                sys.exit()

            x_final = sur[0][i_void_final]  #

            printlog('You chose:',
                     np.array(x_final).round(2),
                     end='\n',
                     imp='Y')

            x_del = x_final  #please compare with vacancy creation mode

            write_xyz(st.add_atoms([x_final], 'H'),
                      replications=(2, 2, 2),
                      file_name=st.name + '_possible_positions2_replicated')

            print_and_log('Choosing the closest position as end',
                          important='n')

            st1 = st

            st2 = st.mov_atoms(i_m, x_final)

            name_suffix += el_num_suffix + 'e' + str(
                i_void_final) + atom_to_insert

            st1 = return_atoms_to_cell(st1)
            st2 = return_atoms_to_cell(st2)

            write_xyz(st1, file_name=st1.name + name_suffix + '_start')

            write_xyz(st2, file_name=st2.name + name_suffix + '_final')

        elif search_type == 'vacancy_creation':
            #Create vacancy by removing some neibouring atom of the same type

            print_and_log(
                'You have chosen vacancy_creation mode of add_neb tool',
                imp='Y')

            print_and_log('Type of atom to move = ',
                          type_atom_to_move,
                          imp='y')
            # print 'List of left atoms = ', np.array(st.leave_only(type_atom_to_move).xcart)

            final_pos_z = end_pos_types_z or [
                invert(type_atom_to_move)
            ]  # by default only moving atom is considered
            end_pos_types_el = [invert(z) for z in end_pos_types_z]

            sur = local_surrounding(x_m,
                                    st,
                                    n_neighbours=14,
                                    control='atoms',
                                    only_elements=final_pos_z,
                                    periodic=True)  #exclude the atom itself

            # print(x_m)
            # print(sur)

            # st.nn()
            end_pos_n = sur[2][1:]
            print_and_log(
                'I can suggest you ' + str(len(end_pos_n)) +
                ' end positions. The distances to them are : ',
                np.round(sur[3][1:], 2),
                ' A\n ',
                'They are ', [invert(z) for z in final_pos_z],
                'atoms, use *i_void_final* to choose required: 1, 2, 3 ..',
                imp='y')

            i_sym_final_l = []
            for j in end_pos_n:
                for i, l in enumerate(numbers):
                    if j in l:
                        i_sym_final_l.append(i + 1)
            printlog('Their symmetry positions are ', i_sym_final_l, imp='y')

            # sys.exit()

            if not i_void_final:
                printlog('Changing i_void_final: None -> 1', imp='y')
                i_void_final = 1  #since zero is itself
            chosen_dist = sur[3][i_void_final]
            print_and_log('Choosing position ',
                          i_void_final,
                          'with distance',
                          round(chosen_dist, 2),
                          'A',
                          imp='y')

            # print(end_pos_n)
            i_sym_final = 0
            n_final = sur[2][i_void_final]
            for i, l in enumerate(numbers):
                if n_final in l:
                    i_sym_final = i + 1
            printlog('It is symmetrically non-equiv position #',
                     i_sym_final,
                     imp='y')

            # sys.exit()

            header.temp_chosen_dist = chosen_dist

            if old_behaviour == '261018':
                name_suffix += el_num_suffix + 'v' + str(i_void_final)
            else:

                name_suffix += el_num_suffix + 'v' + str(
                    i_void_final) + list2string(end_pos_types_el, joiner='')

                # print(name_suffix)
                # sys.exit()

            x_del = sur[0][i_void_final]
            printlog('xcart of atom to delete', x_del)
            i_del = st.find_atom_num_by_xcart(x_del)
            # print(x_del)
            # print(st.xcart)
            # for x in st.xcart:
            #     if x[0] > 10:
            #         print(x)

            print_and_log('number of atom to delete = ', i_del, imp='y')
            if i_del == None:
                printlog('add_neb(): Error! I could find atom to delete!')

            # print st.magmom
            # print st1.magmom

            # try:
            if is_list_like(xr_start):
                st2 = st1.mov_atoms(
                    i_m, x_del)  # i_m and sur[0][neb_config] should coincide
                # i_del = st1.find_atom_num_by_xcart(x_del)

                st1 = st1.del_atom(i_del)

            else:
                print_and_log(
                    'Making vacancy at end position for starting configuration',
                    imp='y')
                st1 = st.del_atom(i_del)

                print_and_log(
                    'Making vacancy at start position for final configuration',
                    important='n')
                st2 = st.mov_atoms(
                    i_m, x_del)  # i_m and sur[0][neb_config] should coincide
            # except:
            # st2 = st

            st2 = st2.del_atom(i_del)  # these two steps provide the same order
    """Checking correctness of path"""
    #if start and final positions are used, collisions with existing atoms are possible
    if is_list_like(xr_start) and is_list_like(xr_final):
        printlog('Checking correctness')
        st1, _, _ = st1.remove_close_lying()

        stt = st1.add_atoms([
            x_final,
        ], 'Pu')
        stt, x, _ = stt.remove_close_lying(
            rm_both=True
        )  # now the final position is empty for sure; however the order can be spoiled
        # print(st._removed)
        if stt._removed:
            st1 = stt  # only if overlapping was found we assign new structure

        st2, _, _ = st2.remove_close_lying(rm_first=stt._removed)
        stt = st2.add_atoms([
            x_start,
        ], 'Pu')
        stt, x, _ = stt.remove_close_lying(
            rm_both=True)  # now the start position is empty for sure
        if stt._removed:
            st2 = stt

        print(st2.get_elements())
        # sys.exit()

    elif is_list_like(xr_final) and not is_list_like(xr_start) or is_list_like(
            xr_start) and not is_list_like(xr_final):
        printlog(
            'Attention! only start or final position is provided, please check that everything is ok with start and final states!!!'
        )
    """ Determining magnetic moments  """
    vp = varset[ise_new].vasp_params

    if 'ISPIN' in vp and vp['ISPIN'] == 2:
        print_and_log(
            'Magnetic calculation detected. Preparing spin modifications ...',
            imp='y')
        cl_test = CalculationVasp(varset[ise_new])
        cl_test.init = st1
        # print 'asdfsdfasdfsadfsadf', st1.magmom
        if inherit_magmom and hasattr(st, 'magmom') and st.magmom and any(
                st.magmom):
            print_and_log(
                'inherit_magmom=True: You have chosen MAGMOM from provided structure',
                imp='y')
            name_suffix += 'mp'  #Magmom from Previous
        else:
            cl_test.init.magmom = None
            print_and_log(
                'inherit_magmom=False or no magmom in input structure : MAGMOM will be determined  from set',
                imp='y')
            name_suffix += 'ms'  #Magmom from Set

        cl_test.actualize_set()  #find magmom for current structure

        st1.magmom = copy.deepcopy(cl_test.init.magmom)
        st2.magmom = copy.deepcopy(cl_test.init.magmom)

        # sys.exit()
        # print_and_log('The magnetic moments from set:')
        # print cl_test.init.magmom
        if search_type != None:  # for None not implemented; x_m should be determined first for this
            #checking for closest atoms now only for Fe, Mn, Ni, Co
            sur = local_surrounding(x_m,
                                    st1,
                                    n_neighbours=3,
                                    control='atoms',
                                    periodic=True,
                                    only_elements=header.TRANSITION_ELEMENTS)

            dist = np.array(sur[3]).round(2)
            numb = np.array(sur[2])
            a = zip(numb, dist)

            # a=  np.array(a)
            # print a[1]
            # a = np.apply_along_axis(np.unique, 1, a)
            # print a
            def unique_by_key(elements, key=None):
                if key is None:
                    # no key: the whole element must be unique
                    key = lambda e: e
                return list({key(el): el for el in elements}.values())

            # print a
            mag_atoms_dists = unique_by_key(a, key=itemgetter(1))
            # print (mag_atoms_dists)
            # a = unique_by_key(a, key=itemgetter(1))
            print_and_log(
                'I change spin for the following atoms:\ni atom     dist\n',
                np.round(mag_atoms_dists, 2),
                imp='y')
            # print 'I have found closest Fe atoms'
            muls = [(1.2, 0.6), (0.6, 1.2)]
            mag_moments_variants = []
            for mm in muls:
                mags = copy.deepcopy(cl_test.init.magmom)
                # print mags
                for a, m in zip(mag_atoms_dists, mm):
                    # print t[1]
                    mags[a[0]] = mags[a[0]] * m
                mag_moments_variants.append(mags)

            print_and_log('The list of possible mag_moments:', imp='y')
            for i, mag in enumerate(mag_moments_variants):
                print_and_log(i, mag)

            print_and_log(
                'Please use *mag_config* arg to choose desired config',
                imp='y')

        if mag_config != None:

            st1.magmom = copy.deepcopy(mag_moments_variants[mag_config])
            st2.magmom = copy.deepcopy(mag_moments_variants[mag_config])

            name_suffix += 'm' + str(mag_config)

            print_and_log('You have chosen mag configuration #',
                          mag_config,
                          imp='y')

    else:
        print_and_log('Non-magnetic calculation continue ...')
    """3. Add to struct_des, create geo files, check set, add_loop """

    if starting_calc:
        it = starting_calc.id[0]
        it_new = it + 'v' + str(starting_calc.id[2]) + '.' + name_suffix

        if not it_new_folder:
            it_new_folder = struct_des[it].sfolder + '/neb/'
        obtained_from = str(starting_calc.id)

        if not ise_new:
            print_and_log('I will run add_loop() using the same set',
                          important='Y')
            ise_new = cl.id[1]

    elif st:
        if not it_new:
            printlog(
                'Error! please provide *it_new* - name for your calculation',
                important='Y')

        it = None
        it_new += '.' + name_suffix
        obtained_from = st.name

        if not ise_new:
            printlog('Error! please provide *ise_new*', important='Y')

        if not it_new_folder and not it_folder:

            printlog(
                'Error! please provide *it_new_folder* - folder for your new calculation',
                important='Y')
        if it_folder:
            it_new_folder = it_folder

    if rep_moving_atom:
        it_new += 'r' + rep_moving_atom

    if it_new not in struct_des:
        add_des(struct_des, it_new, it_new_folder,
                'Automatically created and added from ' + obtained_from)

    print_and_log(
        'Creating geo files for starting and final configurations (versions 1 and 2) ',
        important='y')

    # if starting_calc:
    #     cl = copy.deepcopy(starting_calc)
    # else:

    cl = CalculationVasp()

    #write start position
    if search_type is not None:
        struct_des[it_new].x_m_ion_start = x_m
        struct_des[it_new].xr_m_ion_start = xcart2xred([x_m], st1.rprimd)[0]

        # st1, _, _ = st1.remove_close_lying()
        # st2, _, _ = st2.remove_close_lying()
        print('Trying to find x_m', x_m)
        i1 = st1.find_atom_num_by_xcart(
            x_m,
            prec=0.45,
        )

        # sys.exit()
        print('Trying to find x_del', x_del)

        i2 = st2.find_atom_num_by_xcart(
            x_del,
            prec=0.45,
        )

        if rep_moving_atom:  #replace the moving atom by required
            st1 = st1.replace_atoms([i1], rep_moving_atom)
            st2 = st2.replace_atoms([i2], rep_moving_atom)
        else:
            #allows to make correct order for nebmake.pl
            st1 = st1.replace_atoms([i1], type_atom_to_move)
            st2 = st2.replace_atoms([i2], type_atom_to_move)

        i1 = st1.find_atom_num_by_xcart(
            x_m,
            prec=0.45)  # the positions were changed # check if this is correct
        i2 = st2.find_atom_num_by_xcart(x_del, prec=0.45)

    cl.end = st1
    ver_new = 1
    cl.version = ver_new
    cl.path["input_geo"] = header.geo_folder + struct_des[it_new].sfolder + '/' + \
        it_new+"/"+it_new+'.auto_created_starting_position_for_neb_'+str(search_type)+'.'+str(ver_new)+'.'+'geo'

    cl.write_siman_geo(geotype='end',
                       description='Starting conf. for neb from ' +
                       obtained_from,
                       override=True)

    #write final position

    struct_des[it_new].x_m_ion_final = x_del
    struct_des[it_new].xr_m_ion_final = xcart2xred([x_del], st2.rprimd)[0]

    cl.end = st2
    ver_new = 2
    cl.version = ver_new
    cl.path["input_geo"] = header.geo_folder + struct_des[it_new].sfolder + '/' + \
        it_new+"/"+it_new+'.auto_created_final_position_for_neb_'+str(search_type)+'.'+str(ver_new)+'.'+'geo'

    cl.write_siman_geo(geotype='end',
                       description='Final conf. for neb from ' + obtained_from,
                       override=True)

    if not rep_moving_atom and search_type is not None:
        st1s = st1.replace_atoms([i1], 'Pu')
        st2s = st2.replace_atoms([i2], 'Pu')
    else:
        st1s = copy.deepcopy(st1)
        st2s = copy.deepcopy(st2)

    if center_on_moving and search_type is not None:

        vec = st1.center_on(i1)
        st1s = st1s.shift_atoms(vec)
        st2s = st2s.shift_atoms(vec)
        write_xyz(st1s, file_name=it_new + '_start')
        write_xyz(st2s, file_name=it_new + '_end')

    st1s.write_poscar('xyz/POSCAR1')
    st2s.write_poscar('xyz/POSCAR2')
    # print(a)
    # runBash('cd xyz; mkdir '+it_new+'_all;'+"""for i in {00..04}; do cp $i/POSCAR """+ it_new+'_all/POSCAR$i; done; rm -r 00 01 02 03 04')

    with cd('xyz'):
        a = runBash(header.PATH2NEBMAKE + ' POSCAR1 POSCAR2 3')
        print(a)
        dst = it_new + '_all'
        makedir(dst + '/any')
        for f in ['00', '01', '02', '03', '04']:
            shutil.move(f + '/POSCAR', dst + '/POSCAR' + f)
            shutil.rmtree(f)

    #prepare calculations
    # sys.exit()

    #Check if nebmake is avail
    # if int(runBash('ssh '+cluster_address+' test -e '+project_path_cluster+'/tools/vts/nebmake.pl; echo $?') ):

    #     ''
    #     print_and_log('Please upload vtsttools to ',cluster_address, project_path_cluster+'/tools/vts/')
    #     raise RuntimeError

    #     copy_to_server(path_to_wrapper+'/vtstscripts/nebmake.pl', to = project_path_cluster+'/tools/',  addr = cluster_address)
    # if  int(runBash('ssh '+cluster_address+' test -e '+project_path_cluster+'/tools/Vasp.pm; echo $?') ):
    #     copy_to_server(path_to_wrapper+'/vtstscripts/Vasp.pm', to = project_path_cluster+'/tools/',  addr = cluster_address)

    inherit_ngkpt(it_new, it, varset[ise_new])

    if run:
        add_loop_dic['run'] = run

    add_loop_dic['corenum'] = corenum
    # print(add_loop_dic)
    add_loop(
        it_new,
        ise_new,
        verlist=[1, 2],
        up=up,
        calc_method=calc_method,
        savefile='oc',
        inherit_option=inherit_option,
        n_neb_images=images,
        # params=params,
        **add_loop_dic)

    if upload_vts:
        siman_dir = os.path.dirname(__file__)
        # print(upload_vts)
        push_to_server([
            siman_dir + '/cluster_tools/nebmake.pl',
            siman_dir + '/cluster_tools/Vasp.pm'
        ],
                       to=header.cluster_home + '/tools/vts',
                       addr=header.cluster_address)

    else:
        print_and_log('Please be sure that vtsttools are at',
                      header.cluster_address,
                      header.cluster_home + '/tools/vts/',
                      imp='Y')

    printlog('add_neb finished')
    return it_new
Beispiel #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
Beispiel #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'
Beispiel #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
Beispiel #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))