Example #1
0
def chgsum(cll, el, site, silent = 1):
    """
    calculate sum of Bader charges for particular atoms
    """


    for cl in cll:
        # print(cl.id, end = '  ')

        try:
            cl.chgsum[(el, site)] = 0
        except:
            pass
        if not hasattr(cl, 'charges') or len(cl.charges) == 0:
            cl.get_bader_ACF()
        # determine_symmetry_positions(cl.end, el, silent = 0)

    # print('')
    try:
        pos = determine_symmetry_positions(cll[0].end, el, silent = 1)
    except:
        printlog('chgsum() Warning!', cll[0].id, 'is broken!')
        return 0

    for p in pos[site]:
        ''
        for cl in cll:
            if not hasattr(cl, 'chgsum'):
                cl.chgsum = {}
                cl.chgsum[(el, site)] = 0

            cl.chgsum[(el, site)] += cl.charges[p]
        
            # print('{:5.3f}'.format(cl.charges[p]), end = '  ')
        # print('')
    if not silent:
        print('Sum of charges for ', el+str(site+1), ':')
    

    el_ind = cl.init.znucl.index(invert(el)) # index of element in znucl and zval and nznucl
    zval = cl.init.zval[el_ind] # number of electrons in chosen potential

    for cl in cll:
        cl.chgsum[(el, site)]/=len(pos[site])
        
        chgsum = zval - cl.chgsum[(el, site)]



        if cl == cll[0]:
            chgsum_ref = chgsum
        if not silent:

            print('{:5.2f}({:4.2f})'.format(chgsum, chgsum_ref-chgsum), end = '  ')
    if not silent:
        print('\n')

    # print(cl.charges)
    return chgsum
Example #2
0
def form_en(sources, products, norm_el = None):
    """
    Calculate formation energy of reaction
    sources, products - list of tuples (x, cl), where x is multiplier and cl is calculation
    norm_el  - which element to use for normalization
        'all' - normalize by total number of atoms

    """

    El = []
    Nzl = []


    for ls in [sources, products]:
        E = 0
        Nz = {}
        for x, cl in ls:
            E += x*cl.e0 
            for i, z in enumerate(cl.end.znucl):
                if z not in Nz:
                    Nz[z] = 0
                Nz[z] += x*cl.end.nznucl[i]
        El.append(E)
        Nzl.append(Nz)

    for z in Nzl[0]:
        if abs(Nzl[0][z] - Nzl[1][z]) > 1e-5:
            printlog('Error! Number of', invert(z), 'atoms in source and product are different!')

    # norm = 1
    if 'all' == norm_el:
        norm = sum(Nzl[0].values())
    elif type(norm_el) == str:
        norm = Nzl[0][invert(norm_el)]
    elif norm_el != None:
        norm = norm_el
    else:
        norm = 1
    # print('Normalizing by ', norm_el, norm, 'atoms')


    print('dE = {:4.2f} eV'.format((El[1]-El[0])/norm))
Example #3
0
    def set_potential(self,znucl, arg = ''):
        # print arg
        
        if not arg:
            arg = header.PATH2POTENTIALS+'/'+invert(znucl)
            printlog('Attention!, Default potentials is chosen from ',header.PATH2POTENTIALS, 'for',invert(znucl) , imp ='Y')

        if type(arg) not in (str,):
            # sys.exit("\nset_potential error\n")
            raise RuntimeError



        if znucl in self.potdir:
            if arg == self.potdir[znucl]:
                print_and_log( "Warning! You already have the same potential for "+str(znucl)+" element\n" )
        # print type(self.potdir)
        self.potdir[znucl] = arg
        self.history += "Potential for "+str(znucl)+" was changed to "+arg+"\n"
        print_and_log( "Potential for "+str(znucl)+" was changed to "+arg+"\n" )

        # self.update()
        return
else:
    cases = case_raw.keys()

if vectors == 'Binary':
    # Take log base 2 to figure out how many bits we need for each
    human_size = int(ceil(log(len(human), 2))) # 2
    dec_size = int(ceil(log(len(declensions), 2))) # 3
    gen_size = int(ceil(log(len(genders), 2))) # 2
    case_size = int(ceil(log(len(cases), 2))) # 3
    if casenum_sep == True:
        num_size = int(ceil(log(len(numbers), 2))) # 1

    # Now make two way dictionary with bit vectors
    human_dict = functions.binaryDict(human)
    dec_dict = functions.binaryDict(declensions)
    dec_dict.update(functions.invert(dec_dict))
    gen_dict = functions.binaryDict(genders)
    gen_dict.update(functions.invert(gen_dict))
    case_dict = functions.binaryDict(cases)
    case_dict.update(functions.invert(case_dict))
    if casenum_sep == True:
        num_dict = functions.binaryDict(numbers)
        num_dict.update(functions.invert(num_dict))
# Identity vectors
else:
    human_size = len(human)
    dec_size = len(declensions)
    gen_size = len(genders)
    case_size = len(cases)
    if casenum_sep == True:
        num_size = len(numbers)
Example #5
0
else:
    cases = case_raw.keys()

if vectors == 'Binary':
    # Take log base 2 to figure out how many bits we need for each
    human_size = int(ceil(log(len(human), 2)))  # 2
    dec_size = int(ceil(log(len(declensions), 2)))  # 3
    gen_size = int(ceil(log(len(genders), 2)))  # 2
    case_size = int(ceil(log(len(cases), 2)))  # 3
    if casenum_sep == True:
        num_size = int(ceil(log(len(numbers), 2)))  # 1

    # Now make two way dictionary with bit vectors
    human_dict = functions.binaryDict(human)
    dec_dict = functions.binaryDict(declensions)
    dec_dict.update(functions.invert(dec_dict))
    gen_dict = functions.binaryDict(genders)
    gen_dict.update(functions.invert(gen_dict))
    case_dict = functions.binaryDict(cases)
    case_dict.update(functions.invert(case_dict))
    if casenum_sep == True:
        num_dict = functions.binaryDict(numbers)
        num_dict.update(functions.invert(num_dict))
# Identity vectors
else:
    human_size = len(human)
    dec_size = len(declensions)
    gen_size = len(genders)
    case_size = len(cases)
    if casenum_sep == True:
        num_size = len(numbers)
Example #6
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,
    corenum=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,
    inherit_magmom=False,
    x_start=None,
    xr_start=None,
    x_final=None,
    xr_final=None,
    upload_vts=False,
    run=False,
    add_loop_dic=None,
    old_behaviour=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  (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

    ###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) 


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

    # print(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 = []

    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*')

    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(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]
            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)

            sur = local_surrounding(x_m,
                                    st,
                                    n_neighbours=12,
                                    control='atoms',
                                    only_elements=[invert(type_atom_to_move)] +
                                    end_pos_types_z,
                                    periodic=True)  #exclude the atom itself

            # print(x_m)
            # print(sur)

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

            if not i_void_final:
                i_void_final = 1  #since zero is itself

            print_and_log('Choosing position ',
                          i_void_final,
                          'with distance',
                          round(sur[3][i_void_final], 2),
                          'A',
                          imp='y')

            name_suffix += el_num_suffix + 'v' + str(i_void_final)

            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 of 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 search_type != None:  #for None not implemented; x_m should be determined first for this

        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

            #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:
            printlog(
                'Error! please provide *it_new_folder* - folder for your new calculation',
                important='Y')

    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

    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()
    i1 = st1.find_atom_num_by_xcart(x_m, prec=0.3)
    i2 = st2.find_atom_num_by_xcart(x_del, prec=0.3)

    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.3)  # the positions were changed
    i2 = st2.find_atom_num_by_xcart(x_del, prec=0.3)

    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:
        st1s = st1.replace_atoms([i1], 'Pu')
        st2s = st2.replace_atoms([i2], 'Pu')
    else:
        st1s = copy.deepcopy(st1)
        st2s = copy.deepcopy(st2)

    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')

        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])

    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,
             corenum=corenum,
             run=run,
             **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
Example #7
0
########

# Read in corpus
(corpus, suffixes) = objects.readCorpus(constants.corpus_file)
# Determine corpus size from this
corpus_size = len(corpus)

# Create suffix dictionary
if constants.vectors == 'binary':
    suffix_size = int(ceil(log(len(suffixes), 2)))  # 6
    suffix_dict = functions.binaryDict(suffixes)
else:
    suffix_size = len(suffixes)
    suffix_dict = dict(zip(suffixes, map(tuple, identity(suffix_size))))

suf_to_tup = functions.invert(suffix_dict)
suffix_dict.update(functions.invert(suffix_dict))

##########
# OUTPUT #
##########

# Output layer will be list of potential suffixes, gathered from corpus
output_nodes = suffix_size

# Print information
print '''Training on %d Epochs
        Number of Input Nodes: %d
        Number of Hidden Nodes: %d
        Number of Output Nodes: %d
        Token Frequency taken into account: %s\n''' % (
# Determine corpus size from this
corpus_size = len(corpus)

root_size = int(ceil(log(corpus_size, 2)))

# Create suffix dictionary
suf_dict = {}
for suffix in suffixes:
    phon_suf = functions.reworkSuffix(suffix)
    feat_suf = ()
    for phoneme in ''.join(phon_suf):
        feat_suf += constants.phon_to_feat[phoneme]
    suf_dict[suffix] = feat_suf

inv_suf = functions.invert(suf_dict)

# TOTAL input bits
#       If binary and casenum separate: 9 + 2 + 3 + 2 + 3 + 1 = 20
#       If binary and casenum together: 9 + 2 + 3 + 2 + 4 = 20
#       If identity and casenum separate: 9 + 3 + 5 + 3 + 5 + 2 = 27
#       If identity and casenum together: 9 + 3 + 5 + 3 + 10 = 30
input_nodes = sum([root_size, constants.human_size, constants.dec_size, constants.gen_size, constants.case_size])
if constants.casenum_sep == True:
        input_nodes += constants.num_size

##########
# OUTPUT #
##########

# # Output layer will be list of potential suffixes, gathered from corpus
########

# Read in corpus
(corpus, suffixes) = objects.readCorpus(constants.corpus_file)
# Determine corpus size from this
corpus_size = len(corpus)

# Create suffix dictionary
if constants.vectors == 'binary':
        suffix_size = int(ceil(log(len(suffixes), 2)))          # 6
        suffix_dict = functions.binaryDict(suffixes)
else:
        suffix_size = len(suffixes)
        suffix_dict = dict(zip(suffixes, map(tuple, identity(suffix_size))))

suf_to_tup = functions.invert(suffix_dict)
suffix_dict.update(functions.invert(suffix_dict))

##########
# OUTPUT #
##########

# Output layer will be list of potential suffixes, gathered from corpus
output_nodes = suffix_size

# Print information
print '''Training on %d Epochs
        Number of Input Nodes: %d
        Number of Hidden Nodes: %d
        Number of Output Nodes: %d
        Token Frequency taken into account: %s\n''' % ( 
Example #10
0
# Determine corpus size from this
corpus_size = len(corpus)

root_size = int(ceil(log(corpus_size, 2)))

# Create suffix dictionary
suf_dict = {}
for suffix in suffixes:
    phon_suf = functions.reworkSuffix(suffix)
    feat_suf = ()
    for phoneme in ''.join(phon_suf):
        feat_suf += constants.phon_to_feat[phoneme]
    suf_dict[suffix] = feat_suf

inv_suf = functions.invert(suf_dict)

# TOTAL input bits
#       If binary and casenum separate: 9 + 2 + 3 + 2 + 3 + 1 = 20
#       If binary and casenum together: 9 + 2 + 3 + 2 + 4 = 20
#       If identity and casenum separate: 9 + 3 + 5 + 3 + 5 + 2 = 27
#       If identity and casenum together: 9 + 3 + 5 + 3 + 10 = 30
input_nodes = sum([
    root_size, constants.human_size, constants.dec_size, constants.gen_size,
    constants.case_size
])
if constants.casenum_sep == True:
    input_nodes += constants.num_size

##########
# OUTPUT #
Example #11
0
def find_polaron(st, i_alk_ion, out_prec = 1):
    """
    #using magmom, find the transition atoms that have different magnetic moments
    #i_alk_ion - number of ion from 0 to calculate distances to transition metals
    out_prec (int) - precision of magmom output


    # maglist = cli.end.get_maglist()
    # magm = np.array(cli.end.magmom)

    # n_tm = len(magm[maglist])
    # # print(len(maglist))
    # numb, dist, chosen_ion = around_alkali(cli.end, n_tm, atom_num)
    # # print(magm[numb][1:]) 
    # mtm = magm[numb][1:] # the first is alkali

    # m_av = sum(mtm)/len(mtm)
    # print(mtm-m_av)
    """


    def zscore(s):
        # print(np.std(s))
        return (s - np.mean(s)) / np.std(s)



    magmom = np.array(st.magmom)
    if len(magmom) == 0 :
        printlog('Error! magmom is empty')

    _, mag_numbers = st.get_maglist()

    pol = {}
    # for z in mag_numbers:
    #     pos = determine_symmetry_positions(st, invert(z))


    # sys.exit()
    magmom_tm = None
    for key in mag_numbers:
        printlog('Looking at polarons on transition atoms: ',invert(key) )
        numbs = np.array(mag_numbers[key])
        # print(numbs)
        # print(magmom)
        magmom_tm = magmom[numbs]
        dev = np.absolute(  zscore(magmom_tm) )
        # print(magmom_tm)
        # print(list(zip(magmom_tm, dev.round(1))))
        # p = np.where(dev>2)[0] # 2 standard deviations
        # print(dev>2)
        # print (type(numbs))
        nstd = 1.5
        # nstd = 4
        i_pols = numbs[dev>nstd]

        if len(i_pols) > 0:
            x1 = st.xcart[i_alk_ion]
            d_to_pols = []
            for j in i_pols:
                x2 = st.xcart[j]
                d, _ = st.image_distance(x1, x2, st.rprimd)
                d_to_pols.append(d)
            print('polarons are detected on atoms', [i+1 for i in i_pols], 'with magnetic moments:', magmom[i_pols], 'and distances: '+', '.join('{:2.2f}'.format(d) for d in d_to_pols), 'A'  )
            print('mag moments on trans. atoms:', magmom_tm.round(out_prec))
            
            pol[key] = i_pols
        else:
            print('no polarons is detected with nstd', nstd)
            print('mag moments on trans. atoms:', magmom_tm.round(out_prec))
            # print(' deviations                :', dev.round(1))
            pol[key] = None
    return pol, magmom_tm
Example #12
0
def add_to_archive_database(cl, subgroup):
    """
    cl is Calculation which should be added to database
    subgroup (str) - subgroup folder

    """

    from pymatgen.core.composition import Composition
    from pymatgen.io.cif import CifWriter
    from pymatgen.symmetry.analyzer import SpacegroupAnalyzer

    join = os.path.join
    basename = os.path.basename
    dirname = os.path.dirname

    save_format = 'azh'
    dbpath = header.PATH2DATABASE
    it = cl.id[0]

    # print(cl.path)
    sub_folder = cl.path['output'].split('/')[
        0]  # usually basic chemical formula
    # sub_folder = header.struct_des[it].sfolder.split('/')[0] # usually basic chemical formula

    print('Processing ', cl.id)
    cl.read_results()

    if '4' not in cl.state:
        return
    st = cl.end

    # print(cl.end.typat)
    # sys.exit()

    if 1:
        #determine x
        #universal method, supports several alkali elements
        #requires cl.base_formula in 'Na2FePO4F' format
        #requires pymatgen, would be nice to remove dependency
        cmb = Composition(cl.base_formula)
        cm = st.get_pm_composition()

        rc = cl.end.get_reduced_composition().as_dict(
        )  #reduced composition dict
        rcb = cmb.reduced_composition.as_dict()

        # print(rc, rcb)

        alk = list(set(st.get_specific_elements(
            header.ALKALI_ION_ELEMENTS)))  # list of unique alkali elements
        tra = list(set(st.get_specific_elements(header.TRANSITION_ELEMENTS)))
        # print(alk, tra)
        el_for_norm = tra[0]  #first element used for normalization

        nnb = rcb[el_for_norm]  #number of norm elements in base
        nn = rc[el_for_norm]  #number of norm elements in interesting structure
        # print(nb, n)
        mul = nn / nnb  # multiplier that garanties normalization

        # print(rcb)
        nab = sum([
            rcb[invert(z)] for z in header.ALKALI_ION_ELEMENTS
            if invert(z) in rcb
        ])

        na = sum([rc[el] for el in alk])
        x = na / mul / nab

        # determine formula
        # cm = st.get_pm_composition() #get pymatgen composition class
        # print( (cm/4).formula)

        # print('Material detected:', formula, 'sub_folder:', sub_folder)

        #obtain base without alk
        formula = (cm.reduced_composition / mul).formula
        # formula = formula.replace('1 ', '').replace(' ', '')
        # print(formula)
        cl.formula = formula
        # print(Composition('Na0.75'))
        print('Material detected:', formula, 'sub_folder:', sub_folder)

        # sys.exit()

    if 0:
        #Old method, not robust at all!
        #determine x for alkali ion from structure name
        parsed = re.findall(r'([A-Z][a-z]*)(\d*)', formula)
        parsed = [(el, x if x else '1') for (el, x) in parsed]
        print(parsed)
        print('detected element is ', parsed[0][0])

        if parsed[0][0] in [invert(z) for z in header.ALKALI_ION_ELEMENTS]:
            x = parsed[0][0]

            if hasattr(cl, 'max_alk_ion_content'):
                x = float(x) / cl.max_alk_ion_content
            else:
                x = '1'

        else:
            x = '0'

    sfolder = os.path.join(dbpath, sub_folder)

    name = []

    if 'azh' in save_format:
        #1. Single point calculation of total energy
        # print(sfolder)
        makedir(join(sfolder, 'dummy'))

        if x < 1:
            x = int(round(100 * x, 0))
        else:
            x = int(round(x, 0))

        print('Concentration x:', x)

        name.append('x' + str(x))
        # sys.exit()

        # if formula in ['LiCoO2', 'LiTiO2', 'LiFePO4', 'NaFePO4', 'LiMnPO4',
        # 'LiNiO2', 'LiTiS2', 'LiMn2O4', 'LiVP2O7', 'LiVPO4F',
        # 'NaMnAsO4', 'Na2FePO4F', 'Na2FeVF7', 'KFeSO4F', 'NaLiCoPO4F', 'KVPO4F' ]:
        sfolder = join(sfolder, subgroup)
        makedir(join(sfolder, 'dummy'))

        cl.set.update()

        # print(cl.potcar_lines)
        potcar1_m = cl.potcar_lines[0][0]

        if '_' in potcar1_m:
            (pot, _) = potcar1_m.split('_')
        else:
            pot = potcar1_m

        xc = cl.xc_inc
        if '-' in xc:
            xc = cl.xc_pot

        if xc == 'PE':
            func = 'PBE'
        elif xc == 'CA':
            func = 'LDA'
        elif xc == 'PS':
            func = 'PBEsol'
        else:
            print('uknown xc type:', xc)
            sys.exit()

        if cl.set.spin_polarized:
            func = 'U' + func  #unrestricted

        u_ramping_flag = False
        if hasattr(cl.set, 'u_ramping_nstep') and cl.set.u_ramping_nstep:
            func += '-UR'
            u_ramping_flag = True

        elif cl.set.dftu:
            func += '-U'
        else:
            func += '-'

        func += pot.lower()
        ecut = str(round(cl.set.ecut))

        func += ecut
        # print(func)
        name.append(func)

        name.extend([it.replace('.', '_')] + [cl.id[1]] + [str(cl.id[2])])

        name_str = '_'.join(name)
        # print('_'.join(name) )

        # sys.exit()

        outcar_name = name_str + '.out'

        shutil.copyfile(cl.path["output"], join(sfolder, outcar_name))

        if u_ramping_flag:
            print(cl.associated_outcars)
            for i, u_outcar in enumerate(
                    cl.associated_outcars[:-1]
            ):  # except the last one, which was copied above
                u = u_outcar.split('.')[1]
                # print(u)
                path_to_outcar = join(dirname(cl.path["output"]), u_outcar)

                cl.read_results(load='o', choose_outcar=i + 1, only_load=1)

                shutil.copyfile(path_to_outcar,
                                join(sfolder, name_str + '_' + u + '.out'))

            # sys.exit()

        cl.end.write_xyz(path=sfolder, filename=name_str)

        pickle_file = cl.serialize(os.path.join(sfolder, 'bin', name_str))
        # cl

        #write input, problem with fitted version 100, which does not have input geometry, since they are created on cluster
        # makedir(sfolder+'input/dummy')
        # shutil.copyfile(cl.path["input_geo"], sfolder+'input/'+name_str+'.geo')

        st_mp = cl.end.convert2pymatgen()
        sg_before = st_mp.get_space_group_info()
        # from pymatgen.symmetry.finder import SymmetryFinder
        # sf = SymmetryFinder(st_mp_prim)
        symprec = 0.1
        sf = SpacegroupAnalyzer(st_mp, symprec=symprec)

        st_mp_prim = sf.find_primitive()
        # st_mp_prim = sf.get_primitive_standard_structure()
        # st_mp_prim = sf.get_conventional_standard_structure()

        # st_mp_conv = sf.get_conventional_standard_structure()
        # print(st_mp_conv)
        # print(st_mp_conv.lattice.matrix)
        # print(st_mp_prim)
        # print(st_mp_prim.lattice)

        sg_after = st_mp_prim.get_space_group_info()

        if sg_before[0] != sg_after[0]:
            printlog(
                'Attention! the space group was changed after primitive cell searching',
                sg_before, sg_after)
            printlog('I will save supercell in cif and reduce symprec to 0.01')
            st_mp_prim = st_mp
            symprec = 0.01

        if st_mp_prim:
            cif = CifWriter(st_mp_prim, symprec=symprec)
            cif_name = name_str + '.cif'
            cif.write_file(join(sfolder, cif_name))
            printlog('Writing cif', cif_name)

        if 0:
            #get multiplication matrix which allows to obtain the supercell from primitive cell.
            #however this matrix is not integer which is not convinient.
            print(st_mp.lattice.matrix.round(2))
            print(st_mp_prim.lattice.matrix.round(2))

            mul_matrix = np.dot(st_mp.lattice.matrix,
                                np.linalg.inv(st_mp_prim.lattice.matrix))

            print(mul_matrix.round(1))

            rprimd = np.dot(mul_matrix, st_mp_prim.lattice.matrix)

            print(rprimd.round(2))

        #write chg
        if 1:
            path_to_chg = cl.get_chg_file('CHGCAR')
            if path_to_chg:
                makedir(join(sfolder, 'bin', 'dummy'))
                printlog('path to chgcar', path_to_chg)
                gz = '.gz'
                if gz not in path_to_chg:
                    gz = ''
                shutil.copyfile(path_to_chg,
                                join(sfolder, 'bin', name_str + '.chg' + gz))

        #write dos
        if subgroup in ['dos', 'DOS']:
            DOSCAR = cl.get_file('DOSCAR', nametype='asoutcar')
            if DOSCAR:
                printlog('path to DOSCAR', DOSCAR)
                gz = '.gz'
                if gz not in path_to_chg:
                    gz = ''
                shutil.copyfile(DOSCAR,
                                join(sfolder, 'bin', name_str + '.dos' + gz))

        if subgroup in ['BAD']:  #bader
            cl.get_bader_ACF()
            acf = cl.get_file(basename(cl.path['acf']))
            # print(acf)
            # sys.exit()
            if acf:
                shutil.copyfile(acf, join(sfolder, 'bin', name_str + '.acf'))

        if subgroup in ['ph', 'PH']:  #bader
            # cl.get_bader_ACF()
            xml = cl.get_file('vasprun.xml', nametype='asoutcar')
            # print(acf)
            # sys.exit()
            if xml:
                shutil.copyfile(xml, join(sfolder, 'bin', name_str + '.xml'))

        #make dat
        #incars
        makedir(join(sfolder, 'dat', 'dummy'))
        incars = glob.glob(join(cl.dir, '*INCAR*'))
        # print(incars)
        for inc in incars:

            dest = join(sfolder, 'dat')
            # inc_name =
            if not os.path.exists(join(dest, basename(inc))):
                shutil.copy(inc, dest)

        #kpoints
        if it in header.struct_des:
            with open(join(sfolder, 'dat', 'kpoints_for_kspacings.json'),
                      'w',
                      newline='') as fp:
                json.dump(
                    header.struct_des[it].ngkpt_dict_for_kspacings,
                    fp,
                )
        else:
            printlog('Warning!, it not in struct_des:', it)
        # print(cl.set.toJSON())

        #prepare for neb
        # makedir(sfolder+'neb_'+name_str+'/dummy')

    return