Esempio n. 1
0
def insert(it_ins, ise_ins, mat_path, it_new, calc, type_of_insertion="xcart"):
    """For insertion of atoms to cells with changed lateral sizes
    Input:
    'type_of_insertion = xred' used to add xred coordinates  
    mat_path - path to geo files which are supposed to be changed
    it_ins - already existed calculation; xred will be used from this calculation.
    it_new - new folder in geo folder for obtained structure
    
    This function finds version of calculation in folder mat_path and tries to use the same version of it_ins

    """
    if not os.path.exists(mat_path):
        print_and_log("Error! Path " + mat_path + " does not exist\n\n")
        raise RuntimeError

    if it_ins not in mat_path and it_ins not in it_new:
        print_and_log('Cells are', it_ins, mat_path, it_new)
        print_and_log(
            "Error! you are trying to insert coordinates from cell with different name\n\n"
        )
        #raise RuntimeError

    hstring = ("%s    #on %s" %
               (traceback.extract_stack(None, 2)[0][3], datetime.date.today()))
    if hstring != header.history[-1]: header.history.append(hstring)

    geofilelist = runBash('find ' + mat_path +
                          '/target -name "*.geo*" ').splitlines()

    if geofilelist == []:
        print_and_log(
            "Warning! Target folder is empty. Trying to find in root folder ..."
        )
        geofilelist = runBash('find ' + mat_path +
                              '/ -name "*.geo*" ').splitlines()

    ins = None
    for mat_geofile in geofilelist:
        mat = CalculationVasp()
        mat.name = mat_geofile
        mat.read_geometry(mat_geofile)
        #step = 0.27
        #r_pore = 0.56
        #r_mat = mat.hex_a / 2 - step
        #pores = find_pores(mat.init, r_mat, r_pore, step, 0.3, 'central') #octahedral
        #mat.xcart.append ( pores.xcart[0] )
        #mat.typat.append(1)
        try:
            ins_working = ins
            ins = calc[(it_ins, ise_ins, mat.version)]
        except KeyError:
            print_and_log("No key", (it_ins, ise_ins, mat.version),
                          "I use previous working version !!!",
                          imp='y')
            ins = ins_working
            #return
        #ins.end.znucl = ins.znucl
        #ins.end.nznucl = ins.nznucl
        #ins.end.ntypat = ins.ntypat
        #ins.end.typat = ins.typat
        #print ins.xcart[-1]
        mat_geopath = geo_folder + struct_des[it_new].sfolder + '/'

        if type_of_insertion == "xcart":
            #Please update here!
            mat_filename = '/' + it_new + "." + "inserted." + str(
                mat.version) + '.' + 'geo'

            v = np.zeros(3)
            result = insert_cluster(ins.end, v, mat.init, v)
            mat.end = result
            mat.init = result
            # mat.znucl  =   mat.end.znucl
            # mat.nznucl =   mat.end.nznucl
            # mat.ntypat =   mat.end.ntypat
            # mat.typat  =   mat.end.typat
            # mat.natom = len(mat.end.xred)
            #mat.version = ins.version
            des = ins.name + " was inserted to " + mat_geofile

        elif type_of_insertion == "xred":

            mat_filename = '/from/' + it_new + ".xred." + str(
                mat.version) + '.' + 'geo'

            #mat.end.rprimd = mat.rprimd
            #mat.init.xred  = copy.deepcopy(ins.end.xred)
            #mat.init.typat = copy.deepcopy(ins.end.)
            #print ins.end.xcart
            rprimd = copy.deepcopy(mat.init.rprimd)
            #build    = mat.build
            mat.init = copy.deepcopy(ins.end)
            #mat.build = build
            mat.init.rprimd = rprimd  #return initial rprimd
            mat.init.xred2xcart()  #calculate xcart with new rprimd

            des = "atoms with reduced coord. from " + ins.name + " was fully copied to " + mat_geofile
            mat.init.name = 'test_insert_xred' + str(mat.version)
            write_xyz(mat.init)

        mat.path["input_geo"] = mat_geopath + it_new + mat_filename
        if not mat.write_geometry("init", des): continue
        print_and_log("Xred from " + it_ins + " was inserted in " +
                      mat_geofile + " and saved as " + mat_filename + " \n\n")

    return
Esempio n. 2
0
    vasprun_command = params.get('vasp_run') or 'vasp'
    nmcstep = params.get('mcsteps') or 2  # minimum two steps are done
    thickness = params.get('thickness') or 6  # minimum layer
    temperature = params.get('temp') or 1

    printlog('\n\n\nStarting Monte-Carlo script!')
    printlog('Command to run vasp', vasprun_command)
    printlog('Total number of steps is', nmcstep)
    printlog('Thickness is ', thickness)
    printlog('Temperature is ', temperature, 'K')
    """1. Run initial calculation"""
    if debug:
        cl = CalculationVasp()
        cl.read_poscar('1.POSCAR')
        cl.end = cl.init
        last_number = 0
    else:

        files_yes = glob.glob('*yes.pickle')  #get list of calculated yes files
        files_all = glob.glob('*.pickle')  #get list of all calculated files
        """Find last yes pickle file"""
        if files_yes:
            yes_numbers = [int(file.split('-')[0]) for file in files_yes]
            all_numbers = [int(file.split('-')[0]) for file in files_all]
            last_yes_n = max(yes_numbers)
            last_number = max(all_numbers)
            last_yes_file = str(last_yes_n) + '-yes.pickle'
            printlog('Last calculation file is ', last_yes_file, imp='y')

        else:
Esempio n. 3
0
def initial_run(xcart_voids, ):
    """1. Run initial calculation"""
    if debug:
        cl = CalculationVasp()
        cl.read_poscar('1.POSCAR')
        cl.end = cl.init
        if xcart_voids: # read void coordinates
            cl.end = cl.end.add_atoms(xcart_voids, 'void')
        last_number = 0
    else:
        
        files_yes = glob.glob('*yes.pickle') #get list of calculated yes files
        files_all = glob.glob('*.pickle') #get list of all calculated files
        

        """Find last yes pickle file"""
        if files_yes:
            yes_numbers = [int(file.split('-')[0]) for file in files_yes]
            all_numbers = [int(file.split('-')[0]) for file in files_all]
            last_yes_n = max(yes_numbers)
            last_number = max(all_numbers)
            last_yes_file = str(last_yes_n)+'-yes.pickle'
            printlog('Last calculation file is ', last_yes_file, imp = 'y')
        
        else:
            last_number = 0
            last_yes_file = None

        """Read last pickle file or run vasp """
        
        if last_yes_file:
            cl = CalculationVasp().deserialize(last_yes_file)
            printlog('Successfully deserialized')
            xcart_voids = cl.end.get_specific_elements([300], fmt = 'x') # extract voids form the last calculation
        
        else:
            cl = vasp_run(3, 'first run', vasprun_command = vasprun_command)
            
            if xcart_voids: # read void coordinates
                cl.end = cl.end.add_atoms(xcart_voids, 'void')
                printlog('I found', len(xcart_voids), 'voids in config file. Added to structure.')

            if check(cl) == 0:
                cl.serialize('0-yes')
                copyfile('OUTCAR', 'OUTCAR-0')
                copyfile('OSZICAR', 'OSZICAR-0')
                copyfile('CONTCAR', 'CONTCAR-0')
                copyfile('OUTCAR', 'OUTCAR_last')
                copyfile('CONTCAR', 'CONTCAR_last')
                with open('ENERGIES', 'w') as f:
                    f.write('{:5d}  {:.5f}\n'.format(0, cl.e0))
            else:
                printlog('Calculation is broken, no data was saved, exiting ...', imp = 'y')
                sys.exit()



    if debug2:
        sys.exit()

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

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

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

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

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

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

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

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

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

    ###RETURN:
        None

    ###DEPENDS:

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


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

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

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

    if not add_loop_dic:
        add_loop_dic = {}

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

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

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

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

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

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

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

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

    # print(corenum)
    # sys.exit()

    # print(atom_to_insert)
    # sys.exit()

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

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

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

    name_suffix = ''
    st_pores = []

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

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

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

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

        st1 = st
        st2 = st_end

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

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

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

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

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

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

        else:

            atoms_to_move = []
            atoms_to_move_types = []

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

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

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

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

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

                type_atom_to_move = atom_to_move  #atoms_to_move[0][1]

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

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

                    numbers = determine_symmetry_positions(st, atom_to_move)

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

                else:
                    i_m = numbers[0][0]

                x_m = st.xcart[i_m]

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

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

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

            else:

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

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

                insert_positions = determine_unique_voids(st_pores, sums, avds)

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

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

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

                name_suffix += 'i' + str(i_void_start)

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

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

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

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

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

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

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

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

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

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

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

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

            if i_void_final == None:
                sys.exit()

            x_final = sur[0][i_void_final]  #

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

            x_del = x_final  #please compare with vacancy creation mode

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

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

            st1 = st

            st2 = st.mov_atoms(i_m, x_final)

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

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

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

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

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

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

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

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

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

            # print(x_m)
            # print(sur)

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

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

            # sys.exit()

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

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

            # sys.exit()

            header.temp_chosen_dist = chosen_dist

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

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

                # print(name_suffix)
                # sys.exit()

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

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

            # print st.magmom
            # print st1.magmom

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

                st1 = st1.del_atom(i_del)

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

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

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

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

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

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

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

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

        cl_test.actualize_set()  #find magmom for current structure

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

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

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

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

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

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

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

        if mag_config != None:

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

            name_suffix += 'm' + str(mag_config)

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

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

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

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

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

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

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

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

        if not it_new_folder and not it_folder:

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

    if rep_moving_atom:
        it_new += 'r' + rep_moving_atom

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

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

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

    cl = CalculationVasp()

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

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

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

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

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

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

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

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

    #write final position

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

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

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

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

    if center_on_moving and search_type is not None:

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

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

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

    #prepare calculations
    # sys.exit()

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

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

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

    inherit_ngkpt(it_new, it, varset[ise_new])

    if run:
        add_loop_dic['run'] = run

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

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

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

    printlog('add_neb finished')
    return it_new
Esempio n. 5
0
            xcart_voids = st_new_init.get_specific_elements([300], fmt = 'x')
            printlog('The following voids after changes were extracted from st:', xcart_voids)

        if debug:
            st_new_init.write_poscar('POSCAR-'+str(i_mcstep))
            st_new_init = read_poscar(st_new_init, 'POSCAR-'+str(i_mcstep))
            # print(xcart_voids)
            # sys.exit()
            if xcart_voids:
                st_new_init = st_new_init.add_atoms(xcart_voids, 'void')
            # xcart_voids = st_new_init.get_specific_elements([300], fmt = 'x')
            # print('After writing and reading the voids are ', xcart_voids)
            st = st_new_init
            cl = CalculationVasp()
            cl_new = CalculationVasp()
            cl.end = st
            cl_new.end = st_new_init
            cl.e0 = random.random()
            cl_new.e0 = random.random()
        else:
            """4. Write new structure and calculate energy  """

            st_new_init.write_poscar('POSCAR') #here voids are lost
            
            cl_new = vasp_run(3, 'mcstep '+str(i_mcstep), vasprun_command = vasprun_command)

            if check(cl_new):
                printlog('{:5d} is unlucky configuration, trying another ... '.format(i_mcstep), imp = 'y')
                continue