Exemple #1
0
    def set_vaspp(self, token, arg, des = "see manual"):
        """
        Used for setting vasp parameters.

        """


        if token in ("ISMEAR",):
            if type(arg) not in [int, None, ]:
                raise TypeError
        if token in ("KSPACING",):
            if type(arg) not in [float, None, ]:
                raise TypeError


        old = self.vasp_params[token]
        self.vasp_params[token] = arg
        
        if old == arg:
            print_and_log("Warning! You did not change  "+token+"  in "+self.ise+" set\n")
        else:
            self.history += " "+token+"  was changed from "+str(old)+" to "+str(arg) + "\n"
            print_and_log(token+"  was changed from "+str(old)+" to "+str(arg) +" - "+ des+" in set "+self.ise+" \n")
        
        self.update()                

        return
Exemple #2
0
def read_vectors(token, number_of_vectors, list_of_words):
    """Returns the list of numpy vectors for the last match"""

    number_of_matches = list_of_words.count(token)
    if number_of_matches == 0:
        #print_and_log("Warning token '"+token+"' was not found! return empty\n")
        return [None]

    if number_of_matches > 1:
        print_and_log("Warning token '" + token +
                      "' was found more than one times\n")
        raise RuntimeError

    index = list_of_words.index(token, number_of_matches -
                                1)  #Return the index of the last match
    #print list_of_words[index]
    list_of_vectors = []
    vector = np.zeros((3))
    for i in range(number_of_vectors):
        vector[0] = float(list_of_words[index + 1])
        vector[1] = float(list_of_words[index + 2])
        vector[2] = float(list_of_words[index + 3])
        index += 3
        list_of_vectors.append(vector.copy())
    return list_of_vectors
Exemple #3
0
 def set_relaxation_type(self,type_of_relaxation):
     name = "Type of relaxation ISIF"
     if type(type_of_relaxation) not in [str, ]:
         raise TypeError
     old = self.vasp_params["ISIF"]
     if "ions" == type_of_relaxation:
         if int(self.ise[0]) != 9:
             print_and_log("Warning! The name of set is uncostintent with relaxation type\n")
             raise TypeError     
         self.vasp_params["ISIF"] = 2
         # self.set_nmdsteps(200)
     elif type_of_relaxation == "full":
         if int(self.ise[0]) != 2:
             print_and_log("Warning! The name of set is uncostintent with relaxation type\n")
             raise TypeError              
         self.vasp_params["ISIF"] = 3
     else:
         print_and_log("Error! Uncorrect type of relaxation\n")
         raise TypeError
     arg = self.vasp_params["ISIF"]
     if old == arg:
         print_and_log("Warning! You did not change  "+name+"  in "+self.ise+" set\n")
         return
     self.history += " "+name+"  was changed from "+str(old)+" to "+str(arg) + "\n"
     print_and_log(name+"  was changed from "+str(old)+" to "+str(arg) + " in set "+self.ise+" \n")
     self.update()                
     #print self.history
     return
Exemple #4
0
 def set_relaxation_type(self,type_of_relaxation):
     name = "Type of relaxation ISIF"
     if type(type_of_relaxation) not in [str, ]:
         raise TypeError
     old = self.vasp_params["ISIF"]
     if "ions" == type_of_relaxation:
         if int(self.ise[0]) != 9:
             print_and_log("Warning! The name of set is uncostintent with relaxation type\n")
             raise TypeError     
         self.vasp_params["ISIF"] = 2
         # self.set_nmdsteps(200)
     elif type_of_relaxation == "full":
         if int(self.ise[0]) != 2:
             print_and_log("Warning! The name of set is uncostintent with relaxation type\n")
             raise TypeError              
         self.vasp_params["ISIF"] = 3
     else:
         print_and_log("Error! Uncorrect type of relaxation\n")
         raise TypeError
     arg = self.vasp_params["ISIF"]
     if old == arg:
         print_and_log("Warning! You did not change  "+name+"  in "+self.ise+" set\n")
         return
     self.history += " "+name+"  was changed from "+str(old)+" to "+str(arg) + "\n"
     print_and_log(name+"  was changed from "+str(old)+" to "+str(arg) + " in set "+self.ise+" \n")
     self.update()                
     #print self.history
     return
Exemple #5
0
    def set_vaspp(self, token, arg, des = "see manual"):
        """
        Used for setting vasp parameters.

        """


        if token in ("ISMEAR",):
            if type(arg) not in [int, None, ]:
                raise TypeError
        if token in ("KSPACING",):
            if type(arg) not in [float, None, ]:
                raise TypeError


        old = self.vasp_params[token]
        self.vasp_params[token] = arg
        
        if old == arg:
            print_and_log("Warning! You did not change  "+token+"  in "+self.ise+" set\n")
        else:
            self.history += " "+token+"  was changed from "+str(old)+" to "+str(arg) + "\n"
            print_and_log(token+"  was changed from "+str(old)+" to "+str(arg) +" - "+ des+" in set "+self.ise+" \n")
        
        self.update()                

        return
Exemple #6
0
    def printme(self):
        for key in self.vasp_params:
            if self.vasp_params[key] == None: continue
            print_and_log( "{:30s} = {:s} ".format("s.vasp_params['"+key+"']", str(self.vasp_params[key]) ), imp = 'Y', end = '\n' )

        printlog('ngkpt:', self.ngkpt, imp = 'Y')

        printlog('POTDIR:', self.potdir, imp = 'Y', end = '\n' )
Exemple #7
0
 def add_conv_kpoint(self,arg):
     if type(arg) is not str:
         sys.exit("\nadd_conv_kpoint error\n")
     if arg in self.conv_kpoint:
         print_and_log( "Warning! You already have this name in list")
         return    
     self.conv_kpoint.append(arg)
     self.history += "Name "+arg+" was added to self.conv_kpoint\n"
     self.update()
Exemple #8
0
 def add_conv_kpoint(self,arg):
     if type(arg) is not str:
         sys.exit("\nadd_conv_kpoint error\n")
     if arg in self.conv_kpoint:
         print_and_log( "Warning! You already have this name in list")
         return    
     self.conv_kpoint.append(arg)
     self.history += "Name "+arg+" was added to self.conv_kpoint\n"
     self.update()
Exemple #9
0
    def load(self,param, inplace = False):
        """
        Update parameters of set from dict param
        """
        if inplace:
            s = self
        else:
            s = copy.deepcopy(self)
            
        for key in param:
            
            if key in vasp_keys:
                s.set_vaspp(key, param[key])

            elif key == 'set_potential':
                for key2 in param[key]:
                    # print key2, 'key2'
                    s.set_potential(key2, param[key][key2])

            elif key == 'add_nbands':
                # print param[key]

                s.set_add_nbands(param[key])

            elif key == 'ngkpt':
                s.set_ngkpt(param[key])


            elif key == 'bfolder':
                print_and_log( 'New blockfolder', param[key])

            elif key in siman_keys:
                s.set_attrp(key, param[key] )
            
            else:
                print_and_log('Error! Uknown key: '+key)
                raise RuntimeError
         

            if key == 'set_sequence':
                sets = []
                for se in s.set_sequence:
                    sets.append(copy.deepcopy(header.varset[se]))

                s.set_sequence = sets  #put objects instead of names

            # if hasattr(s, 'set_sequence') and s.set_sequence:
            #     sets = []
            #     for se in s.set_sequence:
            #         if type(se) == str:
            #             sets.append(copy.deepcopy(varset[se]))
            #         else:
            #             sets.append(copy.deepcopy(se))

            #     s.set_sequence = sets  #put objects instead of names
        return s
Exemple #10
0
def determine_unique_final(st_pores, sums, avds, x_m):

    final_table = []
    insert_positions = []
    """Please determine unique positions with similar distances taking into acc PBC!!!
    below is incorrect
    """
    # crude_prec = 1
    # sums_crude = np.unique(sums.round(crude_prec))
    # print_and_log('The unique voids based on the sums:',
    #     '\nwith 0.01 A prec:',np.unique(sums.round(2)),
    #     '\nwith 0.1  A prec:',sums_crude,
    #     imp ='y')
    # print_and_log('Based on crude criteria only', len(sums_crude),'types of void are relevant', imp = 'y')

    # xcart_unique = []
    # avds_unique  = []
    # sums_unique  = []

    # for i, s in enumerate(sums_crude):
    #     index_of_first =  np.where(sums.round(crude_prec)==s)[0][0]
    #     xcart_unique.append(st_pores.xcart[index_of_first])
    #     avds_unique.append(avds[index_of_first] )
    #     sums_unique.append(sums[index_of_first] )

    # st_pores_unique = copy.deepcopy(st_pores)

    # st_pores_unique.xcart = xcart_unique
    # st_pores_unique.xcart2xred()

    sur = local_surrounding(x_m,
                            st_pores,
                            n_neighbours=len(st_pores.xcart),
                            control='atoms',
                            periodic=True)

    # print('neb.determine_unique_final(): sur',  sur)

    print_and_log('I can suggest you ' + str(len(sur[0])) + ' end positions.',
                  imp='y')

    for i, (x, d, ind) in enumerate(zip(sur[0], sur[3], sur[2])):
        # if i == 0:
        #     continue
        final_table.append(
            [i, np.array(x).round(2),
             round(d, 2), avds[ind], sums[ind]])

    print_and_log(tabulate(final_table,
                           headers=['void #', 'Cart.', 'Dist', 'Dev.', 'Sum'],
                           tablefmt='psql'),
                  imp='Y')

    return sur
Exemple #11
0
def makedir(path):
    """
    *path* - path to some file 
    Make dirname(path) directory if it does not exist
    """
    dirname = os.path.dirname(path)

    if dirname and not os.path.exists(dirname):
        os.makedirs(dirname)
        print_and_log("Directory", dirname, " was created", imp = 'y')
    return
Exemple #12
0
 def set_ngkpt(self,arg):
     if not is_list_like(arg):
         printlog("Error! set_ngkpt type error")
     old = copy.copy(self.ngkpt)     
     self.ngkpt = copy.copy(arg)
     self.kpoints_file = True
     self.vasp_params['KSPACING'] = None
     if old == arg:
         print_and_log( "Warning! You did not change one of your parameters in new set", imp = 'y')
         return
     self.history += "ngkpt was changed from "+str(old)+" to "+str(arg) + " and KPOINTS file was swithed on\n"
     return
Exemple #13
0
 def set_ngkpt(self,arg):
     if type(arg) is not tuple:
         sys.exit("\nset_ngkpt type error\n")
     old = copy.copy(self.ngkpt)     
     self.ngkpt = copy.copy(arg)
     self.kpoints_file = True
     self.vasp_params['KSPACING'] = None
     if old == arg:
         print_and_log( "Warning! You did not change one of your parameters in new set", imp = 'y')
         return
     self.history += "ngkpt was changed from "+str(old)+" to "+str(arg) + " and KPOINTS file was swithed on\n"
     return
Exemple #14
0
 def set_add_nbands(self,arg):
     name = "add_nbands"  
     if type(arg) not in [float, int ]:
         raise TypeError
     try: self.add_nbands
     except AttributeError: self.add_nbands = 1.
     old = self.add_nbands    
     self.add_nbands = arg
     if old == arg:
         print_and_log("Warning! You did not change  "+name+"  in "+self.ise+" set\n")
         return
     self.history += " "+name+"  was changed from "+str(old)+" to "+str(arg) + "\n"
     print_and_log(" "+name+"  was changed from "+str(old)+" to "+str(arg) + " in set "+self.ise+" \n")
     return
Exemple #15
0
 def add_conv_tsmear(self,arg):
     if type(arg) is not str:
         sys.exit("\nadd_conv_tsmear type error\n")
     try:
         self.conv_tsmear[0]
     except AttributeError:
         print_and_log( "Error! Set "+self.ise+" does not have conv_tsmear, I create new\n")
         self.conv_tsmear = []
     if arg in self.conv_tsmear:
         print_and_log( "Warning! You already have this name in list", imp = 'y')
         return    
     self.conv_tsmear.append(arg)
     self.history += "Name "+arg+" was added to self.conv_tsmear\n"
     self.update()
Exemple #16
0
 def add_conv_tsmear(self,arg):
     if type(arg) is not str:
         sys.exit("\nadd_conv_tsmear type error\n")
     try:
         self.conv_tsmear[0]
     except AttributeError:
         print_and_log( "Error! Set "+self.ise+" does not have conv_tsmear, I create new\n")
         self.conv_tsmear = []
     if arg in self.conv_tsmear:
         print_and_log( "Warning! You already have this name in list", imp = 'y')
         return    
     self.conv_tsmear.append(arg)
     self.history += "Name "+arg+" was added to self.conv_tsmear\n"
     self.update()
Exemple #17
0
 def set_add_nbands(self,arg):
     name = "add_nbands"  
     if type(arg) not in [float, int ]:
         raise TypeError
     try: self.add_nbands
     except AttributeError: self.add_nbands = 1.
     old = self.add_nbands    
     self.add_nbands = arg
     if old == arg:
         print_and_log("Warning! You did not change  "+name+"  in "+self.ise+" set\n")
         return
     self.history += " "+name+"  was changed from "+str(old)+" to "+str(arg) + "\n"
     print_and_log(" "+name+"  was changed from "+str(old)+" to "+str(arg) + " in set "+self.ise+" \n")
     return
Exemple #18
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)
            print_and_log( 'Saving file ...',path_to_images+str(image_name)+'.png', imp = 'y' )
            plt.savefig(path_to_images+str(image_name)+'.png',format='png', dpi = 300)
        return fit_func2  
Exemple #19
0
    def set_potential(self,znucl, arg):
        # print arg
        if type(arg) not in (str,):
            # sys.exit("\nset_potential error\n")
            raise RuntimeError

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

        # self.update()
        return
Exemple #20
0
def gb_energy_volume(gb,bulk):
    if (gb.end.rprimd[1] != bulk.end.rprimd[1]).any() or (gb.end.rprimd[2] != bulk.end.rprimd[2]).any():
        print_and_log("Warning! You are trying to calculate gb_energy from cells with different lateral sizes:"+str(gb.end.rprimd)+" "+str(bulk.end.rprimd)+"\n")
    #print bulk.vol
    V_1at = bulk.vol / bulk.natom #* to_ang**3

    E_1at = bulk.energy_sigma0 / bulk.natom 
    A = np.linalg.norm( np.cross(gb.end.rprimd[1], gb.end.rprimd[2])  ) #surface area of gb
    #print A
    gb.v_gb =      ( gb.vol              - V_1at * gb.natom) / A / 2. * 1000
    gb.e_gb =      ( gb.energy_sigma0    - E_1at * gb.natom) / A / 2. * eV_A_to_J_m * 1000
    gb.e_gb_init = ( gb.list_e_sigma0[0] - E_1at * gb.natom) / A / 2. * eV_A_to_J_m * 1000
    gb.bulk_extpress = bulk.extpress     
    #print "Calc %s; e_gb_init = %.3f J/m^2; e_gb = %.3f J/m; v_gb = %.3f angstrom "%(gb.name, gb.e_gb_init, gb.e_gb, gb.v_gb )
    outst = "%15s&%7.0f&%7.0f"%(gb.name, gb.e_gb, gb.v_gb)
    return outst
Exemple #21
0
def calc_ac(a1, c1, a2, c2, a_b = 0.1, c_b = 0.1, type = "two_atoms"):
    """
    Calculate values of hexagonal lattice parameters for cell with two different atoms.
    The used assumption is:
    1. Provided lattice constants are for large enougth cells, in which excess volume (dV) of impurity does not depend on the size of cell.
    2. Two atoms do not interact with each other, which allows to use dV(CO) = dV(C) + dV(O)
    
    Two regimes:
    two_atoms - calculate cell sizes if additional atom was added
    double_cell - if cell was doubled; only first cell and second_cell are needed


    Input:
    a1, c1 - lattice constants of cell with first impurity atom (first cell)
    a2, c2 - lattice constants of cell with second impurity atom (second cell)
    a_b, c_b - lattice constants of cell with pure hexagonal metall
    
    Output:
    a, c - lattice constants of cell with two atoms
    """
    hstring = ("%s    #on %s"% (traceback.extract_stack(None, 2)[0][3],   datetime.date.today() ) )
    if hstring != header.history[-1]: header.history.append( hstring  )
    
    A = (a1**2 * c1) + (a2**2 * c2) - (a_b**2 * c_b)
    B = 0.5 * (c1/a1 + c2/a2)
    C = ( (a1**2 * c1) + (a2**2 * c2) ) * 0.5 #sum of cell volumes divided by 2 since during the construction of new cell we will use multiplication by 2
    # print "A,B=",A,B
    a = (A/B)**(1./3)
    c = a * B
    a = round(a,5)
    c = round(c,5)
    print_and_log( "a, c, c/a for cell with pure    hcp ", a_b, c_b, round(c_b/a_b,4), imp ='y' )
    print_and_log( "a, c, c/a for cell with first  atom ", a1, c1, round(c1/a1,4), imp ='y' )
    print_and_log( "a, c, c/a for cell with second atom ", a2, c2, round(c2/a2,4), imp ='y' )

    #for double cell
    a3 = (C/B)**(1./3)
    c3 = a3 * B
    a3 = round(a3,5)
    c3 = round(c3,5)    

    if type == "two_atoms":
        print_and_log( "a, c, c/a for cell with two   atoms ", a,  c, round(c/a,4), "# the same cell but with two atoms\n", imp ='y')
    elif type == "double_cell":
        print_and_log( "a, c, c/a for new cell              ", a3,  c3, round(c3/a3,4), "# for cell with V = V(first_cell) + V(second cell), but only for the case if V(second cell) == V(first_cell)", imp ='y')

    return a, c
Exemple #22
0
def calculate_voronoi(self, state = 'end'):
    # By default two quantities per atom are calculated by this compute. 
    # The first is the volume of the Voronoi cell around each atom. 
    # Any point in an atom's Voronoi cell is closer to that atom than any other. 
    # The second is the number of faces of the Voronoi cell, which 
    # is also the number of nearest neighbors of the atom in the middle of the cell. 
    # state - init or end; if init then saved in self.init.vorovol; if end than saved in self.vorovol

    write_lammps(self, state, filepath = 'voronoi_analysis/structure.lammps') #write structure for lammps
    runBash("rm voronoi_analysis/dump.voro; /home/aksenov/installed/lammps-1Feb14/src/lmp_serial < voronoi_analysis/voronoi.in > voronoi_analysis/log")

    if state == 'end':
        self.vorovol = []
        self.vorofaces = []
        vorovol = self.vorovol
        vorofaces = self.vorofaces
    elif state == 'init':
        self.init.vorovol = []
        self.init.vorofaces = []
        vorovol = self.init.vorovol
        vorofaces = self.init.vorofaces        

    vsum=0
    wlist = []    
    with open('voronoi_analysis/dump.voro','r') as volfile:  #analyze dump.voro
        for line in volfile:
            if 'ITEM: ATOMS ' in line:
                break
        for line in volfile:
            ll = line.split()
            if int(ll[1]) > 1:
                wlist.append( [ll[0], ll[5], ll[6], ll[2]] )
            # print 'Volume of atom ',ll[0],'is', ll[5]
            vsum= vsum+float(ll[5])
        print_and_log( 'Check total volume ', vsum, self.end.vol)

        wlist.sort(key = itemgetter(0)) #sort according to the position of atoms
        print_and_log( "atom #, voronoi vol, voronoi faces, x coordinate: ", )
        print_and_log( wlist)
        for w in wlist:
            vorovol.append(float(w[1]))
            vorofaces.append(int(w[2]))
        # print 'Voro vol  ',self.end.vorovol
        # print 'Voro faces',self.end.vorofaces
        # print len(wlist)
    if hasattr(self, 'vorovol'): 
        voro = ''
        if len(vorovol) == 2: #C and O
            voro = " {0:5.2f} & {1:2d} & {2:5.2f} & {3:2d} ".format(vorovol[0], vorofaces[0], vorovol[1], vorofaces[1]  ).center(25)
        else: 
            voro = " {0:5.2f} & {1:2d} ".format(vorovol[0], vorofaces[0] ).center(25)
        voro+='&'
    else:
        voro = ""
    print_and_log( "Voronoi volume = ", voro, imp = 'y')
    return voro
Exemple #23
0
def determine_voids(st, r_impurity, fine=1, step_dec=0.05):

    if not r_impurity:
        printlog('add_neb(): Error!, Please provide *r_impurity* (1.6 A?)')

    sums = []
    avds = []
    printlog('Searching for voids', important='y')
    st_pores = find_pores(st,
                          r_matrix=0.5,
                          r_impurity=r_impurity,
                          step_dec=step_dec,
                          fine=fine,
                          calctype='all_pores')

    printlog('List of found voids:\n', np.array(st_pores.xcart))
    write_xyz(st.add_atoms(st_pores.xcart, 'H'),
              file_name=st.name + '_possible_positions')
    write_xyz(st.add_atoms(st_pores.xcart, 'H'),
              replications=(2, 2, 2),
              file_name=st.name + '_possible_positions_replicated')

    for x in st_pores.xcart:
        # summ = local_surrounding(x, st, n_neighbours = 6, control = 'sum', periodic  = True)
        # avd = local_surrounding(x, st, n_neighbours = 6, control = 'av_dev', periodic  = True)
        summ, avd = local_surrounding2(x,
                                       st,
                                       n_neighbours=6,
                                       control='sum_av_dev',
                                       periodic=True)
        # print (summ, avd)

        sums.append(summ)
        avds.append(avd[0])
    # print
    sums = np.array(sums)
    avds = np.array(avds).round(0)

    print_and_log(
        'Sum of distances to 6 neighboring atoms for each void (A):\n',
        sums,
        imp='y')
    print_and_log('Distortion of voids (0 - is symmetrical):\n', avds, imp='y')

    return st_pores, sums, avds
Exemple #24
0
def element_name_inv(el):
    el_dict = header.el_dict
    nu_dict = header.nu_dict
    # print type(el), el, type(str('sdf') )
    if is_string_like(el):
        try:
            elinv = el_dict[el]
        except:
            print_and_log("Error! Unknown element: " + str(el))
            raise RuntimeError
    else:
        el = int(el)
        try:
            elinv = nu_dict[el]
        except:
            print_and_log("Error! Unknown element: " + str(el))
            raise RuntimeError

    return elinv  # inversed notion of element
Exemple #25
0
def element_name_inv(el):
    el_dict = {'octa':200, 'n':0, 'H':1, 'He':2, 'Li':3, 'Be':4, 'B':5, 'C':6, 'N':7, 'O':8, 'F':9, 'Ne':10, 'Na':11, 'Mg':12, 'Al':13, 'Si':14, 'P':15, 'S':16, 'Cl':17, 'Ar':18, 'K':19, 'Ca':20, 'Sc':21, 'Ti':22, 'V':23, 'Cr':24, 'Mn':25, 'Fe':26, 'Co':27, 'Ni':28, 'Cu':29, 'Zn':30, 'Ga':31, 'Ge':32, 'As':33, 'Se':34, 'Br':35, 'Kr':36, 'Rb':37, 'Sr':38, 'Y':39, 'Zr':40, 'Nb':41, 'Mo':42, 'Tc':43, 'Ru':44, 'Rh':45, 'Pd':46, 'Ag':47, 'Cd':48, 'In':49, 'Sn':50, 'Sb':51, 'Te':52, 'I':53, 'Xe':54, 'Cs':55, 'Ba':56, 'La':57, 'Ce':58, 'Pr':59, 'Nd':60, 'Pm':61, 'Sm':62, 'Eu':63, 'Gd':64, 'Tb':65, 'Dy':66, 'Ho':67, 'Er':68, 'Tm':69, 'Yb':70, 'Lu':71, 'Hf':72, 'Ta':73, 'W':74, 'Re':75, 'Os':76, 'Ir':77, 'Pt':78, 'Au':79, 'Hg':80, 'Tl':81, 'Pb':82, 'Bi':83, 'Po':84, 'At':85, 'Rn':86, 'Fr':87, 'Ra':88, 'Ac':89, 'Th':90, 'Pa':91, 'U':92, 'Np':93, 'Pu':94, 'Am':95, 'Cm':96, 'Bk':97, 'Cf':98, 'Es':99, 'Fm':100, 'Md':101, 'No':102, 'Lr':103, 'Rf':104, 'Db':105, 'Sg':106, 'Bh':107, 'Hs':108, 'Mt':109, 'Ds':110, 'Rg':111, 'Cn':112, 'Uuq':114, 'Uuh':116, }
    nu_dict = { 200:'octa', 0:'n', 1:'H', 2:'He', 3:'Li', 4:'Be', 5:'B', 6:'C', 7:'N', 8:'O', 9:'F', 10:'Ne', 11:'Na', 12:'Mg', 13:'Al', 14:'Si', 15:'P', 16:'S', 17:'Cl', 18:'Ar', 19:'K', 20:'Ca', 21:'Sc', 22:'Ti', 23:'V', 24:'Cr', 25:'Mn', 26:'Fe', 27:'Co', 28:'Ni', 29:'Cu', 30:'Zn', 31:'Ga', 32:'Ge', 33:'As', 34:'Se', 35:'Br', 36:'Kr', 37:'Rb', 38:'Sr', 39:'Y', 40:'Zr', 41:'Nb', 42:'Mo', 43:'Tc', 44:'Ru', 45:'Rh', 46:'Pd', 47:'Ag', 48:'Cd', 49:'In', 50:'Sn', 51:'Sb', 52:'Te', 53:'I', 54:'Xe', 55:'Cs', 56:'Ba', 57:'La', 58:'Ce', 59:'Pr', 60:'Nd', 61:'Pm', 62:'Sm', 63:'Eu', 64:'Gd', 65:'Tb', 66:'Dy', 67:'Ho', 68:'Er', 69:'Tm', 70:'Yb', 71:'Lu', 72:'Hf', 73:'Ta', 74:'W', 75:'Re', 76:'Os', 77:'Ir', 78:'Pt', 79:'Au', 80:'Hg', 81:'Tl', 82:'Pb', 83:'Bi', 84:'Po', 85:'At', 86:'Rn', 87:'Fr', 88:'Ra', 89:'Ac', 90:'Th', 91:'Pa', 92:'U', 93:'Np', 94:'Pu', 95:'Am', 96:'Cm', 97:'Bk', 98:'Cf', 99:'Es', 100:'Fm', 101:'Md', 102:'No', 103:'Lr', 104:'Rf', 105:'Db', 106:'Sg', 107:'Bh', 108:'Hs', 109:'Mt', 110:'Ds', 111:'Rg', 112:'Cn', 114:'Uuq', 116:'Uuh', }
  
    # print type(el), el, type(str('sdf') )
    if is_string_like(el):
        try: 
            elinv = el_dict[el]
        except:
            print_and_log("Error! Unknown element: " +str(el))
            raise RuntimeError
    else:
        el = int(el)
        try:
            elinv = nu_dict[el]
        except:
            print_and_log("Error! Unknown element: "+str(el))
            raise RuntimeError

    return elinv # inversed notion of element
Exemple #26
0
def determine_unique_voids(st_pores, sums, avds):
    crude_prec = 1
    sums_crude = np.unique(sums.round(crude_prec))
    print_and_log('The unique voids based on the sums:',
                  '\nwith 0.01 A prec:',
                  np.unique(sums.round(2)),
                  '\nwith 0.1  A prec:',
                  sums_crude,
                  imp='y')
    print_and_log('Based on crude criteria only',
                  len(sums_crude),
                  'types of void are relevant',
                  imp='y')

    insert_positions = []
    start_table = []
    for i, s in enumerate(sums_crude):
        index_of_first = np.where(sums.round(crude_prec) == s)[0][0]

        start_table.append([
            i, st_pores.xcart[index_of_first].round(2), index_of_first,
            avds[index_of_first], sums[index_of_first]
        ])

        insert_positions.append(st_pores.xcart[index_of_first])

    print_and_log(tabulate(start_table,
                           headers=['void #', 'Cart.', 'Index', 'Dev.', 'Sum'],
                           tablefmt='psql'),
                  imp='Y')

    return insert_positions
Exemple #27
0
def gb_energy_volume(gb, bulk):
    if (gb.end.rprimd[1] != bulk.end.rprimd[1]).any() or (
            gb.end.rprimd[2] != bulk.end.rprimd[2]).any():
        print_and_log(
            "Warning! You are trying to calculate gb_energy from cells with different lateral sizes:"
            + str(gb.end.rprimd) + " " + str(bulk.end.rprimd) + "\n")
    #print bulk.vol
    V_1at = bulk.vol / bulk.natom  #* to_ang**3

    E_1at = bulk.energy_sigma0 / bulk.natom
    A = np.linalg.norm(np.cross(gb.end.rprimd[1],
                                gb.end.rprimd[2]))  #surface area of gb
    #print A
    gb.v_gb = (gb.vol - V_1at * gb.natom) / A / 2. * 1000
    gb.e_gb = (gb.energy_sigma0 -
               E_1at * gb.natom) / A / 2. * eV_A_to_J_m * 1000
    gb.e_gb_init = (gb.list_e_sigma0[0] -
                    E_1at * gb.natom) / A / 2. * eV_A_to_J_m * 1000
    gb.bulk_extpress = bulk.extpress
    #print "Calc %s; e_gb_init = %.3f J/m^2; e_gb = %.3f J/m; v_gb = %.3f angstrom "%(gb.name, gb.e_gb_init, gb.e_gb, gb.v_gb )
    outst = "%15s&%7.0f&%7.0f" % (gb.name, gb.e_gb, gb.v_gb)
    return outst
Exemple #28
0
    def set_potential(self,znucl, arg = ''):
        # print arg
        
        if not arg:
            arg = header.PATH2POTENTIALS+'/'+invert(znucl)
            printlog('Attention!, Default potentials is chosen from ',header.PATH2POTENTIALS, 'for',invert(znucl) , imp ='Y')

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



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

        # self.update()
        return
Exemple #29
0
def read_vectors(token, number_of_vectors, list_of_words):
    """Returns the list of numpy vectors for the last match"""

    number_of_matches = list_of_words.count( token )
    if number_of_matches == 0: 
        #print_and_log("Warning token '"+token+"' was not found! return empty\n")
        return [None]

    if number_of_matches > 1:
        print_and_log("Warning token '"+token+"' was found more than one times\n")
        raise RuntimeError


    index = list_of_words.index(token, number_of_matches - 1 )     #Return the index of the last match
    #print list_of_words[index]
    list_of_vectors = []
    vector = np.zeros((3))
    for i in range(number_of_vectors):
        vector[0] = float(list_of_words[index + 1])
        vector[1] = float(list_of_words[index + 2])
        vector[2] = float(list_of_words[index + 3])
        index+=3
        list_of_vectors.append(vector.copy())
    return list_of_vectors
Exemple #30
0
def push_figure_to_archive(local_figure_path,
                           caption,
                           figlabel=None,
                           autocompl=True):
    shutil.copy(local_figure_path, header.path_to_images)
    print_and_log('push_figure_to_archive():',
                  local_figure_path,
                  'copied to',
                  header.path_to_images,
                  imp='y')

    name_without_ext = '.'.join(
        os.path.basename(local_figure_path).split('.')[:-1])
    figfile = '{{' + name_without_ext + '}}'

    if not figlabel:
        figlabel = '.'.join(name_without_ext.split('.')[:-1])

    if autocompl:
        caption += ' for ' + figlabel

    tex_text = \
    ("\\begin{{figure}} \n\includegraphics[width=\columnwidth]{{{:s}}}\n"
    "\caption{{\label{{fig:{:s}}} {:s} }}\n"
    "\end{{figure}}\n").format(figfile, figlabel, caption )

    # print (tex_text)
    with open(header.project_conf.path_to_paper + '/auto_fig.tex',
              'a+',
              newline='') as f:
        f.seek(0)
        a = f.read()
        # print (a)
        if tex_text not in a:
            f.write(tex_text)
    return
Exemple #31
0
def inherit_iset(ise_new, ise_from, varset, override = False, newblockfolder = None):
    """ Create new set copying from existing and update some fields. If ise_from does not exist create new"""

    ise_new = ise_new.strip()
    ise_from = ise_from.strip()

    if ise_from not in varset:
        print_and_log( "\nError! Set "+ise_from+" does not exist. I return new empty set\n")
        return InputSet(ise_new)

    old = varset[ise_from]

    for key in vasp_electronic_keys+vasp_ionic_keys+vasp_other_keys: #check if new keys was added
        if key not in old.vasp_params: 
            old.vasp_params[key] = None 

    if override:
        print_and_log( "\nAttention! You have chosen to override set "+ise_new+"\n")
    elif ise_new in varset:
        print_and_log( "\nSet "+ise_new+" already exists. I return it without changes. Be carefull not to spoil it\n")
        return varset[ise_new]           



    new = copy.deepcopy( old )
    new.ise = ise_new
    new.compare_with = ise_from+" "
    new.des = "no description for these set, see history"
    new.conv = {}

    print_and_log( "New set "+ise_new+" was inherited from set "+ise_from+"\n")
    new.history = old.history + "\nSet "+ise_new+" was inherited from: "+ ise_from +"\n"

    if newblockfolder:
        new.history += 'blockfolder changed from '+new.blockfolder+' to '+newblockfolder+'\n'
        new.blockfolder = newblockfolder
    
    varset[ise_new] = new
    

    return new
Exemple #32
0
def inherit_iset(ise_new, ise_from, varset, override = False, newblockfolder = None):
    """ Create new set copying from existing and update some fields. If ise_from does not exist create new"""

    ise_new = ise_new.strip()
    ise_from = ise_from.strip()

    if ise_from not in varset:
        print_and_log( "\nError! Set "+ise_from+" does not exist. I return new empty set\n")
        return InputSet(ise_new)

    old = varset[ise_from]

    for key in vasp_electronic_keys+vasp_ionic_keys+vasp_other_keys: #check if new keys was added
        if key not in old.vasp_params: 
            old.vasp_params[key] = None 

    if override:
        print_and_log( "\nAttention! You have chosen to override set "+ise_new+"\n")
    elif ise_new in varset:
        print_and_log( "\nSet "+ise_new+" already exists. I return it without changes. Be carefull not to spoil it\n")
        return varset[ise_new]           



    new = copy.deepcopy( old )
    new.ise = ise_new
    new.compare_with = ise_from+" "
    new.des = "no description for these set, see history"
    new.conv = {}

    print_and_log( "New set "+ise_new+" was inherited from set "+ise_from+"\n")
    new.history = old.history + "\nSet "+ise_new+" was inherited from: "+ ise_from +"\n"

    if newblockfolder:
        new.history += 'blockfolder changed from '+new.blockfolder+' to '+newblockfolder+'\n'
        new.blockfolder = newblockfolder
    
    varset[ise_new] = new
    

    return new
Exemple #33
0
 def add_conv(self,arg,type_of_conv):
     if type(arg) is not str:
         raise TypeError
     if type_of_conv not in ["kpoint_conv","tsmear_conv","ecut_conv","nband_conv","npar_conv"]:
         raise TypeError
     try:
         self.conv[type_of_conv][0]
     except AttributeError:
         print_and_log( "Warning! Set "+self.ise+" does not have conv, I create new\n")
         self.conv = {}
     except KeyError:
         print_and_log( "Warning! Set "+self.ise+" does not have list for this key in conv, I add new\n")
         self.conv[type_of_conv] = []
     except IndexError:
         pass
     if arg in self.conv[type_of_conv]:
         print_and_log( "Warning! You already have name %s in list of conv %s. Nothing done.\n" % \
         (str(arg), str(self.conv[type_of_conv])    ) )
         return    
     self.conv[type_of_conv].append(arg)
     self.history += "Name "+arg+" was added to self.conv["+type_of_conv+"]\n"
     print_and_log( "Name "+arg+" was added to self.conv["+type_of_conv+"] of set "+self.ise+" \n")
     self.update()
Exemple #34
0
 def add_conv(self,arg,type_of_conv):
     if type(arg) is not str:
         raise TypeError
     if type_of_conv not in ["kpoint_conv","tsmear_conv","ecut_conv","nband_conv","npar_conv"]:
         raise TypeError
     try:
         self.conv[type_of_conv][0]
     except AttributeError:
         print_and_log( "Warning! Set "+self.ise+" does not have conv, I create new\n")
         self.conv = {}
     except KeyError:
         print_and_log( "Warning! Set "+self.ise+" does not have list for this key in conv, I add new\n")
         self.conv[type_of_conv] = []
     except IndexError:
         pass
     if arg in self.conv[type_of_conv]:
         print_and_log( "Warning! You already have name %s in list of conv %s. Nothing done.\n" % \
         (str(arg), str(self.conv[type_of_conv])    ) )
         return    
     self.conv[type_of_conv].append(arg)
     self.history += "Name "+arg+" was added to self.conv["+type_of_conv+"]\n"
     print_and_log( "Name "+arg+" was added to self.conv["+type_of_conv+"] of set "+self.ise+" \n")
     self.update()
Exemple #35
0
    def test_adding_of_impurities(added, init, v):
        """
        Can be used only inside add_impurity()
        Replicates the structure and find again pores
        """
        global natoms_v1
        if added == None: return
        if v == 1:  #TEST

            natoms_v1 = len(added.init.xcart)  # for test
            st_rep_after = added.init.replic((1, 2, 1))

            rep = copy.deepcopy(init)

            rep.init = rep.init.replic((1, 2, 1))
            #print rep
            rep = add(znucl, "", rep, write_geo=False)
            #print rep
            #print "xcart of replic after adding ", st_rep_after.xcart
            #print "xcart of adding to    replic ", rep.init.xcart
            if len(st_rep_after.xcart) != len(rep.init.xcart):
                raise RuntimeError
            p = 0
            #for x2 in st_rep_after.xcart:
            #    print x2
            for x in rep.init.xcart:
                a = any((np.around(x2, p) == np.around(x, p)).all()
                        for x2 in st_rep_after.xcart)
                #b = any(  ( np.ceil(x2, p)   == np.ceil(x, p)  ).all()  for x2 in st_rep_after.xcart   )
                #c = any(  ( np.floor(x2, p)  == np.floor(x, p) ).all()  for x2 in st_rep_after.xcart   )
                #print a, b, c
                #np.concatenate(a, b, c):
                if not a:
                    print_and_log("Error! Can't find ", np.around(x, 3),
                                  "in replic  ")
                    raise RuntimeError

            #assert all([ all( np.around(v1, 8) == np.around(v2, 8) ) for (v1, v2) in zip(st_rep_after.xcart, rep.init.xcart) ])
            print_and_log("add_impurity: test succesfully done")

        if natoms_v1 != len(added.init.xcart):
            print_and_log(
                "You have different number of pores in different versions\n")
            raise RuntimeError
        return
Exemple #36
0
    def set_attrp(self, token, arg, des = "see manual"):
        """
        set any attribute.

        """
        # print token
        if hasattr(self, token):
            old = getattr(self, token)
            if old == arg:
                print_and_log("Warning! You did not change  "+token+"  in "+self.ise+" set\n")
            else:
                setattr(self, token, arg)

                self.history += " "+token+"  was changed from "+str(old)+" to "+str(arg) + "\n"
                print_and_log(token+"  was changed from "+str(old)+" to "+str(arg) +" - "+ des+" in set "+self.ise+" \n")
        
        else:
            setattr(self, token, arg)
            print_and_log("New attribute  "+token+"  added to "+self.ise+" set\n")
            self.history += " "+token+"  was added as a new attr with "+str(arg) + " value \n"

        return
Exemple #37
0
    def test_adding_of_impurities(added, init, v):
        """
        Can be used only inside add_impurity()
        Replicates the structure and find again pores
        """
        global natoms_v1
        if added == None: return
        if v == 1: #TEST
            
            natoms_v1 = len(added.init.xcart) # for test 
            st_rep_after  = replic( added.init,      (1,2,1) )

            rep = copy.deepcopy(init)

            rep.init = replic( rep.init, (1,2,1) );   
            #print rep
            rep = add(znucl, "", rep, write_geo = False)
            #print rep
            #print "xcart of replic after adding ", st_rep_after.xcart
            #print "xcart of adding to    replic ", rep.init.xcart
            if len(st_rep_after.xcart) != len(rep.init.xcart): raise RuntimeError
            p = 0
            #for x2 in st_rep_after.xcart:
            #    print x2
            for x in rep.init.xcart:
                a = any(  ( np.around(x2, p) == np.around(x, p) ).all() for x2 in st_rep_after.xcart   )
                #b = any(  ( np.ceil(x2, p)   == np.ceil(x, p)  ).all()  for x2 in st_rep_after.xcart   )
                #c = any(  ( np.floor(x2, p)  == np.floor(x, p) ).all()  for x2 in st_rep_after.xcart   )
                #print a, b, c
                #np.concatenate(a, b, c):
                if not a:
                    print_and_log( "Error! Can't find ", np.around(x,3), "in replic  ")
                    raise RuntimeError

            #assert all([ all( np.around(v1, 8) == np.around(v2, 8) ) for (v1, v2) in zip(st_rep_after.xcart, rep.init.xcart) ])
            print_and_log( "add_impurity: test succesfully done")

        if natoms_v1 != len(added.init.xcart): print_and_log("You have different number of pores in different versions\n");  raise RuntimeError
        return
Exemple #38
0
    def set_attrp(self, token, arg, des = "see manual"):
        """
        set any attribute.

        """
        # print token
        if hasattr(self, token):
            old = getattr(self, token)
            if old == arg:
                print_and_log("Warning! You did not change  "+token+"  in "+self.ise+" set\n")
            else:
                setattr(self, token, arg)

                self.history += " "+token+"  was changed from "+str(old)+" to "+str(arg) + "\n"
                print_and_log(token+"  was changed from "+str(old)+" to "+str(arg) +" - "+ des+" in set "+self.ise+" \n")
        
        else:
            setattr(self, token, arg)
            print_and_log("New attribute  "+token+"  added to "+self.ise+" set\n")
            self.history += " "+token+"  was added as a new attr with "+str(arg) + " value \n"

        return
Exemple #39
0
def write_jmol(xyzfile, pngfile, scriptfile = None, atomselection = None, topview = False, orientation = None,
    axis = False, bonds = True, rprimd = None, shift = None, rotate = None,
    label = None, high_contrast = None, specialcommand = None,
    boundbox = 2):
    """
    atomselection - string in gmol format with number of atoms to be nrotateSelected
    topview - additional top view, requires two models in xyz
    orientation - additional rotation
    axis - add axes
    rotate - rotation of all atoms around view axis in degrees
    """
    if not scriptfile:
        scriptfile = os.getcwd()+'/'+'temporary_jmol_script'
    with open(scriptfile,'w') as f:
        f.write('set frank off\n') #no jmol label
        if bonds:
            f.write('set autobond on\n')

        else:
            f.write('set autobond off\n set bonds off\n')

        f.write('load "'+xyzfile+'"\n')

        f.write('select all \ncpk 250 \nwireframe 0.3\n') #250
        f.write('background white \nselect Ti* \ncolor [20,120,250] \nselect C* \ncolor [80,80,80]\n cpk 100\n')
        f.write('set perspectivedepth off\n')
        




        if boundbox:
            f.write('set boundbox ' +str(boundbox)+ ' \n')



        # f.write('set specular 85\n set specpower 85\n set diffuse 85\n')
        if high_contrast: #allows to make better view for black and white printing 
            f.write('set ambient 10 \nset specular 95\n set specpower 95\n set diffuse 95\n')



        
        if axis:
            f.write('set axes 10 \naxes scale 2.5 \n')
            f.write('axes labels "X" "Y" "Z" "" \n')
            f.write('color  axes  red \n')
            f.write('font axes 26 \n')


        if orientation:
            f.write(orientation+'\n')


        if atomselection:
            f.write('select '+atomselection+'\n')
            f.write('color purple    \n')

        if topview:
            f.write('select * /2  \ntranslateSelected 0 '+str(-rprimd[1][1]*shift)+' 0\nrotateSelected X 90\n')
        
            f.write('wireframe 0.1\ncpk 150\nmodel 0\n#zoom 60\n')



        if label:
            j = 1
            name_old = ''
            for i, el in enumerate(label):
                name  = el[0]+el[1]
                if name != name_old: j = 1
                label = str(j)+el[1]
                # print "label",label
                f.write('select '+el[0]+str(i+1)+'\ncpk 200\nset labeloffset 0 0\nset labelfront\ncolor label black\nlabel '+label+'\n font label 24 bold \n')
                j+=1
                name_old = name


        if rotate:
            f.write('rotate z '+str(rotate)+'\n')

        if specialcommand:
            f.write(specialcommand)

        
        # f.write('write image 2800 2800 png "'+pngfile+'"')
        f.write('write image 1800 1800 png "'+pngfile+'"')
    print_and_log( runBash(header.path_to_jmol+' -ions '+scriptfile) )
    # print runBash('convert '+pngfile+' -shave 0x5% -trim '+pngfile) #cut by 5% from up and down (shave) and that trim left background
    print_and_log( pngfile )
    print_and_log( runBash('convert '+pngfile+' -trim '+pngfile)  ) # trim background
    return
Exemple #40
0
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): 
        print_and_log( "Error! write_xyz: check your structure"    )
    
    if name == '': 
        name = 'noname'
    if xcart == [] or len(xcart) != len(xred):
        print_and_log( "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
Exemple #41
0
def write_xyz(st, path = None, repeat = 1, shift = 1.0,  gbpos2 = None, gbwidth = 1 , 
    imp_positions = [], specialcommand = None, analysis = None, show_around = None, replications = None, nnumber = 6, topview = True,
    filename = None, file_name = None, full_cell = False, orientation = None, boundbox = 2, withgb = False,
    include_boundary = 2, rotate = None, imp_sub_positions = None, jmol = None, show_around_x = None,
    ):
    """Writes st structure in xyz format in the folder xyz/path

    if repeat == 2: produces jmol script
    shift - 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 - type and xcart coordinates additionally to be added to structure; to visulaze all impurity positions: for jmol
    imp_sub_positions - list of atom numbers; the typat of these atoms is changed: not used now

    specialcommand - any command at the end of script

    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
        show_around_x - show atoms around point, has higher priority

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

    full_cell - returns atoms to cell and replicate boundary atoms

    jmol - 1,0 - allow to use jmol
    """
    if replications:
        st = replic(st, mul = replications, inv = 1 )
  
    def update_var():
        return st.rprimd, st.xcart, st.xred, st.typat, st.znucl, len(st.xred)

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


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



    if natom != len(xred) != len(xcart) != len(typat) or len(znucl) != max(typat): 
        print_and_log( "Error! write_xyz: check your arrays.\n\n"    )
    # print st.natom, len(st.xred), len(st.xcart), len(st.typat), len(st.znucl), max(st.typat)
    
    print_and_log("write_xyz(): Name is", name, important = 'n')
    if name == '': name = 'noname'


    if xcart == [] or len(xcart) != len(xred):
        print_and_log( "Warining! write_xyz: len(xcart) != len(xred) making xcart from xred.\n")
        xcart = xred2xcart(xred, rprimd)
        #print xcart[1]
    
    if path:
        basepath = path
    else:
        basepath = 'xyz/'



    xyzfile = os.path.join(basepath, name+".xyz")
    makedir(xyzfile)


    """Processing section"""


    if analysis == 'imp_surrounding':
        lxcart = []
        ltypat = []
        i=0
        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
            
            # 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)
                # print x_t[1]
                lxcart+=x_t[0]
                ltypat+=x_t[1]
            i+=1
        
        if show_around_x:
            x = show_around_x
            x_t = local_surrounding(x, st, nnumber, control = 'atoms', periodic = True)
            # print x_t[1]
            lxcart+=x_t[0]
            ltypat+=x_t[1]            


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



    """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()
        
    # asdegf

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

    #analyze imp_positions
    if imp_sub_positions == None:
        imp_sub_positions = []
    nsub = 0
    for pos in imp_positions:
        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 : 
        print_and_log( imp_sub_positions, ': numbers of found atoms to be changed ' )


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




    with open(xyzfile,'w') as f:
        for i in range(repeat):
            f.write(str(natom + len(imp_positions)-nsub + 3)+"\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] ) )

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


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


    if jmol:
        """
        script mode for jmol. Create script file as well for elobarate visualization
        """
        
        """Choose gb atoms to change their color"""
        print_and_log( '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)
            print_and_log( '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"
        pngfile = os.getcwd()+'/'+basepath+name+".png"
        
        print_and_log( 'imp_positions = ',imp_positions)
        write_jmol(xyzfile, pngfile, scriptfile, atomselection, topview = topview, rprimd =rprimd, shift = shift, label = [(pos[3], pos[4]) for pos in imp_positions], 
            specialcommand = specialcommand, orientation = orientation, boundbox =boundbox, rotate = rotate)


    return
def plot_conv(list_of_calculations=None,
              calc=None,
              type_of_plot=None,
              conv_ext=[],
              labelnames=None,
              cl=None,
              plot=1,
              filename=None):
    """
    Allows to fit and plot different properties;
    Input:
    'type_of_plot' - ("fit_gb_volume"-fits gb energies and volume and plot dependencies without relaxation and after it,
     'dimer'

    cl - calculation to use - new interface, please rewrite the old one

    """
    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

    if list_of_calculations:
        conv = list_of_calculations
        n = conv[0]

        name = []

        name.append(n[0])

        image_name = n[0] + '_' + n[1] + '_' + str(n[2])

    energies = []
    init_energies = []
    volumes = []
    gb_volumes = []
    pressures = []
    pressures_init = []
    sigma_xx = []
    sigma_yy = []
    sigma_zz = []
    e_gbs = []
    e_gbs_init = []

    if type_of_plot == "e_imp":
        e_imps = []
        v_imps = []
        lengths = []
        for id in conv:
            e_imps.append(calc[id].e_imp * 1000)
            v_imps.append(calc[id].v_imp)
            l = calc[id].vlength
            lengths.append("%s\n%.1f\n%.1f\n%.1f" % (id[0], l[0], l[1], l[2]))
        #l = lengths[0]
        #print str(l[0])+'\n'+str(l[1])+'\n'+str(l[2])

        xlabel = "Sizes, $\AA$"
        ylabel = "Impurity energy, meV"
        ylabel2 = "Impurity volume, $\AA^3$"
        plt.figure()
        plt.title(str(name) + ' other cells')
        plt.ylabel(ylabel)
        plt.xlabel(xlabel)
        x = range(len(e_imps))
        plt.xticks(x, lengths)
        plt.plot(x, e_imps, 'ro-', label='energy')
        plt.legend()
        plt.twinx()
        plt.ylabel(ylabel2)
        plt.plot(x, v_imps, 'bo-', label='volume')

        plt.subplots_adjust(left=None,
                            bottom=0.2,
                            right=None,
                            top=None,
                            wspace=None,
                            hspace=None)
        #plt.ticker.formatter.set_scientific(True)
        plt.legend(loc=9)
        plt.savefig('images/e_imp_' + str(image_name) + '.png',
                    format='png')  #+str(image_name))#+'e_imp')

    if type_of_plot == "e_2imp":

        def dist_between_imp(cl):
            """Only for two impurities"""

            return np.linalg.norm(
                cl.end.xcart[-1] - cl.end.xcart[-2]
            )  #assuming that impurities are at the end of xcart list.

        e_imps = []  # binding energy
        dist = []  #dist between impurities

        e_imps_ex = []
        dist_ex = []
        name_ex = []

        for id in conv:
            cl = calc[id]
            e_imps.append(cl.e_imp * 1000)
            #dist.append( "%s\n%.1f"%(id[0],dist_between_imp(cl) ) )
            dist.append(dist_between_imp(cl))

        xlabel = "Distance between atoms, $\AA$"
        ylabel = "Interaction energy, meV"
        plt.figure()

        # plt.title(str(name)+' v1-15')

        plt.ylabel(ylabel)
        plt.xlabel(xlabel)
        #x = range( len(e_imps) )
        #plt.xticks(x, dist)
        # plt.yscale('log')
        # plt.yscale('semilog')
        if labelnames:
            label = labelnames
        else:
            label = []
            label[0] = str(name)
            label[1] = name_ex[0]
            label[2] = name_ex[1]

        plt.plot(dist, e_imps, 'ro-', label=label[0], linewidth=2)

        if conv_ext:  #manually add
            for conv in conv_ext:
                e_imps_ex.append([])
                dist_ex.append([])
                for id in conv:
                    cl = calc[id]
                    e_imps_ex[-1].append(cl.e_imp * 1000)
                    #dist.append( "%s\n%.1f"%(id[0],dist_between_imp(cl) ) )
                    dist_ex[-1].append(dist_between_imp(cl))
                name_ex.append(id[0])
            plt.plot(dist_ex[0],
                     e_imps_ex[0],
                     'go-',
                     label=label[1],
                     linewidth=2)
            plt.plot(dist_ex[1],
                     e_imps_ex[1],
                     'bo-',
                     label=label[2],
                     linewidth=2)

        plt.axhline(color='k')  #horizontal line

        plt.tight_layout()

        # plt.subplots_adjust(left=None, bottom=0.2, right=None, top=None,
        #         wspace=None, hspace=None)
        # #plt.ticker.formatter.set_scientific(True)
        plt.legend(loc=9)
        plt.savefig(path_to_images + 'e_2imp_' + str(image_name) + '.png',
                    format='png',
                    dpi=300)  #+str(image_name))#+'e_imp')

    if type_of_plot == "fit_gb_volume_pressure":

        for id in conv:
            #energies.append(calc[id].energy_sigma0)
            #init_energies.append( calc[id].list_e_sigma0[0] )
            gb_volumes.append(calc[id].v_gb)
            #volumes.append(calc[id].end.vol)
            pressures.append(calc[id].extpress / 1000.)
            pressures_init.append(calc[id].extpress_init / 1000.)
            sigma_xx.append(calc[id].stress[0])
            sigma_yy.append(calc[id].stress[1])
            sigma_zz.append(calc[id].stress[2])
            #pressures_init = pressures
            e_gbs.append(calc[id].e_gb)
            e_gbs_init.append(calc[id].e_gb_init)
            # print calc[id].bulk_extpress

        power = 3

        fit_ve = fit_and_plot(gb_volumes, e_gbs_init, gb_volumes, e_gbs, power,
                              name, "Grain boundary expansion (m$\AA$)",
                              "Grain boundary energy (mJ/m$^2$)",
                              image_name + "_fit_ve")

        fit = fit_and_plot(pressures_init, e_gbs_init, pressures, e_gbs, power,
                           name, "External pressure (GPa)",
                           "Grain boundary  energy (mJ/m$^2$)",
                           image_name + "_pe")
        #print fit
        ext_p_min = fit.deriv().r[
            power -
            2]  #external pressure in the minimum; derivative of function and the value of x in minimum

        fit_sxe = fit_and_plot(sigma_xx, e_gbs_init, sigma_xx, e_gbs, power,
                               name, "Sigma xx (MPa)",
                               "Grain boundary energy (mJ/m$^2$)",
                               image_name + "_sxe")
        sxe_min = fit_sxe.deriv().r[power -
                                    2]  #sigma xx at the minimum of energy
        print_and_log("sigma xx at the minimum of energy is", sxe_min, " MPa")

        fit1 = fit_and_plot(pressures_init,
                            gb_volumes,
                            pressures,
                            gb_volumes,
                            1,
                            name,
                            "External pressure (GPa)",
                            "Grain boundary expansion (m$\AA$)",
                            image_name + "_pv",
                            lines='xy')
        #print fit1
        pulay = -calc[id].bulk_extpress
        #print " At external pressure of %.0f MPa; Pulay correction is %.0f MPa." % (ext_p_min+pulay, pulay)
        #print " Egb = %.1f mJ m-2; Vgb = %.0f mA;"%(fit(ext_p_min), fit1(ext_p_min)  )
        print_and_log("%s.fit.pe_pv & %.0f & %.0f & %0.f & %0.f \\\\" %
                      (n[0] + '.' + n[1], fit(ext_p_min), fit1(ext_p_min),
                       ext_p_min, ext_p_min + pulay))

        #print "\n At zero pressure with Pullay correction:"
        #print " Egb = %.1f mJ m-2; Vgb = %.0f mA; " % (fit(-pulay), fit1(-pulay))
        outstring = ("%s.fit.pe_pv & %.0f & %.0f & %0.f & %0.f\\\\" %
                     (n[0] + '.' + n[1], fit(-pulay), fit1(-pulay), -pulay, 0))
        # print outstring
        calc[conv[0]].egb = fit(-pulay)
        calc[conv[0]].vgb = fit1(-pulay)

        return outstring  #fit(ext_p_min), fit1(ext_p_min)

    if type_of_plot == "fit_gb_volume":
        """
        should be rewritten using fit_and_plot() function
        """

        for id in conv:
            #energies.append(calc[id].energy_sigma0)
            #init_energies.append( calc[id].list_e_sigma0[0] )
            gb_volumes.append(calc[id].v_gb)
            e_gbs.append(calc[id].e_gb)
            e_gbs_init.append(calc[id].e_gb_init)

        power = 3
        fit_ve = fit_and_plot(gb_volumes, e_gbs_init, gb_volumes, e_gbs, power,
                              name, "Excess volume ($m\AA$)",
                              "Twin energy ($mJ/m^2$)", image_name + "_fit_ve")

        vgb_min = fit_ve.deriv().r[power - 2]

        #print "Fit of excess volume against energy. Pressure is uknown:"
        #print "Test Egb_min = %.1f mJ m-2; v_min = %.0f mA;"%(fit_ve(vgb_min), vgb_min)
        print("%s.fit.ve & %.0f & %.0f & - & - \\\\" % (
            n[0] + '.' + n[1],
            fit_ve(vgb_min),
            vgb_min,
        ))

    if type_of_plot == "fit_gb_volume2":

        for id in conv:
            energies.append(calc[id].energy_sigma0)
            init_energies.append(calc[id].list_e_sigma0[0])
            volumes.append(calc[id].end.vol)
            pressures.append(calc[id].extpress)
            pressures_init.append(calc[id].extpress_init)

        power = 3
        pulay = 500

        fit_ve = fit_and_plot(volumes, init_energies, volumes, energies, power,
                              name, "Volume ($\AA^3$)",
                              "Energy  sigma->0 ($eV$)",
                              image_name + "_fit_ve")

        Vmin = fit_ve.deriv().r[power -
                                2]  # minimum volume at the minimum energy
        Emin = fit_ve(Vmin)

        fit_pe = fit_and_plot(pressures_init, init_energies, pressures,
                              energies, power, name,
                              "External pressure ($MPa$)",
                              "Energy  sigma->0 ($eV$)",
                              image_name + "_fit_pe")

        ext_p_min = fit_pe.deriv().r[
            power -
            2]  #external pressure in the minimum; derivative of function and the value of x in minimum

        fit_pv = fit_and_plot(pressures_init, volumes, pressures, volumes, 1,
                              name, "External pressure ($MPa$)",
                              "Volume of cell ($\AA^3$)",
                              image_name + "_fit_pv")



        atP = (" Emin = %.3f meV;  Vmin = %.0f A^3; "%( fit_pe(ext_p_min), fit_pv(ext_p_min)  )  ) + \
              (" for the minimum of energy relative to external pressure. The value of pressure is %.0f MPa; Pulay correction is %.0f MPa." % (ext_p_min+pulay, pulay) )

        at_zeroP = (" Emin = %.3f meV;  Vmin = %.0f A^3; " % (fit_pe(-pulay), fit_pv(-pulay) )  ) + \
                   (" the value of energy and volume at zero pressure with Pullay correction" )

        #print " Emin = %.3f meV;  Vmin = %.0f A^3;  for the minimum of energy relative to volume at some external pressure"%(fit_ve(Vmin), Vmin )
        #print atP
        #print at_zeroP

        print_and_log("Compare V at -pulay and V for energy minimum",
                      fit_pv(-pulay), Vmin)

        return fit_pe(-pulay), fit_pv(-pulay), Emin, Vmin

    if type_of_plot == "kpoint_conv":
        energies = []
        kpoints = []
        times = []

        for id in list_of_calculations:
            if "4" not in calc[id].state:
                continue
            energies.append(calc[id].potenergy)
            kpoints.append(calc[id].kspacing[2])
            times.append(calc[id].time)

            name.append(id[1])

        plt.figure()
        plt.title(name)
        plt.plot(kpoints, energies, 'bo-')
        plt.ylabel("Total energy (eV)")
        plt.xlabel("KSPACING along 3rd recip. vector ($\AA ^{-1}$)")
        plt.twinx()
        plt.plot(kpoints, times, 'ro-')
        plt.ylabel("Elapsed time (min)")
        plt.savefig('images/' + str(conv[0]) + 'kconv')

    if type_of_plot == "contour":
        alist = []
        clist = []
        nn = str(calc[conv[0]].id[0]) + "." + str(calc[conv[0]].id[1])
        f = open("a_c_convergence/" + nn + "/" + nn + ".out", "w")
        f.write("END DATASET(S)\n")
        k = 1
        for id in conv:  #Find lattice parameters and corresponding energies
            a = calc[id].a
            c = calc[id].c
            if a not in alist: alist.append(a)
            if c not in clist: clist.append(c)
            f.write("acell%i %f %f %f Bohr\n" %
                    (k, calc[id].a / to_ang, calc[id].a / to_ang,
                     calc[id].c / to_ang))
            #print "etotal%i %f\n"%(k, calc[id].energy_sigma0/to_eV ),
            k += 1
        X, Y = np.meshgrid(alist, clist)
        Z = np.zeros(X.shape)
        Zinv = np.zeros(X.shape)

        k = 1
        for i in range(len(alist)):
            for j in range(len(clist)):
                for id in conv:
                    if calc[id].a == alist[i] and calc[id].c == clist[j]:
                        Z[i][j] = calc[id].energy_sigma0
                        Zinv[j][i] = calc[id].energy_sigma0
                        f.write("etotal%i %f\n" %
                                (k, calc[id].energy_sigma0 / to_eV))
                        k += 1
        f.write(
            "+Overall time at end (sec) : cpu=     976300.2  wall=     976512.8"
        )
        f.close

        #Make two plots for different a and c
        plt.figure()
        plt.title(name)
        for i in range(len(alist)):
            plt.plot(clist, Z[i], 'o-', label='a=' + str(alist[i]))
        plt.legend()
        plt.ylabel("Total energy (eV)")
        plt.xlabel("c parameter ($\AA$)")
        plt.savefig('images/' + str(conv[0]) + 'c')

        plt.figure()
        plt.title(name)
        for j in range(len(clist)):
            plt.plot(alist, Zinv[j], 'o-', label='c=' + str(clist[j]))
        plt.legend()
        plt.ylabel("Total energy (eV)")
        plt.xlabel("a parameter ($\AA$)")
        plt.savefig('images/' + str(conv[0]) + 'a')

        #Make contour
        plt.figure()
        cf = plt.contourf(X, Y, Z, 20, cmap=plt.cm.jet)
        cbar = plt.colorbar(cf)
        cbar.ax.set_ylabel('Energy (eV)')

        plt.xlabel('$a$ ($\AA$)')
        plt.ylabel('$c/a$')

        plt.legend()
        plt.savefig('images/ru-contourf.png')
        #plt.show()

        #Make equation of state
        eos = EquationOfState(clist, Z[2])
        v0, e0, B = eos.fit()
        #print "a = ", alist[2]
        print_and_log('''
        v0 = {0} A^3
        E0 = {1} eV
        B  = {2} eV/A^3'''.format(v0, e0, B))
        eos.plot('images/a[2]-eos.png')

        eos = EquationOfState(alist, Zinv[2])
        v0, e0, B = eos.fit()
        #print "c = ", clist[2]
        print_and_log('''
        v0 = {0} A^3
        E0 = {1} eV
        B  = {2} eV/A^3'''.format(v0, e0, B))
        eos.plot('images/c[2]-eos.png')

    if type_of_plot == "dimer":

        if not cl:
            cl = calc[list_of_calculations[0]]

        x1 = []  #list of distances

        if cl.end.natom > 2:
            raise RuntimeError

        # print (cl.end.list_xcart)
        for xcart in cl.end.list_xcart:
            # x = xcart[1]
            # d = (x[0]**2 + x[1]**2 + x[2]**2)**0.5
            d = np.linalg.norm(xcart[1] -
                               xcart[0])  #assuming there are only two atoms
            print(xcart[0], xcart[1], d)

            x1.append(d)

        y1 = cl.list_e_without_entr
        power = 4
        name = 'dimer'
        xlabel = 'Bond length'
        ylabel = 'Full energy'
        # print(x1, y1)
        coeffs1 = np.polyfit(x1, y1, power)

        fit_func1 = np.poly1d(coeffs1)

        x_range = np.linspace(min(x1), max(x1))
        fit_y1 = fit_func1(x_range)
        f = fit_func1.deriv()
        min_e = fit_func1(f.r[2]).real
        printlog(
            "The minimum energy per atom and optimal length of dimer are {:.3f} eV and {:.3f} A"
            .format(min_e / 2., f.r[2].real),
            imp='Y')
        try:
            printlog(
                "The atomization energy for dimer is {:.3f} eV ; The energy of atom in box is taken from the provided b_id"
                .format(min_e - 2 * cl.e_ref),
                imp='Y')
        except:
            print('Reference energy was not found')
        plt.figure()
        plt.title(name)
        plt.ylabel(ylabel)
        plt.xlabel(xlabel)
        plt.plot(x1, y1, 'ro', label='init')
        plt.plot(x_range, fit_y1, 'r-', label='init_fit')

        if filename:
            path2saved, path2saved_png = process_fig_filename(
                filename, fig_format)

        if plot:
            plt.show()

    return
Exemple #43
0
def insert_cluster(insertion, i_center, matrix, m_center):
    """
    Take care of orientation; typat should be consistent
    Input:
    insertion -  object of class Structure(), which is supposed to be inserted in matrix
    in such a way that i_center will be combined with m_center.
    matrix - object of class Structure().
    i_center, m_center - numpy arrays (3).
    """
    ins = copy.deepcopy(insertion)
    mat = copy.deepcopy(matrix)
    r = mat.rprimd

    for i, z in enumerate(ins.znucl):
        if z not in mat.znucl:
            mat.znucl.append(z)
            mat.ntypat += 1
            mat.nznucl.append(ins.nznucl[i])

    hproj = [(r[0][i] + r[1][i] + r[2][i]) * 0.5
             for i in (0, 1, 2)]  #projection of vectors on three axis

    for i, x in enumerate(ins.xcart):
        ins.xcart[i] = x - i_center

    for i, x in enumerate(mat.xcart):
        mat.xcart[i] = x - m_center

    max_dis = 1
    for i_x, ix in enumerate(ins.xcart):
        dv_min = max_dis
        print_and_log(
            "Insertion atom ",
            ix,
        )

        for j, mx in enumerate(mat.xcart):
            dv = mx - ix
            for i in 0, 1, 2:
                if dv[i] > hproj[i]:
                    dv = dv - mat.rprimd[
                        i]  #periodic boundary conditions - can be not correct (in the sense that closest image can lie not 100 % in the neighbourhood image cell ) for oblique cells and large absolute values of dv
                if dv[i] < -hproj[i]: dv = dv + mat.rprimd[i]

            len1 = np.linalg.norm(dv)
            len2, second_len2 = mat.image_distance(mx, ix, r, 2)  #check len1

            #print "Lengths calculated with two methods ", len1, len2
            len1 = len2  #just use second method
            #assert np.around(len1,1) == np.around(len2,1)

            if len1 < dv_min:
                dv_min = len1
                j_r = j  # number of matrix atom to replace

        if dv_min == max_dis:
            print_and_log(" is more far away from any matrix atom than ",
                          dv_min, " A; I insert it")
            mat.xcart.append(ix)
            print_and_log('type of added atom is ', ins.typat[i_x])
            mat.typat.append(ins.typat[i_x])
        else:
            print_and_log("will replace martix atom", mat.xcart[j_r])
            mat.xcart[j_r] = ix.copy()

    mat.rprimd = r
    mat.xcart2xred()
    mat.natom = len(mat.xcart)
    mat.name = 'test_of_insert'
    write_xyz(mat)
    return mat
Exemple #44
0
def add_impurity(it_new, impurity_type = None, addtype = 'central', calc = [], r_pore = 0.5,
    it_to = '', ise_to = '', verlist_to = [], copy_geo_from = "", find_close_to = (),add_to_version = 0,
    write_geo = True, only_version = None, fine = 4, put_exactly_to = None, check_pore_vol = 0, replace_atom = None, override = False):

    """
    Add impurities in pores.

    Input:
    it_new - name of new structure with impurity
    
    impurity_type - name of impurity from Mendeley table, for example 'C'
    
    addtype - type of adding: ['central',]; 'central' means that impurity 
    will be placed as close to the geometrical center of cell as possible.
    
    it_to , ise_to , verlist_to - completed calculations in which impurity 
    will be added
    
    if 'verlist_to' is empty, function will try to find geometry files in 'geo_folder + struct_des[it_to].sfolder' folder;
    even if 'it_to' is empty it will try to find files in 'geo_folder + struct_des[it_new].sfolder+'/from' ' folder.
    'ise_to' also can be empty

    if 'copy_geo_from' is not empty, then programm copy all files from folder 'copy_geo_from' to 
    folder 'geo_folder + struct_des[it_to].sfolder+"/"+it_to' or  'geo_folder + struct_des[it_new].sfolder+"/from" '  

    'find_close_to' is tuple of three reduced coordinates of point close to which you want to find impurity. If empty - ignored; 

    'add_to_version' is integer number added to each 'verlist_to' number to produce ver_new.
    
    'only_version' - if == [v,], then instertion will be provided only for v. If None insertion will be made in all found versions

    If you want to add impurity to relaxed structure ...

    'fine' - integer number; allows to reduce number of small steps for defining center


    Possible addtype's:
    'central' - add one atom to the pore which is most close to  the center of the cell but with reduced coordinates less than 0.5 0.5 0.5
    'all_pore'  - add atoms in every found pore
    'all_local' - add atoms to every local point which allows to visualise topology of pores.
    'gb' - uses self.gbpos and places atom close to this value assuming that it will be at gb
    'grain_vol' - uses self.gbpos and assuming that cell contains two gb and two equal grains, places atom close to the centre of grain; y and z can be arbiratry


    put_exactly_to - will add impurity to this point 
    find_close_to - will try to find closest void and insert pore here.

    check_pore_vol - allows to estimate volume of pores; has problems for big cells

    replace_atom - if not None, than the specified atom is substituted


    Side effects: creates new geometry folder with input structures; 

    """

    struct_des = header.struct_des

    def test_adding_of_impurities(added, init, v):
        """
        Can be used only inside add_impurity()
        Replicates the structure and find again pores
        """
        global natoms_v1
        if added == None: return
        if v == 1: #TEST
            
            natoms_v1 = len(added.init.xcart) # for test 
            st_rep_after  = replic( added.init,      (1,2,1) )

            rep = copy.deepcopy(init)

            rep.init = replic( rep.init, (1,2,1) );   
            #print rep
            rep = add(znucl, "", rep, write_geo = False)
            #print rep
            #print "xcart of replic after adding ", st_rep_after.xcart
            #print "xcart of adding to    replic ", rep.init.xcart
            if len(st_rep_after.xcart) != len(rep.init.xcart): raise RuntimeError
            p = 0
            #for x2 in st_rep_after.xcart:
            #    print x2
            for x in rep.init.xcart:
                a = any(  ( np.around(x2, p) == np.around(x, p) ).all() for x2 in st_rep_after.xcart   )
                #b = any(  ( np.ceil(x2, p)   == np.ceil(x, p)  ).all()  for x2 in st_rep_after.xcart   )
                #c = any(  ( np.floor(x2, p)  == np.floor(x, p) ).all()  for x2 in st_rep_after.xcart   )
                #print a, b, c
                #np.concatenate(a, b, c):
                if not a:
                    print_and_log( "Error! Can't find ", np.around(x,3), "in replic  ")
                    raise RuntimeError

            #assert all([ all( np.around(v1, 8) == np.around(v2, 8) ) for (v1, v2) in zip(st_rep_after.xcart, rep.init.xcart) ])
            print_and_log( "add_impurity: test succesfully done")

        if natoms_v1 != len(added.init.xcart): print_and_log("You have different number of pores in different versions\n");  raise RuntimeError
        return
    


    def add(znucl, xyzpath = "", new = None, write_geo = True, put_exactly_to = None):
        "if put_exactly_to is True, then atom just added and nothing are searched"


        if write_geo and os.path.exists(new.path["input_geo"]) and not override:
            print_and_log("add: File '"+new.path["input_geo"]+"' already exists; continue\n", imp = 'Y');
            return new

        #new.init = return_atoms_to_cell(new.init)
        if replace_atom:
            #atom substitution
            if znucl not in new.init.znucl:
                new.init.znucl.append(znucl)
                new.init.ntypat+=1
                new.init.typat[replace_atom] = new.init.ntypat
            else:
                ind = new.init.znucl.index(znucl)
                new.init.typat[replace_atom] = ind + 1
            new.init.nznucl = []
            for typ in range(1, new.init.ntypat+1):
                new.init.nznucl.append(new.init.typat.count(typ) )



        else:
            new_before = copy.deepcopy(new)
            
            # new.init.xcart[-2][0]-=0.9 #was made once manually for c1gCOi10.1
            # new.init.xcart[-2][2]+=0.2
            # new.init.xred = xcart2xred(new.init.xcart, new.init.rprimd)
            write_xyz(new.init)
            #step = 0.042
            step = 0.06
            #r_pore = 0.56
            #fine = 0.3 # for visualisation of pores
            #fine = 4   #controls small steps; the steps are smaller for larger numbers
            #r_pore = 0.54
            prec = 0.004 # precision of center Angs
            if new.hex_a == None:
                r_mat = 1.48 -step
            else:
                r_mat = new.hex_a / 2 - step

            if put_exactly_to:
                pores_xred = [np.array(put_exactly_to),]
                print_and_log( 'Inmpurity just put in ', pores_xred, imp = 'Y')
            else:
                pores = find_pores(new.init, r_mat, r_pore, step, fine, prec,  addtype, new.gbpos, find_close_to, check_pore_vol) #octahedral
                pores_xred = pores.xred
            


            npores = len(pores_xred)
            
            st = new.init

            #delete last oxygen; was made once manually for c1gCOi10.1
            # st.natom-=1
            # del st.xred[-1]
            # del st.typat[-1]




            st.natom += npores
            st.xred.extend( pores_xred )

            if znucl in st.znucl:
                print_and_log( "znucl of added impurity is already in cell")
                ind = st.znucl.index(znucl)
                typat = ind+1
                st.nznucl[ind]+=npores
            else:
                st.ntypat +=1
                typat = st.ntypat
                st.znucl.append( znucl )
                st.nznucl.append( npores )



            for i in range( npores  ):
                st.typat.append( typat )



            st.xcart = xred2xcart(st.xred, st.rprimd)

            new.init = st

            #print "Add impurity: len(xred ", len(new.init.xred)
            #print "natom", new.init.natom


            #For automatisation of fit
            try: 
                #new.build
                if new.build.nadded == None:      new.build.nadded=npores
                else: new.build.nadded+=npores
                if new.build.listadded == [None]: new.build.listadded = range(new.natom - npores, new.natom) #list of atoms which were added
                else: new.build.listadded.extend( range(new.natom - npores, new.natom) )
                #print "Warning!!! Information about added impurities rewritten"
            except AttributeError: 
                pass

            #new.init.znucl = new.znucl
            #new.init.typat = new.typat
            
            #write_xyz(replic(new.init, (2,1,2))  , xyzpath)

            #test_adding_of_impurities(new, new_before, v)

            print_and_log("Impurity with Z="+str(znucl)+" has been added to the found pore in "+new.name+"\n\n")
            




        if write_geo:
            write_xyz(new.init , xyzpath)
            new.write_geometry("init",new.des, override = override)

        print_and_log( "\n")


        return new

    """0.Begin----------------------------------------------------------------------------"""

    znucl = element_name_inv(impurity_type)


    if impurity_type != 'octa' and impurity_type not in it_new:
        print_and_log("add_impurity: Your name 'it_new' is incorrect!\n\n")
        raise RuntimeError
    #del header.history[-2]
    #
    
    #hstring = ("add_impurity('%s', '%s', '%s', calc, %.3f, '%s', '%s', %s, '%s')  #at %s" %
    #    (it_new, impurity_type, addtype, r_pore,
    #        it_to, ise_to, verlist_to, copy_geo_from,
    #     datetime.date.today() ) )
    
    hstring = ("%s    #on %s"% (traceback.extract_stack(None, 2)[0][3],   datetime.date.today() ) )
    if hstring != header.history[-1]: header.history.append( hstring  )


    #geo_exists = 
    





    """1. The case of insertion to existing calculations--------------------------------------------------"""

    if verlist_to:         

        for v in verlist_to:
            if only_version and v not in only_version: continue # only_version = None works for all versions 
            id = (it_to, ise_to, v)
            new = copy.deepcopy(calc[id])

            new.init = new.end #replace init structure by the end structure

            new.version = v+add_to_version
            new.name = it_new#+'.'+id[1]+'.'+str(id[2])
            new.des = 'Obtained from '+str(id)+' by adding '+impurity_type+' impurity '
            path_new_geo = struct_des[it_new].sfolder+"/"+it_new+"/"+it_new+'.imp.'+addtype+'.'+str(new.version)+'.'+'geo'
            new.init.name = it_new+".init."+str(new.version)
            xyzpath = struct_des[it_new].sfolder+"/"+it_new
            
            new.path["input_geo"] = geo_folder+path_new_geo
            
            print_and_log("File '"+new.path["input_geo"] +"' with impurity will be created\n");
            #new.init.name = 'test_before_add_impurity'

            new = add(znucl, xyzpath, new, write_geo, put_exactly_to = put_exactly_to)

            



        """2. The case of insertion to geo files------------------------------------------------------------"""
    else:     

        

        print_and_log("You does not set 'id' of relaxed calculation. I try to find geometry files in "+it_new+" folder\n")

        if it_to:       geo_path = geo_folder + struct_des[it_to].sfolder  + "/" + it_to
        else:           geo_path = geo_folder + struct_des[it_new].sfolder + "/" + it_new+'/from'
        if copy_geo_from:
            print_and_log("You asked to copy geo files from "+copy_geo_from+" to " +geo_path+ " folder\n") 
            #if not os.path.exists(os.path.dirname(geo_path)): 
            runBash( "mkdir -p "+geo_path ) 
            runBash( "cp "+copy_geo_from+"/* "+geo_path  )




        if os.path.exists(geo_path):
            print_and_log("Folder '"+geo_path +"' was found. Trying to add impurity\n");
        else:
            print_and_log("Error! Folder "+geo_path+" does not exist\n"); raise RuntimeError

        #geofilelist = glob.glob(geo_path+'/*.geo*') #Find input_geofile
        #geofilelist = runBash('find '+geo_path+' -name "*grainA*.geo*" ').splitlines()
        #geofilelist = runBash('find '+geo_path+' -name "*.geo*" ').splitlines()
        geofilelist = glob.glob(geo_path+'/*.geo*')
        print_and_log( "There are several files here already: ", geofilelist, imp = 'y' )
        #print 'find '+geo_path+' -name "*.geo*" ',geofilelist
        #return


        for input_geofile in geofilelist:

            v = int( runBash("grep version "+str(input_geofile) ).split()[1] )
            
            if only_version and v not in only_version: continue # only_version = None works for all versions 
            
            new = CalculationVasp()
            new.version = v
            new.name = input_geofile
            
            

            new.read_geometry(input_geofile)
            init = copy.deepcopy(new)
            
            igl = input_geofile.split("/")
            #new.name = igl[-3]+'/'+igl[-3] #+input_geofile
            new.name = struct_des[it_new].sfolder+"/"+it_new+"/"+it_new
            print_and_log( "New path and part of name of file is ", new.name, imp = 'Y')
            #return
            new.des = 'Obtained from '+input_geofile+' by adding '+impurity_type+' impurity '
            #new.init.xred   = new.xred
            #new.init.rprimd = new.rprimd

            #print new.rprimd
            new.init.name = new.name+'.imp.'+addtype+'.'+str(new.version)
            #new.path["input_geo"] = geo_folder+it_new+"/"+new.end.name+'.'+'geo'
            new.path["input_geo"] = geo_folder+"/"+new.init.name+'.'+'geo'
            #new.init.name = 'test_before_add_impurity'
            
            new = add(znucl, "", new, write_geo, put_exactly_to = put_exactly_to)



    return new.path["input_geo"] #return for last version
def plot_mep(atom_pos,
             mep_energies,
             image_name=None,
             filename=None,
             show=None,
             plot=1,
             fitplot_args=None,
             style_dic=None):
    """
    Used for NEB method
    atom_pos (list) - xcart positions of diffusing atom along the path,
    mep_energies (list) - full energies of the system corresponding to atom_pos

    image_name - deprecated, use filename
    style_dic - dictionary with styles
        'p' - style of points
        'l' - style of labels
        'label' - label of points

    plot - if plot or not

    """

    from analysis import determine_barrier

    if filename is None:
        filename = image_name

    #Create
    if not style_dic:
        style_dic = {'p': 'ro', 'l': 'b-', 'label': None}

    if not fitplot_args:
        fitplot_args = {}
    atom_pos = np.array(atom_pos)
    data = atom_pos.T  #
    tck, u = interpolate.splprep(
        data)  #now we get all the knots and info about the interpolated spline
    path = interpolate.splev(
        np.linspace(0, 1, 500), tck
    )  #increase the resolution by increasing the spacing, 500 in this example
    path = np.array(path)

    diffs = np.diff(path.T, axis=0)
    path_length = np.linalg.norm(diffs, axis=1).sum()
    mep_pos = np.array([p * path_length for p in u])

    if 0:  #plot the path in 3d
        fig = plt.figure()
        ax = Axes3D(fig)
        ax.plot(data[0],
                data[1],
                data[2],
                label='originalpoints',
                lw=2,
                c='Dodgerblue')
        ax.plot(path[0], path[1], path[2], label='fit', lw=2, c='red')
        ax.legend()
        plt.show()

    # if '_mep' not in calc:
    calc['_mep'] = [
        atom_pos, mep_energies
    ]  # just save in temp list to use the results in neb_wrapper

    if hasattr(header,
               'plot_mep_invert') and header.plot_mep_invert:  # for vacancy
        mep_energies = list(reversed(mep_energies))

    mine = min(mep_energies)
    eners = np.array(mep_energies) - mine

    xnew = np.linspace(0, path_length, 1000)

    # ynew = spline(mep_pos, eners, xnew )
    # spl = CubicSpline(mep_pos, eners, bc_type = 'natural' ) # second-derivative zero
    # spl = CubicSpline(mep_pos, eners,) #
    # spl = CubicSpline(mep_pos, eners, bc_type = 'periodic')
    # spl = CubicSpline(mep_pos, eners, bc_type = 'clamped' ) #first derivative zero

    spl = scipy.interpolate.PchipInterpolator(mep_pos, eners)

    ynew = spl(xnew)

    diff_barrier = determine_barrier(mep_pos, eners)

    print_and_log('plot_mep(): Diffusion barrier =',
                  round(diff_barrier, 2),
                  ' eV',
                  imp='y')
    # sys.exit()
    # print()

    path2saved = None
    if plot:
        # print(image_name)
        path2saved = fit_and_plot(orig=(mep_pos, eners, style_dic['p'],
                                        style_dic['label']),
                                  spline=(xnew, ynew, style_dic['l'], None),
                                  xlim=(-0.05, None),
                                  xlabel='Reaction coordinate ($\AA$)',
                                  ylabel='Energy (eV)',
                                  image_name=image_name,
                                  filename=filename,
                                  show=show,
                                  fig_format='eps',
                                  **fitplot_args)

        # print(image_name, filename)
        if 0:
            with open(filename + '.txt', 'w') as f:
                f.write('DFT points:\n')
                for m, e in zip(mep_pos, eners):
                    f.write('{:10.5f}, {:10.5f} \n'.format(m, e))
                f.write('Spline:\n')
                for m, e in zip(xnew, ynew):
                    f.write('{:10.5f}, {:10.5f} \n'.format(m, e))

    return path2saved, diff_barrier
Exemple #46
0
def insert_cluster(insertion, i_center, matrix, m_center):
    """
    Take care of orientation; typat should be consistent
    Input:
    insertion -  object of class Structure(), which is supposed to be inserted in matrix
    in such a way that i_center will be combined with m_center.
    matrix - object of class Structure().
    i_center, m_center - numpy arrays (3).
    """
    ins = copy.deepcopy(insertion)
    mat = copy.deepcopy(matrix)
    r = mat.rprimd

    for i, z in enumerate(ins.znucl):
        if z not in mat.znucl:
            mat.znucl.append(z)
            mat.ntypat+=1
            mat.nznucl.append( ins.nznucl[i]  )



    hproj = [ (r[0][i]+r[1][i]+r[2][i]) * 0.5 for i in (0,1,2) ] #projection of vectors on three axis

    for i, x in enumerate(ins.xcart):
        ins.xcart[i] = x - i_center

    for i, x in enumerate(mat.xcart):
        mat.xcart[i] = x - m_center

    max_dis = 1
    for i_x, ix in enumerate(ins.xcart):
        dv_min = max_dis
        print_and_log( "Insertion atom ",ix,)
        
        for j, mx in enumerate(mat.xcart):
            dv = mx - ix
            for i in 0,1,2:
                if dv[i] >  hproj[i]: dv = dv - mat.rprimd[i] #periodic boundary conditions - can be not correct (in the sense that closest image can lie not 100 % in the neighbourhood image cell ) for oblique cells and large absolute values of dv 
                if dv[i] < -hproj[i]: dv = dv + mat.rprimd[i]
            
            len1 = np.linalg.norm(dv)
            len2, second_len2 = image_distance(mx, ix, r, 2) #check len1
            #print "Lengths calculated with two methods ", len1, len2
            len1 = len2 #just use second method
            #assert np.around(len1,1) == np.around(len2,1)

            if len1 < dv_min: 
                dv_min = len1;   
                j_r = j # number of matrix atom to replace



        if dv_min == max_dis:
            print_and_log( " is more far away from any matrix atom than ",dv_min," A; I insert it")
            mat.xcart.append( ix )
            print_and_log( 'type of added atom is ', ins.typat[i_x])
            mat.typat.append( ins.typat[i_x]   )
        else:        
            print_and_log( "will replace martix atom", mat.xcart[j_r] )
            mat.xcart[j_r] = ix.copy()
    


    mat.xred = xcart2xred(mat.xcart, r)
    mat.natom = len(mat.xcart)
    mat.name = 'test_of_insert'
    write_xyz(mat)
    return mat
Exemple #47
0
def find_pores(st_in, r_matrix=1.4, r_impurity = 0.6, step_dec = 0.05, fine = 0.3, prec = 0.1, calctype = 'central', gbpos = 0,
    find_close_to = (), check_pore_vol = 0):
    """
    st_in - input Structure() object
    r_impurity (A)- all pores smaller than this radius will be found
    r_matrix (A) - radius of matrix atoms disregarding to their type
    step_dec - scanning step of the cell in Angstroms
    fine - allows to change density of local points; local_step = step_dec/fine
    prec - precicion of pore center determination
    check_pore_vol - allows to estimate volume of pores; has problems for big cells


    'find_close_to' - works in the cases of gb and grain_vol; allows to ignore all and find pore close to provided three reduced coordinates
    return - instance of Structure() class with coordinates of pores. Number and type of included pores depend on the argument of 'calctype'.
    """
  
    xred   = st_in.xred
    natom  = len(xred)
    rprimd = st_in.rprimd
    name = st_in.name
    #print xred

    """Additional values"""
    # check_pore_vol = 1
    #if calctype in ("pore_vol","gb","grain_vol","all_local" ): check_pore_vol = 1 #something wrong with this function, especially for big cells

    """----Conversions of types for C++"""
    r1 = create_c_array(rprimd[0], float)
    r2 = create_c_array(rprimd[1], float)
    r3 = create_c_array(rprimd[2], float)

    xred1 = (c_float * len(xred))(*[x[0] for x in xred])
    xred2 = (c_float * len(xred))(*[x[1] for x in xred])
    xred3 = (c_float * len(xred))(*[x[2] for x in xred])

    max_npores = 10000;
    ntot = ctypes.c_int32(); npores = ctypes.c_int32()
    l_pxred1 = (c_float * max_npores)(0) #make static arrays fol local points
    l_pxred2 = (c_float * max_npores)(0)
    l_pxred3 = (c_float * max_npores)(0)
    l_npores = (ctypes.c_int32 * max_npores)(0)

    pxred1 = (c_float * max_npores)(0) #make static arrays natoms + npore
    pxred2 = (c_float * max_npores)(0)
    pxred3 = (c_float * max_npores)(0)

    """----Run C++ function"""
    print_and_log("Starting C++ function lib.findpores()...\n")
    lib.findpores ( check_pore_vol, \
                    max_npores, \
                    byref(ntot),   l_pxred1, l_pxred2, l_pxred3, l_npores, \
                    byref(npores), pxred1,   pxred2,   pxred3,  \
                    natom,         xred1,    xred2,    xred3, \
                    c_float(r_matrix), c_float(r_impurity), c_float(step_dec), c_float(fine), c_float(prec), \
                    r1, r2, r3 )

    print_and_log( "ntot is ", ntot.value)
    print_and_log( "l_npores[0] is ",l_npores[0])

    v = np.zeros((3))
    l_pxred = []
    shift1 = 0; shift2 = 0
    for i_por in range(npores.value):
        l_pxred.append( [] )
        shift2+=l_npores[i_por]    

        for i in range(shift1, shift2):
            v[0] = l_pxred1[i];     v[1] = l_pxred2[i];     v[2] = l_pxred3[i]

            l_pxred[i_por].append( v.copy() )

        shift1 = shift2



    if shift2 != ntot.value: 
        print_and_log( "Error! final shift2 not equal to ntot")

    #print l_pxred[0]

    pxred = [] # only coordinates of pores
    #print pxred1[natom]
    for i in range(npores.value):
        v[0] = pxred1[i+natom]; v[1]= pxred2[i+natom]; v[2] = pxred3[i+natom] #with shift, because first natom elements are coordinates of atoms
        pxred.append( v.copy() )

    #print pxred
    """----End of C++; result is two lists: lpxred - local geometry of all pores, pxred - coordinates of all pores"""


    """ Analyse of pores """
    st_result = Structure()
    st_result.rprimd = rprimd
 
    targetp = np.array((0.,0.,0.))
    if find_close_to: 
        targetp = np.asarray(find_close_to) #targer point
        print_and_log( "Target point is                        ",targetp)
 
    a = step_dec/fine #the side of little cube formed by the mesh which is used to find spheres inside the pore.
    aaa = a*a*a


    #find most central pore
    if calctype == 'central': #return coordinates of the most central pore
        st_result.name = "central_pore_from "+name 
        center = np.array((0.5,0.5,0.5))#center of cell
        d_min = 100
        for x in pxred:
            d = np.linalg.norm(x - center)
            #print x, x-center, d
            if d < d_min and x[0] <= 0.5 and x[1] <= 0.5 and x[2] <= 0.5:
                d_min = d
                x_min = x
        print_and_log( "The closest pore to the center has coordinates",x_min)
        st_result.xred.append( x_min )


    elif calctype == 'gb': #add impurity at gb
        st_result.name = "gb_pore_from "+name
        d_min = 100; #d2_min = 100
        dt_min =100
        i_min = 0; x_min = np.zeros((3))
        for i, x in enumerate(pxred):
            #print "l_npores ",l_npores[i]
            d = abs(x[0] - gbpos/rprimd[0][0]) #
            #print x[0], d
            if find_close_to:   closer = (np.linalg.norm(targetp - x) < dt_min)
            else:               closer = ( d < d_min ) # and x[1]>0.3 and x[2]>0.3:

            if closer:
                x_pre = x_min
                i_pre = i_min
                d_min = d
                dt_min = np.linalg.norm(targetp - x)
                x_min = x
                i_min = i

            #find and add impurity in bulk
            #d2 = abs( x[0] - (gbpos/rprimd[0][0] - 0.25) )
            #if d2 < d2_min: 
            #    d2_min = d2
            #    x2_min = x
            #    i2_min = i

        #print "rprimd[0][0]", rprimd[0][0]
        print_and_log( "Position of boundary is ",gbpos/rprimd[0][0])
     
        #x_min[0] = gbpos/rprimd[0][0]
        if find_close_to: print_and_log( "The closest pore to the target point is [ %.2f  %.2f  %.2f ]"%(x_min[0], x_min[1], x_min[2]))
        else: print_and_log( "The closest pore to the gb has coordinates",x_min)
        st_result.xred.append( x_min )
        #st_result.xred.append( x_pre )           
        #Calculate volume of the pore using local balls:
        print_and_log( "The number of pore is ",i_min," ; It has ",l_npores[i_min], "local balls")
        print_and_log( "Volume of pore is ", l_npores[i_min] * a*a*a, " A^3")
        #st_result.xred.extend( l_pxred[i_min] )
        #st_result.xred.extend( l_pxred[i_pre] )   

        #print "The closest pore to the center of bulk has coordinates",x2_min
        #st_result.xred.append( x2_min )           
        #Calculate volume of the pore using local balls:
        #print "The number of bulk pore is ",i2_min," ; It has ",l_npores[i2_min], "local balls"
        #print "Volume of pore is ", l_npores[i2_min] * a*a*a, " A^3";
        #st_result.xred.extend( l_pxred[i2_min] )  
    
    elif calctype == 'grain_vol': #add impurity to volume of grain
        st_result.name = "grain_volume_pore_from "+name
        d2_min = 100
        dt_min = 100
        i_min = 0; x_min = np.zeros((3))
        for i, x in enumerate(pxred):
            #find and add impurity to the  bulk
            d2 = abs( x[0] - (gbpos/rprimd[0][0] - 0.25) )
            
            if find_close_to:   closer = (np.linalg.norm(targetp - x) < dt_min)
            else:               closer = ( d2 < d2_min ) # and x[1]>0.3 and x[2]>0.3:

            if closer:
                dt_min = np.linalg.norm(targetp - x)
                d2_min = d2
                x2_min = x
                i2_min = i

        if find_close_to: print_and_log( "The closest pore to the target point is [ %.2f  %.2f  %.2f ]"%(x2_min[0], x2_min[1], x2_min[2]))
        else:             print_and_log( "The closest pore to the center of bulk has coordinates",x2_min)
        st_result.xred.append( x2_min )           
        #Calculate volume of the pore using local balls:
        print_and_log( "The number of bulk pore is ",i2_min," ; It has ",l_npores[i2_min], "local balls")
        print_and_log( "Volume of pore is ", l_npores[i2_min] * a*a*a, " A^3")
        st_result.xred.extend( l_pxred[i2_min] )  

    elif calctype == 'all_local':
        st_result.name = "all_local_points_from "+name
        v_max = 0
        i_max = 0
        for i in range(npores.value):
            v_pore = l_npores[i] * aaa
            print_and_log(  "Volume of pore is ", l_npores[i] * aaa, " A^3")
            if v_pore > v_max: v_max = v_pore; i_max = i
        print_and_log( "Pore number ", i_max,"has the largest volume ", v_max," A^3")
        # st_result.xred = l_pxred[i_max] # here coordinates of all local points to show geometry of pore with largerst volume
        st_result.xred = [x for group in l_pxred for x in group ] # all pores


    elif calctype == 'all_pores':
        st_result.name = "all_local_pores_from "+name
        st_result.xred = pxred



    st_result.xcart = xred2xcart(st_result.xred, rprimd)
    st_result.typat = [1 for x in st_result.xred]
    st_result.natom = len(st_result.typat)
    st_result.znucl = [200]
    st_ntypat = 1

    return st_result
Exemple #48
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.xcart = xred2xcart(mat.init.xred, mat.init.rprimd) #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
    
Exemple #49
0
    def add(znucl, xyzpath="", new=None, write_geo=True, put_exactly_to=None):
        "if put_exactly_to is True, then atom just added and nothing are searched"

        if write_geo and os.path.exists(
                new.path["input_geo"]) and not override:
            print_and_log("add: File '" + new.path["input_geo"] +
                          "' already exists; continue\n",
                          imp='Y')
            return new

        #new.init = return_atoms_to_cell(new.init)
        if replace_atom:
            #atom substitution
            if znucl not in new.init.znucl:
                new.init.znucl.append(znucl)
                new.init.ntypat += 1
                new.init.typat[replace_atom] = new.init.ntypat
            else:
                ind = new.init.znucl.index(znucl)
                new.init.typat[replace_atom] = ind + 1
            new.init.nznucl = []
            for typ in range(1, new.init.ntypat + 1):
                new.init.nznucl.append(new.init.typat.count(typ))

        else:
            new_before = copy.deepcopy(new)

            # new.init.xcart[-2][0]-=0.9 #was made once manually for c1gCOi10.1
            # new.init.xcart[-2][2]+=0.2
            # new.init.xred = xcart2xred(new.init.xcart, new.init.rprimd)
            write_xyz(new.init)
            #step = 0.042
            step = 0.06
            #r_pore = 0.56
            #fine = 0.3 # for visualisation of pores
            #fine = 4   #controls small steps; the steps are smaller for larger numbers
            #r_pore = 0.54
            prec = 0.004  # precision of center Angs
            if new.hex_a == None:
                r_mat = 1.48 - step
            else:
                r_mat = new.hex_a / 2 - step

            if put_exactly_to:
                pores_xred = [
                    np.array(put_exactly_to),
                ]
                print_and_log('Inmpurity just put in ', pores_xred, imp='Y')
            else:
                pores = find_pores(new.init, r_mat, r_pore, step, fine, prec,
                                   addtype, new.gbpos, find_close_to,
                                   check_pore_vol)  #octahedral
                pores_xred = pores.xred

            npores = len(pores_xred)

            st = new.init

            #delete last oxygen; was made once manually for c1gCOi10.1
            # st.natom-=1
            # del st.xred[-1]
            # del st.typat[-1]

            st.natom += npores
            st.xred.extend(pores_xred)

            if znucl in st.znucl:
                print_and_log("znucl of added impurity is already in cell")
                ind = st.znucl.index(znucl)
                typat = ind + 1
                st.nznucl[ind] += npores
            else:
                st.ntypat += 1
                typat = st.ntypat
                st.znucl.append(znucl)
                st.nznucl.append(npores)

            for i in range(npores):
                st.typat.append(typat)

            st.xred2xcart()

            new.init = st

            #print "Add impurity: len(xred ", len(new.init.xred)
            #print "natom", new.init.natom

            #For automatisation of fit
            try:
                #new.build
                if new.build.nadded == None: new.build.nadded = npores
                else: new.build.nadded += npores
                if new.build.listadded == [None]:
                    new.build.listadded = range(
                        new.natom - npores,
                        new.natom)  #list of atoms which were added
                else:
                    new.build.listadded.extend(
                        range(new.natom - npores, new.natom))
                #print "Warning!!! Information about added impurities rewritten"
            except AttributeError:
                pass

            #new.init.znucl = new.znucl
            #new.init.typat = new.typat

            #write_xyz(replic(new.init, (2,1,2))  , xyzpath)

            #test_adding_of_impurities(new, new_before, v)

            print_and_log("Impurity with Z=" + str(znucl) +
                          " has been added to the found pore in " + new.name +
                          "\n\n")

        if write_geo:
            write_xyz(new.init, xyzpath)
            new.write_geometry("init", new.des, override=override)

        print_and_log("\n")

        return new
Exemple #50
0
def add_neb(starting_calc = None, st = None, 
    it_new = None, ise_new = None, i_atom_to_move = None, 
    up = 'up1',
    search_type = 'vacancy_creation',
    images  = 3, r_impurity = None, corenum = 15, 
    calc_method = ['neb'], 
    inherit_option  = None, mag_config = None, i_void_start = None, i_void_final = None, 
    atom_to_insert = 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
     ):


    """
    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*
            

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


        - i_atom_to_move (int) - number of atom for moving;
        - *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) - number of voids from the suggested lists
        - atom_to_insert  (str) - element name of atom to insert
        - 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

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

        - x_start, x_final (array) - explicit coordinates of moving atom for starting and final positions, combined with atom_to_insert
        
        - upload_vts (bool) - if True upload Vasp.pm and nebmake.pl to server
        - run (bool)  - run on server

    ###RETURN:
        None

    ###DEPENDS:

    ###TODO
    please take care of manually provided i_atom_to_move in case of replicate flag using init_numbers 
    """

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

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


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




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

    atoms_to_move = []

    for i, typ, x in zip(range(st.natom), st.typat, st.xcart): #try to find automatically
        if st.znucl[typ-1] == 3: #Li
            atoms_to_move.append([i, 'Li', x])

        if st.znucl[typ-1] == 11: #
            atoms_to_move.append([i, 'Na', x])

        if st.znucl[typ-1] == 19: #
            atoms_to_move.append([i, 'K', x])




    if is_list_like(xr_start):
        x_start = xred2xcart([xr_start], st.rprimd)[0]
        st1 = st.add_atoms([x_start], atom_to_insert)
        x_m = x_start
        name_suffix+='s'
        write_xyz(st1, file_name = st.name+'_manually_start')
        printlog('Start position is created manually by adding xr_start', xr_start, x_start)


    elif not atoms_to_move:
        print_and_log('No atoms to move found, you probably gave me intercalated structure', important = 'y')
        print_and_log('Searching for voids', important = 'y')
        st_pores = find_pores(st, r_matrix = 0.5, r_impurity = r_impurity, fine = 1, calctype = 'all_pores')

        print_and_log('List of found voids:\n', np.array(st_pores.xcart) )
        write_xyz(st.add_atoms(st_pores.xcart, 'H'), file_name = st.name+'_possible_positions')
        write_xyz(st.add_atoms(st_pores.xcart, 'H'), replications = (2,2,2), file_name = st.name+'_possible_positions_replicated')



        sums = []
        avds = []
        for x in st_pores.xcart:
            summ = local_surrounding(x, st, n_neighbours = 6, control = 'sum', periodic  = True)
            avd = local_surrounding(x, st, n_neighbours = 6, control = 'av_dev', periodic  = True)
            # print sur,
            sums.append(summ)
            avds.append(avd[0])
        # print
        sums = np.array(sums)
        avds  = np.array(avds).round(0)
        print_and_log('Sum of distances to 6 neighboring atoms for each void (A):\n', sums, imp ='y')
        print_and_log('Distortion of voids (0 - is symmetrical):\n', avds, imp ='y')
        
        crude_prec = 1
        sums_crude = np.unique(sums.round(crude_prec))
        print_and_log('The unique voids based on the sums:', 
            '\nwith 0.01 A prec:',np.unique(sums.round(2)),
            '\nwith 0.1  A prec:',sums_crude,
            imp ='y')
        print_and_log('Based on crude criteria only', len(sums_crude),'types of void are relevant') 

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

        insert_positions = []
        start_table = []
        for i, s in enumerate(sums_crude):
            index_of_first =  np.where(sums.round(crude_prec)==s)[0][0]

            start_table.append([i,  st_pores.xcart[index_of_first].round(2), index_of_first,
            avds[index_of_first], sums[index_of_first]     ])

            insert_positions.append( st_pores.xcart[index_of_first] )


        print_and_log( tabulate(start_table, headers = ['Start void #', 'Cart.', 'Index', 'Dev.', 'Sum'], tablefmt='psql'), imp = 'Y' )

        if i_void_start == None:
            sys.exit()

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



    else:

        print_and_log('I have found', len(atoms_to_move), ' anion atoms', important = 'n')
        print_and_log( 'Sums of bond lengths around these atoms:',)
        sums = []
        for a in atoms_to_move:
            summ = local_surrounding(a[2], st, n_neighbours = 6, control = 'sum', periodic  = True)
            sums.append(summ)
            # print( summ, end = '')
        
        print_and_log('\nAmong them only',len(set(sums)), 'unique' , important = 'n')
        
        # if 
        print_and_log('Choosing the first' , important = 'n')

        type_atom_to_move = atoms_to_move[0][1]
        i_atom_to_move = atoms_to_move[0][0]+1
        el_num_suffix =  type_atom_to_move +str(i_atom_to_move)



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

        #highlight the moving atom for user for double-check
        # st_new = st.change_atom_z(i_m, new_z = 100)
        # search_type = 'vacancy_creation'











    """2. Choose final position"""



    if is_list_like(xr_final):
        x_final = xred2xcart([xr_final], st.rprimd)[0]
        st2 = st.add_atoms([x_final], atom_to_insert)
        x_del = x_final 
        search_type = 'manual_insertion'
        name_suffix+='f'+atom_to_insert
        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 = find_pores(st, r_matrix = 0.5, r_impurity = r_impurity, fine = 2, calctype = 'all_pores')

        sur = local_surrounding(x_m, st_pores, n_neighbours = len(st_pores.xcart), control = 'atoms', periodic  = True)
        # print sur


        print_and_log(
        'I can suggest you '+str (len(sur[0])-1 )+' end positions.' )
        # The distances to them are : '+str(np.round(sur[3], 2) )+' A\n ',
        # 'Openning Jmol end positions are highlighted by inserting H ', important = 'y')
        # print x_m
        # print sur[0]
        print_and_log('Please choose *i_void_final* from the following Table:', end = '\n', imp = 'Y')
        
        final_table = []

        for i, (x, d, ind) in enumerate( zip(sur[0], sur[3], sur[2])[1:] ):
            final_table.append([i, np.array(x).round(2), round(d, 2), avds[ind], sums[ind] ]  )

        print_and_log( tabulate(final_table, headers = ['Final void #', 'Cart.', 'Dist', 'Dev.', 'Sum'], tablefmt='psql'), imp = 'Y' )
        
        if i_void_final == None:
            sys.exit()



        x_final = sur[0][i_void_final+1] # +1 because first element is x_m atom itself

        write_xyz(st.add_atoms([ x_final], 'H'), replications = (2,2,2), file_name = st.name+'_possible_positions2_replicated')
        
        # sys.exit()        
        # write_xyz(st.add_atoms(sur[0][2:3], 'H'), analysis = 'imp_surrounding', show_around = 230,nnumber = 10, replications = (2,2,2), file_name = 'local230')
        # # write_xyz(st.add_atoms(sur[0][0:1], 'H'), analysis = 'imp_surrounding', show_around = 226,nnumber = 10, replications = (2,2,2), file_name = 'local')
        # run_jmol
        print_and_log('Choosing the closest position as end', important = 'n')
        # i_void_final = 0

        st1 = st

        # print st1.natom
        # sys.exit()

        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', important = '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.leave_only(type_atom_to_move) , n_neighbours = 4, control = 'atoms', 
            periodic  = False)
        # print 'xcart of moving atom', x_m
        # print 'Local surround = ', sur
        # print 'len', len(sur[0])
        if len(sur[0]) < 3:
            
            # print 'rprimd = \n',np.array(st.rprimd)
            # print 'r lengths = \n',( [np.linalg.norm(r) for r in st.rprimd] )
            # print 'xred = \n', np.array(st.xred)
            # print 'xcart = \n', np.array(st.xcart)


            print_and_log('The supercell is too small, I increase it 8 times!')
            st = replic(st, mul = (2,2,2) )
            sur = local_surrounding(x_m, st.leave_only(type_atom_to_move) , n_neighbours = 4, control = 'atoms', 
                periodic  = False)
            # print 'xcart of moving atom', x_m
            write_xyz(st, file_name = st.name+'_replicated')#replications = (2,2,2))

            # print 'Local surround = ', sur
            # sys.exit()


        print_and_log(
        'I can suggest you '+str (len(sur[0]) )+' end positions. The distances to them are : '+str(np.round(sur[3], 2) )+' A\n ',
        'They are all', type_atom_to_move, 'atoms', important = 'y')

        print_and_log('Choosing the closest position as end', important = 'n')
        neb_config = 1 #cause the first item in sur is moving atom itself
        x_del = sur[0][neb_config]
        i_del = st.find_atom_num_by_xcart(x_del)


        print_and_log('Making vacancy at end position for starting configuration', important = 'n')
        print_and_log( 'number of atom to delete = ', i_del)
        # print st.magmom
        st1 = st.del_atom(i_del)
        # print st1.magmom

        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
        st2 = st2.del_atom(i_del) # these two steps provide the same order





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

        write_xyz(st1, file_name = st1.name+'_start')# replications = (2,2,2))
        write_xyz(st2, file_name = st2.name+'_end')# replications = (2,2,2))

        # sys.exit()


    # sys.exit()





    """ Determining magnetic moments  """
    if varset[ise_new].vasp_params['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 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]

    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_'+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_'+search_type+'.'+str(ver_new)+'.'+'geo'
    
    cl.write_siman_geo(geotype = 'end', description = 'Final conf. for neb from '+obtained_from, override = True)




    #prepare calculations









    #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 = 'ov', inherit_option = inherit_option, n_neb_images = images, corenum = corenum, run =run  )
    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')


    return it_new 
Exemple #51
0
def make_sets_for_conv(isefrom,conv,list_of_parameters,varset):

    varset[isefrom].add_conv( isefrom, conv ); i = len(varset[isefrom].conv[conv])
    #print varset[isefrom].conv[conv]
    for param in list_of_parameters:
        newise = isefrom+conv[0:2]+str(i) ; i+=1
        if newise in varset:
            print_and_log("Set %s already in varset; continue\n" %( str(newise) ) ) 
            continue
           
        if conv == "kpoint_conv":
            for key in varset[isefrom].conv[conv]:
                if varset[key].ngkpt == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            #print newise
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_ngkpt(param)
            #print s

        elif conv == "tsmear_conv":
            for key in varset[isefrom].conv[conv]:
                if varset[key].tsmear == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_tsmear(param)
        elif conv == "ecut_conv":
            #automatically set dilatmx == 1
            for key in varset[isefrom].conv[conv]:
                if varset[key].vasp_params["ENCUT"] == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_dilatmx(1.)
            s.set_ecut(param)           
        else:
            print_and_log( "Warning! Unknown type of conv; return\n")
            return


        varset[isefrom].add_conv( newise, conv )

    print_and_log( "The following sets are in varset[%s].conv %s \n"%(str(isefrom),str(varset[isefrom].conv)   ) ) 


    return
Exemple #52
0
def make_sets_for_conv(isefrom,conv,list_of_parameters,varset):

    varset[isefrom].add_conv( isefrom, conv ); i = len(varset[isefrom].conv[conv])
    #print varset[isefrom].conv[conv]
    for param in list_of_parameters:
        newise = isefrom+conv[0:2]+str(i) ; i+=1
        if newise in varset:
            print_and_log("Set %s already in varset; continue\n" %( str(newise) ) ) 
            continue
           
        if conv == "kpoint_conv":
            for key in varset[isefrom].conv[conv]:
                if varset[key].ngkpt == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            #print newise
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_ngkpt(param)
            #print s

        elif conv == "tsmear_conv":
            for key in varset[isefrom].conv[conv]:
                if varset[key].tsmear == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_tsmear(param)
        elif conv == "ecut_conv":
            #automatically set dilatmx == 1
            for key in varset[isefrom].conv[conv]:
                if varset[key].vasp_params["ENCUT"] == param:
                    print_and_log( "Set %s already contains param %s; please check; return; \n" %( str(key), str(param) ) )
                    return
            s = inherit_iset(newise, isefrom, varset,newblockfolder = conv)
            s.set_dilatmx(1.)
            s.set_ecut(param)           
        else:
            print_and_log( "Warning! Unknown type of conv; return\n")
            return


        varset[isefrom].add_conv( newise, conv )

    print_and_log( "The following sets are in varset[%s].conv %s \n"%(str(isefrom),str(varset[isefrom].conv)   ) ) 


    return
def fit_and_plot(ax=None,
                 power=None,
                 xlabel=None,
                 ylabel=None,
                 image_name=None,
                 filename=None,
                 show=None,
                 pad=None,
                 xlim=None,
                 ylim=None,
                 title=None,
                 figsize=None,
                 xlog=False,
                 ylog=False,
                 scatter=False,
                 legend=False,
                 ncol=1,
                 fontsize=None,
                 legend_fontsize=None,
                 markersize=None,
                 linewidth=None,
                 hor=False,
                 fig_format='eps',
                 dpi=300,
                 ver_lines=None,
                 xy_line=None,
                 x_nbins=None,
                 alpha=0.8,
                 fill=False,
                 first=True,
                 last=True,
                 convex=None,
                 dashes=None,
                 corner_letter=None,
                 hide_ylabels=None,
                 hide_xlabels=None,
                 annotate=None,
                 **data):
    """
    Plot multiple plots on one axes using *data*
    
    return filename of saved plot

    ax (axes) - matplotlib axes object - to create multiple axes plots

    data - each entry should be 
        (X, Y, fmt) 
        or 
        (X, Y, fmt, label) 
        or
        {'x':,'y':, 'fmt':, 'label', 'xticks' }    not implemented for powers and scatter yet
        or
        (X, Y, R, fmt) - for scatter = 1, R - size of spots

    first, last - allows to call this function multiple times to put several plots on one axes. Use first = 1, last = 0 for the first plot, 0, 0 for intermidiate, and 0, 1 for last

    power (int) - the power of polynom, turn on fitting

    scatter (bool) - plot scatter points - the data format is slightly different - see *data*

    convex (bool) - plot convex hull around points like in ATAT

    fill (bool) - fill under the curves

    filename (str) - name of file with figure, image_name - deprecated
    fig_format (str) - format of saved file.
    dpi    - resolution of saved file


    ver_lines - list of dic args for  vertical lines {'x':, 'c', 'lw':, 'ls':}

    hide_ylabels - just hide numbers

    ncol - number of legend columns

    corner_letter - letter in the corner of the plot

    pad - additional padding, experimental

    annotate - annotate each point, 'annotates' list should be in data dic!

    linewidth - was 3 !
    markersize - was 10

    x_nbins - number of ticks

    TODO:
    remove some arguments that can be provided in data dict


    """

    if image_name == None:
        image_name = filename

    if fontsize:
        header.mpl.rcParams.update({'font.size': fontsize + 4})
        if legend_fontsize is None:
            legend_fontsize = fontsize

        header.mpl.rc('legend', fontsize=legend_fontsize)

    if hasattr(header, 'first'):
        first = header.first

    if hasattr(header, 'last'):
        last = header.last
    # print('fit_and_plot, first and last', first, last)

    if ax is None:
        if first:
            # fig, ax = plt.subplots(1,1,figsize=figsize)
            plt.figure(figsize=figsize)

        ax = plt.gca()  # get current axes )))
        # ax  = fig.axes

    if title:
        ax.title(title)

    # print(dir(plt))
    # print(ax)

    # plt.ylabel(ylabel, axes = ax)
    # print(ylabel)
    if ylabel != None:

        ax.set_ylabel(ylabel)

    if xlabel != None:
        ''
        # plt.xlabel(xlabel, axes = ax)
        ax.set_xlabel(xlabel)

    if corner_letter:
        # print(corner_letter)
        sz = header.mpl.rcParams['font.size']
        ax.text(0.05,
                0.85,
                corner_letter,
                size=sz * 1.5,
                transform=ax.transAxes
                )  # transform = None - by default in data coordinates!

        # text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))

    if convex:
        from scipy.spatial import ConvexHull

    for key in sorted(data):

        if scatter:

            ax.scatter(data[key][0],
                       data[key][1],
                       s=data[key][2],
                       c=data[key][-1],
                       alpha=alpha,
                       label=key)

        else:

            con = data[key]
            # print(con)
            # sys.exit()
            if type(con) == list or type(con) == tuple:
                try:
                    label = con[3]
                except:
                    label = key

                try:
                    fmt = con[2]
                except:
                    fmt = ''

                xyf = [con[0], con[1], fmt]
                con = {'label': label}  #fmt -color style

            elif type(con) == dict:
                if 'fmt' not in con:
                    con['fmt'] = ''
                # print(con)

                if 'x' not in con:
                    l = len(con['y'])
                    con['x'] = list(range(l))

                if 'xticks' in con:
                    # print(con['xticks'])
                    ax.set_xticklabels(con['xticks'])
                    ax.set_xticks(con['x'])
                    del con['xticks']

                xyf = [con['x'], con['y'], con['fmt']]

                # if 'lw' in
            if linewidth:
                con['lw'] = linewidth

            # print(con)
            # sys.exit()

            if markersize:
                con['ms'] = markersize

            # print('key is ', key)
            # print('x ', xyf[0])

            con_other_args = copy.deepcopy(con)
            for k in ['x', 'y', 'fmt', 'annotates']:
                if k in con_other_args:
                    del con_other_args[k]

            ax.plot(*xyf, alpha=alpha, **con_other_args)

            if power:
                coeffs1 = np.polyfit(xyf[0], xyf[1], power)

                fit_func1 = np.poly1d(coeffs1)
                x_range = np.linspace(min(xyf[0]), max(xyf[0]))
                fit_y1 = fit_func1(x_range)

                ax.plot(
                    x_range,
                    fit_y1,
                    xyf[2][0],
                )

                # 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)
                slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(
                    xyf[0], xyf[1])
                print('R^2 = {:5.2f} for {:s}'.format(r_value**2, key))

            if annotate:
                if adjustText_installed:

                    ts = []
                    for t, x, y in zip(con['annotates'], con['x'], con['y']):
                        ts.append(
                            ax.text(x,
                                    y,
                                    t,
                                    size=10,
                                    alpha=0.5,
                                    color=con['fmt'][0]))
                    adjust_text(
                        ts,
                        ax=ax,
                        # force_points=10, force_text=10, force_objects = 0.5,
                        expand_text=(2, 2),
                        expand_points=(2, 2),
                        # lim = 150,
                        expand_align=(2, 2),
                        # expand_objects=(0, 0),
                        text_from_text=1,
                        text_from_points=1,
                        # arrowprops=dict(arrowstyle='->', color='black')
                    )

                else:
                    for name, x, y in zip(con['annotates'], con['x'],
                                          con['y']):
                        ax.annotate(
                            name,
                            xy=(x, y),
                            xytext=(-20, 20),
                            fontsize=9,
                            textcoords='offset points',
                            ha='center',
                            va='bottom',
                            # bbox=dict(boxstyle='round,pad=0.2', fc='yellow', alpha=0.3),
                            arrowprops=dict(arrowstyle='->',
                                            connectionstyle='arc3,rad=0.5',
                                            color='black'))

            # print(key)
            # print(con)
            if fill:
                ''
                ax.fill(xyf[0], xyf[1], facecolor=con['c'], alpha=0.6)

            if convex:
                points = np.asarray(list(zip(xyf[0], xyf[1])))
                hull = ConvexHull(points)
                for simplex in hull.simplices:
                    if max(points[simplex, 1]) > 0:
                        continue
                    ax.plot(points[simplex, 0], points[simplex, 1], 'k-')

    if hor:
        ax.axhline(color='k')  #horizontal line

    ax.axvline(color='k')  # vertical line at 0 always

    if ver_lines:
        for line in ver_lines:
            ax.axvline(**line)

    if xy_line:
        ylim = ax.get_ylim()
        # print(ylim)
        x = np.linspace(*ylim)
        # print(x)
        ax.plot(x, x)

    if x_nbins:
        ax.locator_params(nbins=x_nbins, axis='x')

    if xlim:
        ax.set_xlim(xlim)

    if ylim:
        ax.set_ylim(ymin=ylim[0])
        if ylim[1]:
            ax.set_ylim(ymax=ylim[1])

    if xlog:
        ax.set_xscale('log')

    if ylog:
        if "sym" in str(ylog):
            ax.set_yscale('symlog', linthreshx=0.1)
        else:
            ax.set_yscale('log')

    if hide_ylabels:
        ax.yaxis.set_major_formatter(plt.NullFormatter())
        # ax.yaxis.set_ticklabels([])
    if hide_xlabels:
        ax.xaxis.set_major_formatter(plt.NullFormatter())

    if legend:
        scatterpoints = 1  # for legend

        ax.legend(loc=legend, scatterpoints=scatterpoints, ncol=ncol)
        # plt.legend()

    # plt.tight_layout(pad = 2, h_pad = 0.5)

    plt.tight_layout()

    if pad:
        plt.subplots_adjust(left=0.13,
                            bottom=None,
                            right=None,
                            top=None,
                            wspace=0.07,
                            hspace=None)

    path2saved = ''

    if last:
        if image_name:
            # plt.subplots_adjust(hspace=0.1)

            path2saved, path2saved_png = process_fig_filename(
                image_name, fig_format)

            plt.savefig(path2saved, dpi=dpi, format=fig_format)
            plt.savefig(path2saved_png, dpi=300)

            print_and_log("Image saved to ", path2saved, imp='y')

        elif show is None:
            show = True
        # print_and_log(show)
        if show:
            plt.show()
        plt.clf()
        plt.close('all')
    else:
        printlog('Attention! last = False, no figure is saved')

    return path2saved
Exemple #54
0
    def printme(self):
        for key in self.vasp_params:
            if self.vasp_params[key] == None: continue
            print_and_log( "{:30s} = {:s} ".format("s.vasp_params['"+key+"']", str(self.vasp_params[key]) ), imp = 'Y', end = '\n' )

        print_and_log('POTDIR:', self.potdir, imp = 'Y', end = '\n' )
def plot_bar(xlabel="xlabel",
             ylabel="ylabel",
             xlim=None,
             ylim=None,
             image_name=None,
             title=None,
             bottom=0.18,
             hspace=0.15,
             barwidth=0.2,
             data1=[],
             data2=[],
             data3=[],
             data4=[],
             **data):

    width = barwidth  # the width of the bars

    if data:
        N = len(data.values()[0][0])
        key = data.keys()[0]
        xlabels = data[key][0]
        # print N
        ind = np.arange(N)  # the x locations for the groups
        shift = 0
        fig, ax = plt.subplots()
        for key in sorted(data):
            # print 'color', data[key][2]
            ax.bar(ind + shift,
                   data[key][1],
                   width,
                   color=data[key][2],
                   label=data[key][-1])  # yerr=menStd)
            # print ind
            shift += width

    elif data1 and data4:
        fig = plt.figure(figsize=(10, 5))  #5:7 ratio for A4,
        gs = gridspec.GridSpec(2, 2, width_ratios=[5, 1], height_ratios=[1, 1])
        gs.update(top=0.98,
                  bottom=bottom,
                  left=0.1,
                  right=0.98,
                  wspace=0.15,
                  hspace=hspace)

        ax1 = plt.subplot(gs[0])
        ax2 = plt.subplot(gs[1])
        ax3 = plt.subplot(gs[2])
        ax4 = plt.subplot(gs[3])
        # fig, ax = plt.subplots()
        # fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, sharex='col')#, sharey='row') equal

        for ax, data in (ax1, data1), (ax2, data2), (ax3, data3), (ax4, data4):
            N = len(data[0][0])
            xlabels = data[0][0]
            ind = np.arange(N)  # the x locations for the groups
            shift = 0

            for d in data:
                ax.bar(ind + shift, d[1], width, color=d[2],
                       label=d[-1])  # yerr=menStd)
                # print ind
                shift += width

            ax.axhline(y=0, color='black')
            # ax.set_xticklabels(xlabels , rotation=70 )

            ax.set_xticks(ind + width)

        ax3.set_xticklabels(data3[0][0], rotation=80)
        ax4.set_xticklabels(data4[0][0], rotation=80)

        plt.setp(ax1.get_xticklabels(), visible=False)
        plt.setp(ax2.get_xticklabels(), visible=False)

        ax3.set_ylabel(ylabel)
        ax3.yaxis.set_label_coords(-0.1, 1.1)
        # plt.ylabel(ylabel)

        ax1.legend(loc=2, )
        ax3.legend(loc=2, )
        # ax1.axis('tight')
        # ax2.axis('tight')
        # ax3.axis('tight')
        # ax4.axis('tight')
        ax1.margins(0.0, 0.2)
        ax2.margins(0.0, 0.2)
        ax3.margins(0.0, 0.2)
        ax4.margins(0.0, 0.2)

    elif data1 and data2 and not data4:
        fig = plt.figure(figsize=(10, 5))  #5:7 ratio for A4,
        gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1], height_ratios=[1, 0])
        gs.update(top=0.95,
                  bottom=bottom,
                  left=0.1,
                  right=0.98,
                  wspace=0.15,
                  hspace=hspace)

        ax1 = plt.subplot(gs[0])
        ax2 = plt.subplot(gs[1])

        for ax, data in (ax1, data1), (ax2, data2):
            N = len(data[0][0])
            xlabels = data[0][0]
            ind = np.arange(N)  # the x locations for the groups
            # print ind+width
            # print data[0][0]
            shift = 0.2

            for d in data:
                ax.bar(ind + shift, d[1], width, color=d[2],
                       label=d[-1])  # yerr=menStd)
                # print ind
                shift += width

            ax.axhline(y=0, color='black')
            # ax.set_xticklabels(xlabels , rotation=70 )

            ax.set_xticks(ind + width + len(data) * width / 2)

        names1 = [n1 for n1, n2 in zip(data1[0][0], data1[1][0])]  #
        names2 = [n1 for n1, n2 in zip(data2[0][0], data2[1][0])]

        ax1.set_xticklabels(names1,
                            rotation=80)  # Names of configurations on x axis
        ax2.set_xticklabels(names2, rotation=80)

        ax1.set_ylabel(ylabel)

        ax1.legend(loc=2, )
        ax1.axis('tight')
        ax2.axis('tight')

    elif data1 and not data2:
        # fig = plt.figure(figsize=(10,5))   #5:7 ratio for A4,
        gs = gridspec.GridSpec(1, 2, width_ratios=[9, 1], height_ratios=[1, 0])
        gs.update(top=0.95,
                  bottom=bottom,
                  left=0.1,
                  right=0.98,
                  wspace=0.15,
                  hspace=hspace)

        ax1 = plt.subplot(gs[0])
        # ax2 = plt.subplot(gs[1])

        for ax, data in (ax1, data1), :
            N = len(data[0][0])
            xlabels = data[0][0]
            ind = np.arange(N)  # the x locations for the groups
            # print ind+width
            # print data[0][0]
            shift = 0.2

            for d in data:
                ax.bar(ind + shift, d[1], width, color=d[2],
                       label=d[-1])  # yerr=menStd)
                # print ind
                shift += width

            ax.axhline(y=0, color='black')
            # ax.set_xticklabels(xlabels , rotation=70 )

            ax.set_xticks(ind + width + len(data) * width / 2)

        names1 = [n1 + '; ' + n2
                  for n1, n2 in zip(data1[0][0], data1[1][0])]  #

        ax1.set_xticklabels(names1,
                            rotation=80)  # Names of configurations on x axis

        ax1.set_ylabel(ylabel)

        ax1.legend(loc=2, )
        ax1.axis('tight')
        # ax2.axis('tight')

    # ax.set_yscale('log')
    # plt.yscale('symlog', linthreshx=0.1)

    # ax.set_title('Scores by group and gender')

    def autolabel(rects):
        # attach some text labels
        for rect in rects:
            height = rect.get_height()
            ax.text(rect.get_x() + rect.get_width() / 2.,
                    1.05 * height,
                    '%d' % int(height),
                    ha='center',
                    va='bottom')

    # autolabel(rects1)
    # autolabel(rects2)

    # plt.axis('tight')
    # plt.margins(0.05, 0)

    # plt.tight_layout()
    # elif data1: gs.tight_layout(fig)

    if image_name:
        print_and_log("Saving image ...", str(image_name), imp='y')
        plt.savefig(str(image_name) + '.png', dpi=200, format='png')
    else:
        plt.show()

    return
Exemple #56
0
def read_vasp_sets(user_vasp_sets, override_global = False):
    """
    Read user sets and add them to project database
    Now for VASP
    ###INPUT:
        - varset (dict) - database dict with all sets of a project
        - user_vasp_sets (list) - list of user sets that describes creation of new sets based on inheritance 
        - override - allows to recreate all sets; can be usefull than you want to add some new property to all your sets - very dangerous to do!

    ###RETURN:
        - user_vasp_sets (list)

    """
    # print varset.keys()
    # varset['9'].printme()
    # print varset['9ml'].history
    # print varset['9'].history

    varset = header.varset

    vasp_keys = vasp_electronic_keys+vasp_ionic_keys+vasp_other_keys
    bfolder = '' #by default no blockfolder
    for l in user_vasp_sets:
        if override_global or 'over' in l[-1]: 
            override = True
        else:
            override = False
        
        if override or l[0] not in varset:
            # print override, 'override'
            param = l[2]

            if 'bfolder' in param:
                bfolder = param['bfolder']
            else:
                bfolder = None


            s = inherit_iset(l[0], l[1], varset, override = override, newblockfolder = bfolder) 
            # print param
            for key in param:
                
                if key in vasp_keys:
                    s.set_vaspp(key, param[key])

                elif key == 'set_potential':
                    for key2 in param[key]:
                        # print key2, 'key2'
                        s.set_potential(key2, param[key][key2])

                elif key == 'add_nbands':
                    # print param[key]

                    s.set_add_nbands(param[key])


                elif key == 'bfolder':
                    print_and_log( 'New blockfolder', param[key])

                elif key in siman_keys:
                    s.set_attrp(key, param[key] )
                
                else:
                    print_and_log('Error! Uknown key: '+key)
                    raise RuntimeError
             

                if key == 'set_sequence':
                    sets = []
                    for se in s.set_sequence:
                        sets.append(copy.deepcopy(varset[se]))

                    s.set_sequence = sets  #put objects instead of names

            # if hasattr(s, 'set_sequence') and s.set_sequence:
            #     sets = []
            #     for se in s.set_sequence:
            #         if type(se) == str:
            #             sets.append(copy.deepcopy(varset[se]))
            #         else:
            #             sets.append(copy.deepcopy(se))

            #     s.set_sequence = sets  #put objects instead of names



        header.varset = varset

    return varset
    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
Exemple #58
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
Exemple #59
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
Exemple #60
0
    def add(znucl, xyzpath = "", new = None, write_geo = True, put_exactly_to = None):
        "if put_exactly_to is True, then atom just added and nothing are searched"


        if write_geo and os.path.exists(new.path["input_geo"]) and not override:
            print_and_log("add: File '"+new.path["input_geo"]+"' already exists; continue\n", imp = 'Y');
            return new

        #new.init = return_atoms_to_cell(new.init)
        if replace_atom:
            #atom substitution
            if znucl not in new.init.znucl:
                new.init.znucl.append(znucl)
                new.init.ntypat+=1
                new.init.typat[replace_atom] = new.init.ntypat
            else:
                ind = new.init.znucl.index(znucl)
                new.init.typat[replace_atom] = ind + 1
            new.init.nznucl = []
            for typ in range(1, new.init.ntypat+1):
                new.init.nznucl.append(new.init.typat.count(typ) )



        else:
            new_before = copy.deepcopy(new)
            
            # new.init.xcart[-2][0]-=0.9 #was made once manually for c1gCOi10.1
            # new.init.xcart[-2][2]+=0.2
            # new.init.xred = xcart2xred(new.init.xcart, new.init.rprimd)
            write_xyz(new.init)
            #step = 0.042
            step = 0.06
            #r_pore = 0.56
            #fine = 0.3 # for visualisation of pores
            #fine = 4   #controls small steps; the steps are smaller for larger numbers
            #r_pore = 0.54
            prec = 0.004 # precision of center Angs
            if new.hex_a == None:
                r_mat = 1.48 -step
            else:
                r_mat = new.hex_a / 2 - step

            if put_exactly_to:
                pores_xred = [np.array(put_exactly_to),]
                print_and_log( 'Inmpurity just put in ', pores_xred, imp = 'Y')
            else:
                pores = find_pores(new.init, r_mat, r_pore, step, fine, prec,  addtype, new.gbpos, find_close_to, check_pore_vol) #octahedral
                pores_xred = pores.xred
            


            npores = len(pores_xred)
            
            st = new.init

            #delete last oxygen; was made once manually for c1gCOi10.1
            # st.natom-=1
            # del st.xred[-1]
            # del st.typat[-1]




            st.natom += npores
            st.xred.extend( pores_xred )

            if znucl in st.znucl:
                print_and_log( "znucl of added impurity is already in cell")
                ind = st.znucl.index(znucl)
                typat = ind+1
                st.nznucl[ind]+=npores
            else:
                st.ntypat +=1
                typat = st.ntypat
                st.znucl.append( znucl )
                st.nznucl.append( npores )



            for i in range( npores  ):
                st.typat.append( typat )



            st.xcart = xred2xcart(st.xred, st.rprimd)

            new.init = st

            #print "Add impurity: len(xred ", len(new.init.xred)
            #print "natom", new.init.natom


            #For automatisation of fit
            try: 
                #new.build
                if new.build.nadded == None:      new.build.nadded=npores
                else: new.build.nadded+=npores
                if new.build.listadded == [None]: new.build.listadded = range(new.natom - npores, new.natom) #list of atoms which were added
                else: new.build.listadded.extend( range(new.natom - npores, new.natom) )
                #print "Warning!!! Information about added impurities rewritten"
            except AttributeError: 
                pass

            #new.init.znucl = new.znucl
            #new.init.typat = new.typat
            
            #write_xyz(replic(new.init, (2,1,2))  , xyzpath)

            #test_adding_of_impurities(new, new_before, v)

            print_and_log("Impurity with Z="+str(znucl)+" has been added to the found pore in "+new.name+"\n\n")
            




        if write_geo:
            write_xyz(new.init , xyzpath)
            new.write_geometry("init",new.des, override = override)

        print_and_log( "\n")


        return new