예제 #1
0
파일: inout.py 프로젝트: dimonaks/simanaks
def write_occmatrix(occs, folder):
    #create OCCMATRIX

    makedir(folder)
    printlog('I create OCCMATRIX in ', folder, imp='y')
    filename = folder + '/OCCMATRIX'
    with open(filename, 'w', newline='') as f:
        numat = len(occs)
        f.write(str(numat) + '  #num of atoms to be specified\n')

        at_nums = occs.keys()
        at_spin = []  # # 2 or 1
        at_ltyp = []  # l - orbital type, 1 - s, 2 - d, 3 - f
        for key in occs:
            occ = occs[key]
            if len(occ) == 10:  # spin polarized, d orbital
                at_spin.append(2)
                at_ltyp.append(2)
            else:
                raise RuntimeError  # please write by yourself for other cases

        for i, l, s in zip(at_nums, at_spin, at_ltyp):

            f.write(list2string([i + 1, l, s]) + '    #i, l, s\n')
            # for sp in range(s):
            f.write('spin 1\n')
            for row in occs[i][0:len(occs[i]) // s]:
                f.write(list2string(row) + '\n')
            if s == 2:
                f.write('spin 2\n')
                for row in occs[i][len(occs[i]) // s:]:
                    f.write(list2string(row) + '\n')
            f.write('\n')
    return filename
예제 #2
0
def process_fig_filename(image_name, fig_format):

    makedir(image_name)

    if fig_format in image_name:
        path2saved = str(image_name)

    elif str(image_name).split('.')[-1] in ['eps', 'png', 'pdf']:
        path2saved = str(image_name)
        fig_format = str(image_name).split('.')[-1]

    else:
        path2saved = str(image_name) + '.' + fig_format

    dirname = os.path.dirname(image_name)
    if not dirname:
        dirname += '.'

    path2saved_png = dirname + '/png/' + os.path.basename(image_name) + '.png'
    makedir(path2saved_png)

    return path2saved, path2saved_png
예제 #3
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
예제 #4
0
    def fit_and_plot(x1,
                     y1,
                     x2,
                     y2,
                     power,
                     name="",
                     xlabel="",
                     ylabel="",
                     image_name="test",
                     lines=None):
        """Should be used in two below sections!
        Creates one plot with two dependecies and fit them;
        return minimum fitted value of x2 and corresponding valume of y2; 
        if name == "" image will not be plotted
        power - the power of polynom

        lines - add lines at x = 0 and y = 0

        """
        coeffs1 = np.polyfit(x1, y1, power)
        coeffs2 = np.polyfit(x2, y2, power)

        fit_func1 = np.poly1d(coeffs1)
        fit_func2 = np.poly1d(coeffs2)

        #x_min  = fit_func2.deriv().r[power-2] #derivative of function and the second cooffecient is minimum value of x.
        #y_min  = fit_func2(x_min)

        if name:

            x_range = np.linspace(min(x2), max(x2))
            fit_y1 = fit_func1(x_range)
            fit_y2 = fit_func2(x_range)

            plt.figure(figsize=(8, 6.1))
            # plt.title(name)
            plt.ylabel(ylabel)
            plt.xlabel(xlabel)
            plt.xlim(
                min(x2) - 0.1 * abs(min(x2)),
                max(x2) + 0.1 * abs(min(x2)))

            plt.plot(x1, y1, 'ro', label='initial')
            plt.plot(x2, y2, 'bo', label='relaxed')
            plt.plot(
                x_range,
                fit_y1,
                'r-',
            )  #label = 'init_fit')
            plt.plot(
                x_range,
                fit_y2,
                'b-',
            )  #label = 'r_fit'   )
            plt.legend(loc=9)

            if lines == 'xy':
                plt.axvline(color='k')
                plt.axhline(color='k')

            plt.tight_layout()
            #plt.savefig('images/'+image_name)
            file = header.path_to_images + '/' + str(image_name) + '.png'
            makedir(file)
            print_and_log('Saving file ...', file, imp='y')
            plt.savefig(file, format='png', dpi=300)
        return fit_func2
예제 #5
0
def get_from_server(files=None, to=None, to_file=None, addr=None, trygz=True):
    """
    Download files using either  paramiko (higher priority) or rsync; 
    For paramiko header.ssh_object should be defined

    files (list of str)  - files on cluster to download 
    to (str)      - path to local folder ! 
    to_file (str) - path to local file (if name should be changed); in this case len(files) should be 1 

    The gz file is also checked

    RETURN
        result of download

    TODO:
    now for each file new connection is opened, 
    copy them in one connection
 


    """

    # print(addr)

    def download(file, to_file):

        if header.ssh_object:

            exist = file_exists_on_server(file, addr)
            # try:
            if exist:
                printlog('Using paramiko: ssh_object.get(): from  to ', file,
                         to_file)
                header.ssh_object.get(file, to_file)
                out = ''
            # except FileNotFoundError:
            else:
                out = 'file not found'

        else:
            # print(addr,file,to_file)
            out = runBash('rsync -uaz  ' + addr + ':' + file + ' ' + to_file)

        if 'error' in out:
            res = out
        else:
            res = 'OK'
            out = ''

        printlog('Download result is ', res)

        return out

    if '*' in files:
        printlog('get_from_server(): get by template')
        files = run_on_server('ls ' + files, addr).splitlines()
        # print(files)
        # sys.exit()
        printlog('get_from_server(): I download', files)

    elif not is_list_like(files):
        files = [files]

    files = [file.replace('\\', '/')
             for file in files]  #make sure the path is POSIX

    files_str = ', '.join(np.array(files))
    printlog('Trying to download', files_str, 'from server', imp='n')

    for file in files:

        if not to and not to_file:  #use temporary file
            with tempfile.NamedTemporaryFile() as f:
                to_file_l = f.name  #system independent filename

        elif not to_file:  #obtain filename
            to_file_l = os.path.join(to, os.path.basename(file))

        else:
            to_file_l = to_file

        makedir(to_file_l)

        out = download(file, to_file_l)

        if out and trygz:

            printlog('File', file, 'does not exist, trying gz', imp='n')
            file += '.gz'
            to_file_l += '.gz'
            out = download(file, to_file_l)

            if out:
                printlog('    No gz either!', imp='n')
            else:
                gunzip_file(to_file_l)

    return out
예제 #6
0
파일: inout.py 프로젝트: dimonaks/simanaks
def write_lammps(st, filename='', charges=None):
    """Writes structure in lammps format 

    charges (list of float) - list of charges for each atom type
    """

    rprimd = st.rprimd
    xcart = st.xcart
    xred = st.xred
    typat = st.typat
    ntypat = st.ntypat
    znucl = st.znucl
    name = st.name
    natom = st.natom

    if natom != len(xred) != len(xcart) != len(typat) or len(znucl) != max(
            typat):
        printlog("Error! write_xyz: check your structure")

    if name == '':
        name = 'noname'
    if xcart == [] or len(xcart) != len(xred):
        printlog(
            "Warining! write_xyz: len(xcart) != len(xred) making xcart from xred.\n",
            imp='y')
        xcart = xred2xcart(xred, rprimd)
        #print xcart[1]

    if not filename:
        filename = 'lammps/' + name

    filename += '.inp'

    makedir(filename)
    """Write lammps structure file;  """
    if 1:
        """ My version; valid only for octahedral cells"""
        printlog(
            "Warining! write_lammps(): this func supports only orthogonal cells",
            imp='Y')

        with open(filename + '', 'w') as f:
            f.write("Lammps format " + name + '\n')
            f.write(str(natom) + " atoms\n")
            f.write(str(ntypat) + " atom types\n")
            f.write("{:10.8f}  {:10.8f}  xlo xhi\n".format(0, rprimd[0][0]))
            f.write("{:10.8f}  {:10.8f}  ylo yhi\n".format(0, rprimd[1][1]))
            f.write("{:10.8f}  {:10.8f}  zlo zhi\n".format(0, rprimd[2][2]))
            f.write("0.00000000  0.00000000  0.00000000  xy xz yz\n")
            f.write("\nAtoms\n\n")

            for i, x in enumerate(xcart):
                f.write("{0:8d} {1:2d}".format(i + 1, typat[i]))
                if charges:
                    f.write(" {:6.3f}".format(charges[typat[i] - 1]))
                f.write(" {:12.6f}  {:12.6f}  {:12.6f}\n".format(
                    x[0], x[1], x[2]))

            f.write("\n")

        printlog('File', filename, 'was written', imp='y')

    else:
        """Write poscar and convert from poscar to lammps using external script; Valid for arbitary cells"""
        cl.write_structure('POSCAR',
                           'dir',
                           path='voronoi_analysis/',
                           state=state)
        runBash(
            "voronoi_analysis/VASP-poscar2lammps.awk voronoi_analysis/POSCAR > "
            + filepath)

    if 0:
        """Write lammps.in file """
        with open('voronoi_analysis/voronoi.in', 'w') as f:
            f.write("""units           metal
                    atom_style atomic
                    boundary        p p p\n""")
            f.write(
                "read_data   /home/aksenov/programs/Simulation_wrapper/siman1/voronoi_analysis/structure.lammps\n"
            )
            #         f.write('lattice   custom 1 ')
            #         for i, a in enumerate(rprimd):
            #             f.write(' a'+str(i+1))
            #             for x in a:
            #                 f.write(' '+str(x))

            #         f.write(' &\n')
            #         for x in xred:
            #             f.write(' basis {0:f} {1:f} {2:f}&\n '.format(x[0], x[1], x[2]) )
            #         f.write("""\n
            # region 1 prism 0 1 0 1 0 1  1 0 0
            # create_box 1 prism
            # create_atoms 1 prism""")

            for i in range(ntypat):
                f.write('\nmass ' + str(i + 1) + ' ' + str(int(znucl[i])) +
                        '\n')

            f.write('pair_style      lj/cut 2.0\n')
            for i in range(ntypat):
                for j in range(i, ntypat):
                    f.write('pair_coeff      ' + str(i + 1) + ' ' +
                            str(j + 1) + ' 0.0 1.0\n')

            f.write("""compute v1 all voronoi/atom
                    dump    d1 all custom 1 /home/aksenov/programs/Simulation_wrapper/siman1/voronoi_analysis/dump.voro id type x y z c_v1[1] c_v1[2]
                    run 0
                    uncompute v1\n""")

    return
예제 #7
0
파일: inout.py 프로젝트: dimonaks/simanaks
def write_xyz(st=None,
              path=None,
              filename=None,
              file_name=None,
              include_vectors=True,
              repeat=1,
              shift_2view=1.0,
              replications=None,
              full_cell=False,
              analysis=None,
              show_around=None,
              show_around_x=None,
              nnumber=6,
              only_elements=None,
              gbpos2=None,
              gbwidth=1,
              withgb=False,
              include_boundary=2,
              imp_positions=[],
              imp_sub_positions=None,
              jmol=None,
              specialcommand=None,
              jmol_args=None,
              sts=None):
    """Writes st structure in xyz format in the folder xyz/path

    if repeat == 2: produces jmol script
    shift_2view - in rprimd[1][1] - shift of the second view
    gbpos2 - position of grain boundary in A
    gbwidth - atoms aroung gbpos2 will be colored differently

    imp_positions - (x1,x2,x3, element, label)- xcart and element name coordinates additionally to be added to structure; to visulaze all impurity positions: for jmol, additional key 's', 'i' can be added after element
    imp_sub_positions - list of atom numbers; the typat of these atoms is changed: not used now


    analysis - additional processing, allows to show only specifice atoms, 
        'imp_surrounding' - shows Ti atoms only around impurity
        nnumber - number of neighbours to show
        show_around - choose atom number around which to show, from 1
        show_around_x - show atoms around point, has higher priority
        only_elements - see local_surrounding

    replications - list of replications, (2,2,2) 

    full_cell - returns atoms to cell and replicate boundary atoms

    include_vectors (bool) - write primitive vectors to xyz

    jmol - 1,0 -  use jmol to produce png picture
    jmol_args - see write_jmol()

    specialcommand - any command at the end of jmol script


    sts - list of Structure - write several structures to xyz file - other options are not working in this regime
    """

    if jmol_args == None:
        jmol_args = {}

    if st == None:
        st = sts[0]

    if replications:
        st = replic(st, mul=replications, inv=1)

    def update_var(st):
        if st.natom != len(st.xred) != len(st.xcart) != len(st.typat) or len(
                st.znucl) != max(st.typat):
            printlog("Error! write_xyz: check your arrays.\n\n")

        if st.xcart == [] or len(st.xcart) != len(st.xred):
            printlog(
                "Warining! write_xyz: len(xcart) != len(xred) making xcart from xred.\n"
            )
            st.xcart = xred2xcart(st.xred, st.rprimd)
            #print xcart[1]

        return st.rprimd, st.xcart, st.xred, st.typat, st.znucl, len(st.xred)

    rprimd, xcart, xred, typat, znucl, natom = update_var(st)

    if file_name:
        name = file_name
    elif filename:
        name = filename
    else:
        name = st.name

    if sts:
        name += '_traj'

    printlog("write_xyz(): Name is", name, important='n')

    if name == '':
        name = 'noname'

    if path:
        basepath = path
    else:
        basepath = 'xyz/'

    suf = ''
    """Processing section"""

    if analysis == 'imp_surrounding':

        if show_around == 0:
            printlog('Error! number of atom *show_around* should start from 1')

        suf = '_loc' + str(show_around)
        lxcart = []
        ltypat = []
        i = 0

        if is_list_like(show_around_x):
            x = show_around_x
            x_t = local_surrounding(x,
                                    st,
                                    nnumber,
                                    control='atoms',
                                    periodic=True,
                                    only_elements=only_elements)
            # print('write_xyz: local_surround:', x_t)
            lxcart += x_t[0]
            ltypat += x_t[1]
        else:

            for t, x in zip(typat, xcart):

                condition = False
                # print show_around, 'show'
                if show_around:
                    # print i, condition
                    condition = (i + 1 == show_around)
                    # print i, condition

                else:
                    condition = (
                        t > 1
                    )  # compat with prev behav, to show around any impurities (all atoms with typat more than one)

                # print 'se', condition

                if condition:
                    # lxcart.append(x)
                    # ltypat.append(t)
                    # print x, ' x'
                    x_t = local_surrounding(x,
                                            st,
                                            nnumber,
                                            control='atoms',
                                            periodic=True,
                                            only_elements=only_elements)
                    # print x_t[1]
                    lxcart += x_t[0]
                    ltypat += x_t[1]
                i += 1

        xcart = lxcart
        typat = ltypat
        natom = len(typat)
        # print natom, 'nat'

    name += suf
    xyzfile = os.path.join(basepath, name + ".xyz")
    makedir(xyzfile)
    """Include atoms on the edge of cell"""
    if full_cell:
        # print xred
        # print natom
        # st = return_atoms_to_cell(st)
        # print xred
        st = replic(st,
                    mul=(1, 1, 2),
                    inv=0,
                    cut_one_cell=1,
                    include_boundary=include_boundary)
        # print natom, st.natom

        # print st.xred

        rprimd, xcart, xred, typat, znucl, natom = update_var(st)

    # asdegf
    """Writing section"""
    # printlog("Writing xyz: "+xyzfile, imp = 'y')

    #analyze imp_positions
    if imp_sub_positions == None:
        imp_sub_positions = []
    nsub = 0
    for pos in imp_positions:
        # if len(pos) > 4:
        #     if 's' not in pos[4]: continue # skip interstitial positions

        xs = np.asarray([pos[0], pos[1], pos[2]])
        nsub += 1
        # print xs
        for i, x in enumerate(xcart):
            # print np.linalg.norm( x-xs)
            if np.linalg.norm(x - xs) < 1:
                imp_sub_positions.append(i)

    if imp_sub_positions:
        printlog(imp_sub_positions, ': numbers of found atoms to be changed ')

    # for i in sorted(indices, reverse=True):
    #     del somelist[i]

    if include_vectors:
        nvect = 3
    else:
        nvect = 0

    def write(st):
        rprimd, xcart, xred, typat, znucl, natom = update_var(st)

        f.write(str(natom + len(imp_positions) - nsub + nvect) +
                "\n")  #+3 vectors
        f.write(name + "\n")
        if imp_positions:
            for i, el in enumerate(imp_positions):
                # if len(el) != 4: continue
                f.write("%s %.5f %.5f %.5f \n" % (el[3], el[0], el[1], el[2]))
                # print 'composite -pointsize 60 label:{0:d} -geometry +{1:d}+{2:d} 1.png 2.png'.format(i, el[0], el[1])

        for i in range(natom):
            typ = typat[i] - 1

            z = int(znucl[typ])

            if i in imp_sub_positions:
                # f.write( "Be " )
                continue
            else:
                el = element_name_inv(z)
                f.write(el + " ")

            f.write("%.5f %.5f %.5f \n" %
                    (xcart[i][0], xcart[i][1], xcart[i][2]))

        if include_vectors:
            for r in st.rprimd:
                f.write('Tv {:.10f} {:.10f} {:.10f}\n'.format(*r))

    with open(xyzfile, 'w') as f:
        if sts:
            for st in sts:
                write(st)
        else:
            for i in range(repeat):
                write(st)

    # os._exit(1)
    printlog('File', xyzfile, 'was written', imp='y')

    pngfile = None
    if jmol:
        """
        script mode for jmol. Create script file as well for elobarate visualization
        """
        """Choose gb atoms to change their color"""
        printlog('position of boundary 2', gbpos2)
        atomselection = ''

        #create consistent xcart_new list like it will be in Jmol
        xcart_new = []
        for i, x in enumerate(xcart):
            if i in imp_sub_positions: continue
            xcart_new.append(x)

        if gbpos2:

            gbpos1 = gbpos2 - rprimd[0][0] / 2.
            gbatoms = []

            for i, x in enumerate(xcart_new):
                # print i
                # if x[0] > gbpos1 - gbwidth/2. and x[0] < gbpos1 + gbwidth/2.:
                if abs(x[0] - gbpos1) < gbwidth / 2.:
                    gbatoms.append(i)
                    # print i, x[0], abs(x[0] - gbpos1)
                if abs(x[0] - gbpos2) < gbwidth / 2.:
                    # if x[0] > gbpos2 - gbwidth/2. and x[0] < gbpos2 + gbwidth/2.:
                    # print i, x[0], abs(x[0] - gbpos2)
                    gbatoms.append(i)
            printlog('Atoms at GB:', gbatoms)
            atomselection = ''
            for i in gbatoms:
                atomselection += 'Ti' + str(i + 1 + len(imp_positions)) + ','
            atomselection = atomselection[:-1]

        # elif withgb: # color half of cell
        # else: # color half of cell
        #     # pass
        # atomselection = 'atomno>'+str(0+len(imp_positions) )+' and atomno<'+str(( natom + len(imp_positions)  )/2-1)

        xyzfile = os.getcwd() + '/' + xyzfile
        scriptfile = basepath + name + ".jmol"
        bn = (basepath + name).replace('.', '_')
        pngfile = os.getcwd() + '/' + bn + ".png"

        printlog('imp_positions = ', imp_positions)
        write_jmol(xyzfile,
                   pngfile,
                   scriptfile,
                   atomselection,
                   rprimd=rprimd,
                   shift=shift_2view,
                   label=[(pos[3], pos[4]) for pos in imp_positions],
                   specialcommand=specialcommand,
                   **jmol_args)

    return xyzfile, pngfile
예제 #8
0
def neb_analysis(cl, show, up = None, push2archive = None, old_behaviour = None, results_dic = None, fitplot_args = None, style_dic = None, params = None):
    """
    Analyse traectories and polarons

    params
        mep_shift_vector
    """
    if results_dic is None:
        results_dic = {}

    calc = header.calc
    path2mep_s = cl.project_path_cluster+'/'+cl.dir+'/mep.eps'
    itise = cl.id[0]+'.'+cl.id[1]
    # print(cl.ldauu)
    # sys.exit()
    name_without_ext = 'mep.'+itise+'.U'+str(max(cl.ldauu))
    path2mep_l = cl.dir+name_without_ext+'.eps'
    # print(path2mep_l)
    if not os.path.exists(path2mep_l) or '2' in up:
        ''
        get_from_server(files = path2mep_s, to_file = path2mep_l, addr = cl.cluster_address, )
        movie_to = cl.dir+'/movie.xyz'
        get_from_server(files = cl.project_path_cluster+'/'+cl.dir+'/movie.xyz', to_file = movie_to, addr = cl.cluster_address, )
        
        if os.path.exists(movie_to):
            makedir('figs/'+name_without_ext+'.xyz')
            shutil.copyfile(movie_to, 'figs/'+name_without_ext+'.xyz')



    # trying to get one image closest to the saddle point
    if old_behaviour and cl.version == 2: #old behaviour, now created automatically in add callc
        im = cl.set.vasp_params['IMAGES']
        # if im % 2 > 0: #odd
        #     i = im//2 + 1
        # else:
        #     i = im/2
        # if choose_image:
        #     i = choose_image

        for i in range(im):
            i+=1
            cl_i = copy.deepcopy(cl)
            cl_i.version+=i
            cl_i.id = (cl.id[0], cl.id[1], cl_i.version)
            cl_i.name = str(cl_i.id[0])+'.'+str(cl_i.id[1])+'.'+str(cl_i.id[2])
            # print cl_i.name
            cl_i.path["output"] = cl_i.dir+'0'+str(i)+"/OUTCAR"
            # for i in range():

            cl_i.associated_outcars = [ aso[2:] for aso in cl_i.associated_outcars  ]

            # print cl_i.path["output"] 
            cl_i.state = '2. Ready to read outcar'
            # if not os.path.exists(cl_i.path["output"]):
            #     load = 'o'
            outst2 = ("%s"%cl_i.name).ljust(name_field_length)
            if readfiles:
                print(outst2+'|'+cl_i.read_results(loadflag, show = show, choose_outcar = choose_outcar) )
            else:
                print_and_log(outst2+' | File was not read')
            

            if cl_i.id in calc: #move creation of calcs with images to add_neb
                ''
                # print_and_log('Please test code below this message to save prev calcs')
                # if cl_i != calc[cl_i.id]
                #     if hasattr(calc[cl_i.id], 'prev') and calc[cl_i.id].prev:
                #         prevlist = calc[cl_i.id].prev
                #     else:
                #         prevlist = [calc[cl_i.id]]
                #     cl_i.prev = prevlist
                #     calc[cl_i.id] = cl_i
            else:
                calc[cl_i.id] = cl_i






    # print path2mep_l
    if 0:
        if os.path.exists(path2mep_l):
            # get_from_server(file = path2mep_s, to = path2mep_l, addr = cluster_address)

            runBash('evince '+path2mep_l)
        else:
            a =  glob.glob(cl.dir+'*mep*')
            if a:
                runBash('evince '+a[0])


    


    cl1 = calc[cl.id[0], cl.id[1], 1]
    cl2 = calc[cl.id[0], cl.id[1], 2]
    

    atom_num = find_moving_atom(cl1.end, cl2.end)

    #prepare lists
    ni = cl.set.vasp_params['IMAGES']
    vlist = [1]+list(range(3, ni+3) )+[2]
    # print( vlist)
    mep_energies = []
    atom_pos     = []



    pols = []
    sts = []
    sts_loc = []
    dAO = [] # A-(O,F) distance for each image

    for v in vlist:
        cli = calc[cl.id[0], cl.id[1], v]
        # print(cl.id[0], cl.id[1], v, cli.state)
        if '4' not in cli.state and 'un' not in up:
            printlog('Attention! res_loop(): analys_type == neb, Calc',cli.id,'is not finished; return')
            return {}, []
        # print cli.id
        # cli.end = return_to_cell(cli.end)
        # mep_energies.append(  min(cli.list_e_sigma0)   ) #use minimum energy - not very good, sometimes unconverged energy could be lower! 
        mep_energies.append(  cli.energy_sigma0   ) #use last energy 
        atom_pos.append( cli.end.xcart[atom_num] )

        # Find polaron positions
        if 1 or 'polaron' in show:
            pol, mag = find_polaron(cli.end, atom_num)
            if pol:
                for key in pol:
                    if np.any(pol[key]):
                        for n in pol[key]:
                            if n not in pols:
                                pols.append(n)
            else:
                ''
                # print('Mag_moments on trans,', mag.round(1))
        
        if 1 or 'neb_geo' in show:
            #visualization of path
            # print(atom_num)
            st = copy.deepcopy(cli.end)
            # print('moving_atom', st.xcart[atom_num])
            info = st.nn(atom_num, 15, from_one = False, silent = 1)
            

            st.moving_atom_i = atom_num
            st_loc = info['st']


            # print(st_loc.xcart)
            # st_loc = st_loc.shift
            
            if v == vlist[0]:

                st1 = copy.deepcopy(st)


                vec = st.center_on(atom_num)
                # vec = np.asarray([0.,0.,0.])

            
                if params is not None and 'mep_shift_vector' in params:
                    # vec += np.array([0.11,0.11,0]) # path4
                    # print(params['mep_shift_vector'])
                    vec += np.array(params['mep_shift_vector']) # path4

            # print(vec)
            st_loc = st_loc.shift_atoms(vec)
            if 0:
                st_loc.write_xyz()
            # st.write_cif('xyz/'+st.name)
            st.shift_atoms(vec).write_xyz()
            sts_loc.append(st_loc)

            st1 = st1.add_atom(st.xred[atom_num], 'Rb')

            sts.append(st.shift_atoms(vec))


            if 0:
                info1 = st.nn(atom_num, 2, from_one = False, silent = 1)
                print('Average_distance A-2(O,F)', info1['av(A-O,F)'], 'A')
                dAO.append (info1['av(A-O,F)'])


            if 0 or 'neb_geo' in show:
                av = st.nn(atom_num, 2, from_one = False, silent = 1, more_info = 1)['avsq(A-O,F)']
                print('Average squared distance A-2(O,F)', av, 'A')

                info2 = st.nn(atom_num, 4, from_one = False, silent = 1)
                print('Average_distance A-4(O,F)', info2['av(A-O,F)'], 'A')
                print('Elements are ', info2['el'])

                info3 = st.nn(atom_num, 6, from_one = False, silent = 1, more_info = 1)
                print('Average_distance A-6(O,F)', info3['av(A-O,F)'], 'A')
                print('Average_deviation A-6(O,F)', info3['avdev(A-O,F)'], 'mA')
                print('Elements are ', info3['el'])



    write_xyz(sts = sts) # write traectory
    write_xyz(sts = sts_loc) # write traectory

    st1 = st1.shift_atoms(vec)
    st1.name +='_all'
    # st1.write_cif('xyz/'+st1.name)
    st1.write_xyz()


    if dAO: # find maximum change of distance during migration
        dAO_change = abs(min(dAO) - max(dAO))
        results_dic['dAO_change'] = dAO_change

    results_dic['sts_loc'] = sts_loc # list of local structures, each structure contains dlist - distances from central cation to anions, and ellist - types of elements
    results_dic['sts'] = sts # list of mep structures, each structure contains moving_atom_i - number of moving atom


    if len(pols) > 0:
        print('During migration of alkali ions polarons are detected on atoms:', pols)
    elif len(pols) > 1:
        printlog('Attention! polaron is moving during migration! Obtained barrier is ambiguous')
    else:
        printlog('Compare magnetic moments above! In principle should be the same!')


    # print np.array(atom_pos)

    #test if the distances between points are not spoiled by PBC 
    nbc = range(-1, 2)
    jj=0
    for x in atom_pos:

        x2 = atom_pos[jj+1]
        r = cl.end.rprimd
        d1, _ = image_distance(x, x2, r, order = 1) #minimal distance
        x2_gen = (x2 + (r[0] * i  +  r[1] * j  +  r[2] * k) for i in nbc for j in nbc for k in nbc) #generator over PBC images
        x2c = copy.deepcopy(x2)
        ii = 0
        while  np.linalg.norm(x - x2c) > d1: #find the closest PBC image position
            if ii > 100:
                break
            ii+=1
            x2c = next(x2_gen)
        atom_pos[jj+1] = x2c
        jj+=1
        if jj == len(atom_pos)-1: # the last point is not needed, we could not use slice since we need to use changed atom_pos in place
            break
        # print np.linalg.norm(x - x2c), d1



    _, diff_barrier = plot_mep(atom_pos, mep_energies, plot = 0, show = 0, fitplot_args = fitplot_args, style_dic = style_dic)

    results_dic['barrier'] = diff_barrier
    
    middle_image = len(vlist) // 2
    results_dic['dEm1']    = mep_energies[middle_image] - mep_energies[0]
    


    cl1.barrier = diff_barrier
    cl2.barrier = diff_barrier





    if 'mep' in show:
        if 'mepp' in show:
            show_flag = True
        else:
            show_flag = False
        # sys.exit()

        plot_mep(atom_pos, mep_energies, image_name = 'figs/'+name_without_ext+'_my.eps', show = show_flag, fitplot_args = fitplot_args,  style_dic = style_dic)






    if push2archive:
        path2saved, _ = plot_mep(atom_pos, mep_energies, image_name = 'figs/'+name_without_ext+'_my', fitplot_args = fitplot_args, style_dic = style_dic)
        push_figure_to_archive(local_figure_path = path2saved, caption = description_for_archive)








        if 0: #copy files according to chosen outcar to run nebresults locally 
            wd = cl_i.dir
            out_i = cl_i.associated_outcars[choose_outcar-1]
            out_1 = calc[cl.id[0],cl.id[1], 1].associated_outcars[choose_outcar-1]
            out_2 = calc[cl.id[0],cl.id[1], 2].associated_outcars[choose_outcar-1]
            # print out_1
            # print out_2 
            shutil.copyfile(wd+out_1, wd+'00/OUTCAR')
            shutil.copyfile(wd+out_2, wd+'04/OUTCAR')
            for d in ['01/','02/','03/' ]:
                shutil.copyfile(wd+d+out_i, wd+d+'OUTCAR')

                # print wd+d+out_i

    return results_dic
예제 #9
0
def fit_a(conv, n, description_for_archive, analysis_type, show, push2archive):

    """Fit equation of state for bulk systems.

    The following equation is used::

       sjeos (default)
           A third order inverse polynomial fit 10.1103/PhysRevB.67.026103

                           2      3        -1/3
       E(V) = c + c t + c t  + c t ,  t = V
               0   1     2      3

       taylor
           A third order Taylor series expansion about the minimum volume

       murnaghan
           PRB 28, 5480 (1983)

       birch
           Intermetallic compounds: Principles and Practice,
           Vol I: Principles. pages 195-210

       birchmurnaghan
           PRB 70, 224107

       pouriertarantola
           PRB 70, 224107

       vinet
           PRB 70, 224107

       antonschmidt
           Intermetallics 11, 23-32 (2003)

       p3
           A third order polynomial fit

        Use::

           eos = EquationOfState(volumes, energies, eos='sjeos')
           v0, e0, B = eos.fit()
           eos.plot()

    """
    # e, v, emin, vmin       = plot_conv( conv[n], calc,  "fit_gb_volume2")


    from picture_functions import fit_and_plot

    alist = []
    vlist = []
    etotlist  = []
    magn1 = []
    magn2 = []
    alphas= []
    for id in conv[n]:
        cl = db[id]
        st = cl.end
        alist.append(cl.end.rprimd[0][0])
        etotlist.append(cl.energy_sigma0)
        vlist.append(cl.end.vol)
        magn1.append(cl.magn1)
        magn2.append(cl.magn2)
        alpha, beta, gamma = st.get_angles()
        alphas.append(alpha)
        print('alpha, energy: {:4.2f}, {:6.3f}'.format(alpha, cl.energy_sigma0))

    fit_and_plot(U1 = (alphas, etotlist, 'o-r'), 
        image_name = 'figs/angle', ylabel = 'Total energy, eV', xlabel = 'Angle, deg', xlim = (89, 92.6))

    if ase_flag:
        if 'angle' in analysis_type:
            eos = EquationOfState(alphas, etotlist, eos = 'sjeos')
        else:
            eos = EquationOfState(vlist, etotlist, eos = 'sjeos')
        # import inspect

        # print (inspect.getfile(EquationOfState))

        v0, e0, B = eos.fit()
        #print "c = ", clist[2]
        printlog( '''
        v0 = {0} A^3
        a0 = {1} A
        E0 = {2} eV
        B  = {3} eV/A^3'''.format(v0, v0**(1./3), e0, B), imp = 'Y'  )

        savedpath = 'figs/'+cl.name+'.png'
        makedir(savedpath)


        cl.B = B*160.218
        # plt.close()
        # plt.clf()
        # plt.close('all')
        if 'fit' in show:
            mpl.rcParams.update({'font.size': 14})

            eos.plot(savedpath, show = True)
            printlog('fit results are saved in ',savedpath, imp = 'y')
        else:
            printlog('To use fitting install ase: pip install ase')
    # plt.clf()

    if push2archive:
        push_figure_to_archive(local_figure_path = savedpath, caption = description_for_archive)

    return
예제 #10
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
예제 #11
0
def get_from_database(x1,
                      x2,
                      mat,
                      inquiry_keys=None,
                      silent=None,
                      ssh_object=None):
    """
    inquiry_keys (list) - list of keys that should exist in filenames both for x1 and x2
    ssh_object (SSHTools) - ssh object based on paramiko with access details

    """
    from classes import CalculationVasp

    def check(key, inquiry_keys):
        return all([k in key for k in inquiry_keys])

    path2database = '/home/Data/CEStorage/'

    hash_dict_file = 'hash_dict.json'

    cluster_path2hash = os.path.join(path2database, hash_dict_file)

    if inquiry_keys is None:
        inquiry_keys = []

    if ssh_object:
        # ssh_object.get()
        tempdir = tempfile.gettempdir()
        local_path2hash = os.path.join(tempdir, hash_dict_file)

        ssh_object.get(cluster_path2hash, local_path2hash)

        # sys.exit()

    with open(local_path2hash, 'r') as fp:
        hash_dict = json.load(fp)

    # print(hash_dict)
    x1s = []
    x2s = []
    # print(hash_dict)
    for key, val in hash_dict.items():
        if check(key, inquiry_keys + [x1, mat]):
            x1s.append(key)

        if check(key, inquiry_keys + [x2, mat]):
            x2s.append(key)

    x1s = sorted(x1s, key=lambda el: len(el))
    x2s = sorted(x2s, key=lambda el: len(el))

    for xi, xis in (x1, x1s), (x2, x2s):
        if not silent:
            print('\nFiles for', xi, ':')
        for i, f in enumerate(xis):
            if not silent:

                print(i + 1, f)

    if len(x1s) == 0 or len(x2s) == 0:
        print('No information in database for this inquire:', x1, x2, mat,
              str(inquiry_keys))
        return None, None

    key1 = x1s[0]
    key2 = x2s[0]

    if not silent:

        print('\nI choose first entries for both concentrations:', key1, 'and',
              key2, '\n')
    # print('Use *inquiry_keys* arg to clarify the output results.\n')

    #get files
    loc1 = os.path.join(tempdir, hash_dict[key1])
    loc2 = os.path.join(tempdir, hash_dict[key2])
    makedir(loc1)
    makedir(loc2)
    # print()/

    ssh_object.get(os.path.join(path2database, hash_dict[key1]), loc1)
    ssh_object.get(os.path.join(path2database, hash_dict[key2]), loc2)

    cl1 = CalculationVasp().deserialize(loc1)
    cl2 = CalculationVasp().deserialize(loc2)

    return cl1, cl2