Exemple #1
0
def plot_dos(cl1, cl2 = None, dostype = None, iatom = 0, orbitals = ('s'), up = None, neighbors = 6, show = 1, path = 'dos', xlim = (None, None), ylim = (None,None) ):
    """
    cl1 (CalculationVasp) - object created by add_loop()
    dostype (str) - control which dos to plot:
        'total'   - plot total dos
        'diff_total' - difference of total dos, use cl2 for second calculation
        'partial' - partial dos

    orbitals (list of str) - any from 's, p, d, py, pz, px, dxy, dyz, dz2, dxz, dx2' where 'p' and 'd' are sums of projections
    up - 'up2' allows to download the file once again


    iatom (int) - number of atom starting from 1 to plot DOS by default it is assumed that the last atom is used
    iatom ([float]*3) - cartesian coordinates of point around which atoms will be found
    show (bool) - whether to show the dos 
    path (str)  - path to folder with images

    neighbors - number of neighbours around iatom to plot dos on them

    xlim, ylim (tuple)- limits for plot

    #0 s     1 py     2 pz     3 px    4 dxy    5 dyz    6 dz2    7 dxz    8 dx2 
    #In all cases, the units of the l- and site projected DOS are states/atom/energy.

    """
    iatom -= 1





    """1. Read dos"""
    printlog("------Start plot_dos()-----", imp = 'Y')
    dos = []
    for cl in cl1, cl2:
        if cl == None: 
            continue

        if not hasattr(cl, "efermi"):
            cl.read_results('o')

        printlog(cl.name, 'e_fermi', cl.efermi, imp = 'Y')
     
        DOSCAR = cl.get_file('DOSCAR', update = up); 
        printlog('DOSCAR file is ', DOSCAR)

        dos.append( VaspDos(DOSCAR, cl.efermi) )
    

    #determine number of zero energy    
    i_efermi = int(len(dos[0].energy)  *  -dos[0].energy[0] / (dos[0].energy[-1] - dos[0].energy[0])) # number of point with zero fermi energy
    if cl2:
        i_efermi_e = int(len(dos[1].energy)  *  -dos[1].energy[0] / (dos[1].energy[-1] - dos[1].energy[0])) # number of point with zero fermi energy

    


    

    """2. Plot dos for different cases"""
    if dostype == 'total':

        fit_and_plot(show = show, image_name = os.path.join(path, cl1.name+'.dosTotal'), xlabel = "Energy (eV)", ylabel = "DOS (states/eV)",
            xlim = xlim, ylim = ylim,
            Total = (dos[0].energy, smoother(dos[0].dos, 10), 'b-'))

    elif dostype == 'diff_total':

        if len(dos) > 1:    
            #calculate dos diff 
            dosd = [(d0 - d1)*e for d0, d1, e in zip(dos[0].dos, dos[1].dos, dos[0].energy)] #calculate difference
            area = trapz(dosd[:i_efermi], dx=1)
            printlog("area under dos difference = ", -area, imp = 'Y')

            fit_and_plot(show = show,image_name = cl1.name+'--'+cl2.name+'.dosTotal_Diff', xlabel = "Energy (eV)", ylabel = "DOS (states/eV)",
                xlim = xlim, ylim = ylim,
                Diff_Total = (dos[0].energy, smoother(dosd, 15), 'b-'))
        else:
            printlog('You provided only one calculation; could not use diff_total')





    elif 'partial' in dostype:
        #Partial dos
        #1  p carbon,  d Ti
        #0 s     1 py     2 pz     3 px    4 dxy    5 dyz    6 dz2    7 dxz    8 dx2 
       
        try:
            dos[0].site_dos(0, 4)
        except:
            printlog('Error! No information about partial dxy dos in DOSCAR; use LORBIT 12 to calculate it')



        """Determine neighbouring atoms """
        printlog("Number of considered neighbors is ", neighbors)

        if type(iatom) == int: #for the cases when we need to build surrounding around specific atom in this calculation - just use number of atom
            t = cl1.end.typat[iatom]
            z = cl1.end.znucl[t-1]
            el = element_name_inv(z)
            printlog('Typat of chosen imp atom in cl1 is ', el)
            surround_center = cl1.end.xcart[iatom]
        else: #for the case when coordinates of arbitary point are provided.
            surround_center = iatom
            el = 'undef'

        local_atoms = local_surrounding(surround_center, cl1.end, neighbors, control = 'atoms', periodic = True)

        numbers = local_atoms[2] # first atom is impurity if exist
        printlog("Numbers of local atoms:", [n+1 for n in numbers] )
        printlog("List of distances", [round(d,2) for d in local_atoms[3]] )


        iX = numbers[0]

        for j in range(len(dos)):
            
            dos[j].p = [] #central and and surrounding
            dos[j].d = [] #central atom and surrounding atoms
            dos[j].d6 = 0 #sum by six atoms

            for i in numbers: #Now for surrounding atoms in numbers list:

                plist = [dos[j].site_dos(i, l)  for l in (1,2,3) ]
                dos[j].p.append( [ sum(x) for x in zip(*plist) ] )


                dlist = [dos[j].site_dos(i, l)  for l in (4,5,6,7,8) ] # For total d T96C
                dsum = [ sum(x) for x in zip(*dlist) ] 
                dos[j].d.append(  dsum   )
            

            dos[j].p6 = [ sum(pi) for pi in zip(*dos[j].p) ] #sum over neighbouring atoms
            dos[j].d6 = [ sum(di) for di in zip(*dos[j].d) ] #sum over neighbouring atoms

            # t2g = [dos[0].site_dos(iTi, l)  for l in 4,5,7] #  Now only for first Ti atom
            # dos[0].t2g =  [ sum(x) for x in zip(*t2g) ]  

            # eg = [dos[0].site_dos(iTi, l)  for l in 8, 6] #  Now only for first Ti atom
            # dos[0].eg =  [ sum(x) for x in zip(*eg) ] 
           


        """Plotting"""
        nsmooth = 15 # smooth of dos
        d1 = dos[0]
        energy1 = dos[0].energy
        args = {}
        i_orb = {'s':0, 'py':1, 'pz':2, 'px':3, 'dxy':4, 'dyz':5, 'dz2':6, 'dxz':7, 'dx2':8}
        color = {'s':'k-', 'p':'g-', 'd':'b-', 'py':'r-', 'pz':'b-', 'px':'c-', 'dxy':'m-', 'dyz':'c-', 'dz2':'m-', 'dxz':'r-', 'dx2':'g-'}

        for orb in orbitals:
            if orb == 'p':
                args[orb] = (d1.energy, smoother(d1.p[0], nsmooth), color[orb])
            elif orb == 'd':
                args[orb] = (d1.energy, smoother(d1.d[0], nsmooth), color[orb])
            else:
                args[orb] = (d1.energy, smoother(d1.site_dos(iX, i_orb[orb]), nsmooth), color[orb])

        image_name = os.path.join(path, cl1.name+'.'+''.join(orbitals)+'.'+el+str(iX))

        fit_and_plot(show = show, image_name = image_name, figsize = (4,6), xlabel = "Energy (eV)", ylabel = "DOS (states/eV)", 
        # title = cl1.name.split('.')[0]+'; V='+str(round(cl1.vol) )+' $\AA^3$; Impurity: '+el,
        xlim = xlim, ylim = ylim, legend = 2,
        **args
        )
        # printlog("Writing file", image_name, imp = 'Y')

        """Additional dos analysis; to be refined"""

        if 0:
            """Calculate d DOS at Fermi level"""
            nn = 50 #number to integrate in both directions 
            x1 = dos[0].energy[i_efermi-nn:i_efermi+nn]
            y1 = smoother(dos[0].d6, nsmooth)[i_efermi-nn:i_efermi+nn]
            x2 = dos[1].energy[i_efermi_e-nn:i_efermi_e+nn]
            y2 = smoother(dos[1].d6, nsmooth)[i_efermi_e-nn:i_efermi_e+nn]
            f1 = interp1d(x1, y1, kind='cubic')
            f2 = interp1d(x2, y2, kind='cubic')
            # if debug: print '\n'
            # if debug: print dos[0].d6[i_efermi] - dos[1].d6[i_efermi_e], " - by points; change of d Ti DOS at the Fermi level due to the carbon"
            # if debug: print f2(0), f1(0)
            e_at_Ef_shift = f1(0) - f2(0)

            printlog("{:5.2f} reduction of d dos at Fermi level; smoothed and interpolated".format( e_at_Ef_shift ), imp = 'Y' )
        
        if 0:
            """Calculate second derivative of d at the Fermi level"""
            # tck1 = interpolate.splrep(x1, y1, s=0)
            # tck2 = interpolate.splrep(x2, y2, s=0)
            # e_at_Ef_shift_spline = interpolate.splev(0, tck1, der=0) - interpolate.splev(0, tck2, der=0)
            # if debug: print "{:5.2f} smoothed and interpolated from spline".format( e_at_Ef_shift_spline )
            # # if debug: print type(interpolate.splev(0, tck1, der=2))
            # if debug: print "{:5.2f} {:5.2f} gb and bulk second derivative at Fermi from spline".format( float(interpolate.splev(0, tck1, der=2)), float(interpolate.splev(0, tck2, der=2)) )




        if 0:
            """Calculate shift of d orbitals after adding impurity"""
            d_shift = det_gravity(dos[0],  Erange = (-2.8, 0)) - det_gravity(dos[1],  Erange = (-2.8, 0) ) #negative means impurity shifts states to negative energies, which is favourable
            printlog( "{:5.2f} Shift of Ti d center of gravity".format( d_shift ), imp = 'Y' )
            # if debug: print det_gravity(dos[0],  Erange = (-2.8, 0)), det_gravity(dos[1],  Erange = (-2.8, 0))
            """Calculate correlation between imp p and matrix d"""
            def rmsdiff(a, b):
                # rms difference of vectors a and b:
                #Root-mean-square deviation
                rmsdiff = 0
                for (x, y) in zip(a, b):
                    rmsdiff += (x - y) ** 2  # NOTE: overflow danger if the vectors are long!
                
                return math.sqrt(rmsdiff / min(len(a), len(b)))

            pd_drms = 1/rmsdiff(dos[0].p, dos[0].d6) # the higher the number the higher hybridization
            printlog("{:5.2f} p-d hybridization estimate".format( pd_drms ) , imp = 'Y')

            # if debug: print "sqeuclidean", sqeuclidean(dos[0].p, dos[0].d6)/len(dos[0].d6)

            # if debug: print "pearsonr", pearsonr(dos[0].p, dos[0].d6) #Pearson correlation coefficient; only shape; the larger number means more similarity in shape

            # def autocorr(x):
            #     result = np.correlate(x, x, mode='full')
            #     return result[result.size/2:]


    printlog("------End plot_dos()-----\n\n")


    return {'name':cl1.name}
Exemple #2
0
    def pairs(in_calc, xcart_pores, central_atoms, prec=2, max_dist=20, max_dist_from_gb=4, pairtyp="gvol"):
        """
        Searhing for pairs and make list of distances and numbers of atoms
        prec - precision, allows to control which distances can be related to the same configurations
        max_dist - maximum distance between atoms in pair
        max_dist_from_gb - 
        pairtyp - 'gvol' assumes that central_atoms are in the grain volume, 'gb' assumes that central_atoms are in the grain boundary region

        """
        st = in_calc.init
        st_replic = replic(st, (2, 2, 2))
        st_replic = replic(st_replic, (2, 2, 2), -1)  # replic in negative direction also
        r1x = in_calc.rprimd[0][0]
        r3z = in_calc.rprimd[2][2]
        print "Half length of r1x is", r1x / 2

        if segtyp in ["segreg", "coseg", "grainvol"]:
            gbpos2 = in_calc.gbpos
            gbpos1 = gbpos2 - r1x / 2.0
            print "\n\nPositions of boundaries gb1 and gb2", gbpos1, gbpos2
            print "Maximum possible distance between boundary and impurity", r1x / 4
        else:
            gbpos2 = 0
            gbpos1 = 0

        dlist = []
        d1list = []
        d2list = []
        dgb2list = []

        n_neighbours = 8  # number of atoms to calculate sums

        sumrulist = []  # list of sums (sumr1 or sumr2) of unique pores
        unique_pores = []  # the same list but also with coordinates of pores

        sumrlist = []  # list of sumr1+sumr2

        k = 1
        d2diff = 0
        d1diff = 0
        # z1 = 6 #charge of added impurity
        # z2 = 8

        diffprec = 0.02

        # print xcart_pores

        for i, x1 in enumerate(xcart_pores):
            if i not in central_atoms:
                continue
            # iz = z1
            for j, x2 in enumerate(xcart_pores):
                if all(x1 == x2):
                    continue

                d = abs(x2[0] - in_calc.gbpos)
                if pairtyp == "gb" and d > max_dist_from_gb:
                    continue  # second atom is too far from grain boundary

                d1, d2 = image_distance(x1, x2, st.rprimd, 2)  # the minimum distance and the next minimum dist
                if d1 > max_dist:
                    continue
                if (d1, d2) != image_distance(x1, x2, st.rprimd, 3):
                    raise RuntimeError  # test, searching in father images

                # d1 = round(d1,prec)
                # d2 = round(d2,prec)
                dgb1 = round(x2[0] - gbpos1, prec)
                dgb2 = round(gbpos2 - x2[0], prec)

                sumr1 = local_surrounding(x1, st_replic, n_neighbours)  # sum of distances to surrounding atoms
                sumr2 = local_surrounding(x2, st_replic, n_neighbours)
                sumr = sumr2 + sumr1

                if sumr1 not in sumrulist:
                    sumrulist.append(sumr1)
                    unique_pores.append((sumr1, x1))  # determine unique pores

                if sumr2 not in sumrulist:
                    sumrulist.append(sumr2)
                    unique_pores.append((sumr2, x2))  # determine unique pores

                # if d1 in d1list: continue
                if sumr in sumrlist:  # new condition based on sumr
                    ind = sumrlist.index(sumr)
                    i_min, smaller = min_diff(d1, d1list, diffprec)
                    if smaller:
                        continue

                # if 0:#d1list:
                #     i_min, smaller = min_diff(d1, d1list, diffprec)# d1 has the smallest difference with di
                #     #print "exist"
                #     d2diff = abs(d2list[i_min]-d2)
                #     #print abs(d2list[i_min]-d2)
                #     #print central_atoms
                #     if smaller and abs(d2list[i_min]-d2) < diffprec*2  : continue #and abs(dgb2list[i_min]-dgb2) < diffprec

                #     i_min, smaller = min_diff(d2, d2list, diffprec)# d1 has the smallest difference with di
                #     d1diff = abs(d1list[i_min]-d1)
                #     if smaller and abs(d1list[i_min]-d1) < diffprec*2  : continue

                # print "skiped"
                # di, smaller = min_diff(d2, d2list, diffprec)
                # if di != None and smaller: continue
                # if min_diff(d2, d2list, diffprec): continue # be carefull here. this condition can pass some unique configrations; should make additional check like below
                # if d2 in d2list and dgb2list[d2list.index(d2)] == dgb2: continue
                # jz = z2

                sumrlist.append(sumr)
                d1list.append(d1)
                # d2list.append(d2)
                # dgb2list.append(dgb2)

                sym = ""
                if 0:  # mannualy switched off
                    if abs(x1[1] - x2[1]) < diffprec:  # Find symmetry
                        if abs(x1[2] - x2[2]) < diffprec:
                            sym = "ms"  # if y and z are the same, than mirror symmetry
                        elif abs(x1[2] - x2[2]) - r3z < diffprec:
                            sym = "is"  # inverse symmtry
                        elif (
                            abs(x1[2] + x2[2]) - 0.5 * r3z < diffprec
                        ):  # only for t111g; should be extended for general case of existing periods along y or z
                            sym = "is"

                dlist.append(
                    [round(d1, prec), round(d2, prec), sym, sumr1, sumr2, dgb1, dgb2, x1, x2, sumr1, sumr2]
                )  # the first sumr1, sumr2 below replaced by their types

                k += 1

        dlist.sort(key=itemgetter(0))

        unique_pores.sort(key=itemgetter(0))
        sumrulist.sort()
        print "Number of unique pores     is", len(unique_pores)
        print "Pores have the following sums: ", unique_pores

        print "Searching for similar pairs but with different distances ..."
        print "number, d1, d2, name,  sumr1, sumr2, dgb1, dgb2; parallel pair with larger distances"

        bname = element_name_inv(target_znucl[1]) + element_name_inv(target_znucl[2])
        for i, el1 in enumerate(dlist):

            typ1 = sumrulist.index(el1[3]) + 1  # typ of pore of the first atom
            typ2 = sumrulist.index(el1[4]) + 1
            el1[3] = typ1
            el1[4] = typ2

            if pairtyp == "gb":
                dlist[i][2] = bname + "i" + str(i + 1) + "." + str(el1[3]) + "-" + str(el1[4]) + dlist[i][2]

            elif pairtyp == "gvol":
                dlist[i][2] = bname + ".v" + str(i + 1) + dlist[i][2]

            print i + 1, el1[:3], el1[-2:], el1[-6], el1[-5],  # number, d1, d2, name,  sumr1, sumr2, dgb1, dgb2

            for (
                el2
            ) in (
                dlist
            ):  # this loop looks for pairs which are parallel to the same direction as el1 but have larger interdistances

                if el1 == el2:
                    continue

                mod = el2[0] / el1[0] % 1

                if (mod < 0.005 or mod > 0.995) and abs(el1[0] - el2[0]) > dlist[0][
                    0
                ]:  # only multiple distances and if difference is larger than smallest distance
                    # if round(el1[2],prec-1) != round(el2[2],prec-1): continue #In either case the sum the distances should be the same for the same direction
                    if el1[0] == el2[1]:
                        continue
                    print el2[0] / el1[0],  # el2, this pair of atoms is analogus to el1 but have larger interdistance
            print
        print "Total number of structures is", len(dlist)

        if 0:
            print "\n\nSearching for pairs with equal distances by periodic boundary conditions:"
            for el1 in dlist:
                if el1[0] == el1[1]:
                    print el1

            print "\nSearching for pairs with not equal distances by periodic boundary conditions:"
            for el1 in dlist:
                if el1[0] != el1[1]:
                    print el1

            print "\nSearching for pairs with d2/d1>2:"
            for el1 in dlist:
                if el1[1] / el1[0] > 2:
                    print el1

        dlist[0].append(unique_pores)  # last element of dlist[0] is sum and coordinates of unique pores

        return dlist
Exemple #3
0
    def pairs(in_calc,
              xcart_pores,
              central_atoms,
              prec=2,
              max_dist=20,
              max_dist_from_gb=4,
              pairtyp='gvol'):
        """
        Searhing for pairs and make list of distances and numbers of atoms
        prec - precision, allows to control which distances can be related to the same configurations
        max_dist - maximum distance between atoms in pair
        max_dist_from_gb - 
        pairtyp - 'gvol' assumes that central_atoms are in the grain volume, 'gb' assumes that central_atoms are in the grain boundary region

        """
        st = in_calc.init
        st_replic = replic(st, (2, 2, 2))
        st_replic = replic(st_replic, (2, 2, 2),
                           -1)  #replic in negative direction also
        r1x = in_calc.rprimd[0][0]
        r3z = in_calc.rprimd[2][2]
        print "Half length of r1x is", r1x / 2

        if segtyp in ['segreg', 'coseg', 'grainvol']:
            gbpos2 = in_calc.gbpos
            gbpos1 = gbpos2 - r1x / 2.
            print "\n\nPositions of boundaries gb1 and gb2", gbpos1, gbpos2
            print "Maximum possible distance between boundary and impurity", r1x / 4
        else:
            gbpos2 = 0
            gbpos1 = 0

        dlist = []
        d1list = []
        d2list = []
        dgb2list = []

        n_neighbours = 8  # number of atoms to calculate sums

        sumrulist = []  #list of sums (sumr1 or sumr2) of unique pores
        unique_pores = []  #the same list but also with coordinates of pores

        sumrlist = []  #list of sumr1+sumr2

        k = 1
        d2diff = 0
        d1diff = 0
        #z1 = 6 #charge of added impurity
        #z2 = 8

        diffprec = 0.02

        # print xcart_pores

        for i, x1 in enumerate(xcart_pores):
            if i not in central_atoms: continue
            #iz = z1
            for j, x2 in enumerate(xcart_pores):
                if all(x1 == x2): continue

                d = abs(x2[0] - in_calc.gbpos)
                if pairtyp == 'gb' and d > max_dist_from_gb:
                    continue  #second atom is too far from grain boundary

                d1, d2 = image_distance(
                    x1, x2, st.rprimd,
                    2)  # the minimum distance and the next minimum dist
                if d1 > max_dist: continue
                if (d1, d2) != image_distance(x1, x2, st.rprimd, 3):
                    raise RuntimeError  #test, searching in father images

                #d1 = round(d1,prec)
                #d2 = round(d2,prec)
                dgb1 = round(x2[0] - gbpos1, prec)
                dgb2 = round(gbpos2 - x2[0], prec)

                sumr1 = local_surrounding(
                    x1, st_replic,
                    n_neighbours)  # sum of distances to surrounding atoms
                sumr2 = local_surrounding(x2, st_replic, n_neighbours)
                sumr = sumr2 + sumr1

                if sumr1 not in sumrulist:
                    sumrulist.append(sumr1)
                    unique_pores.append((sumr1, x1))  #determine unique pores

                if sumr2 not in sumrulist:
                    sumrulist.append(sumr2)
                    unique_pores.append((sumr2, x2))  #determine unique pores

                #if d1 in d1list: continue
                if sumr in sumrlist:  # new condition based on sumr
                    ind = sumrlist.index(sumr)
                    i_min, smaller = min_diff(d1, d1list, diffprec)
                    if smaller: continue

                # if 0:#d1list:
                #     i_min, smaller = min_diff(d1, d1list, diffprec)# d1 has the smallest difference with di
                #     #print "exist"
                #     d2diff = abs(d2list[i_min]-d2)
                #     #print abs(d2list[i_min]-d2)
                #     #print central_atoms
                #     if smaller and abs(d2list[i_min]-d2) < diffprec*2  : continue #and abs(dgb2list[i_min]-dgb2) < diffprec

                #     i_min, smaller = min_diff(d2, d2list, diffprec)# d1 has the smallest difference with di
                #     d1diff = abs(d1list[i_min]-d1)
                #     if smaller and abs(d1list[i_min]-d1) < diffprec*2  : continue

                #print "skiped"
                #di, smaller = min_diff(d2, d2list, diffprec)
                #if di != None and smaller: continue
                #if min_diff(d2, d2list, diffprec): continue # be carefull here. this condition can pass some unique configrations; should make additional check like below
                #if d2 in d2list and dgb2list[d2list.index(d2)] == dgb2: continue
                #jz = z2

                sumrlist.append(sumr)
                d1list.append(d1)
                # d2list.append(d2)
                # dgb2list.append(dgb2)

                sym = ''
                if 0:  #mannualy switched off
                    if abs(x1[1] - x2[1]) < diffprec:  #Find symmetry
                        if abs(x1[2] - x2[2]) < diffprec:
                            sym = 'ms'  # if y and z are the same, than mirror symmetry
                        elif abs(x1[2] - x2[2]) - r3z < diffprec:
                            sym = 'is'  # inverse symmtry
                        elif abs(
                                x1[2] + x2[2]
                        ) - 0.5 * r3z < diffprec:  # only for t111g; should be extended for general case of existing periods along y or z
                            sym = 'is'

                dlist.append([
                    round(d1, prec),
                    round(d2, prec), sym, sumr1, sumr2, dgb1, dgb2, x1, x2,
                    sumr1, sumr2
                ])  #the first sumr1, sumr2 below replaced by their types

                k += 1

        dlist.sort(key=itemgetter(0))

        unique_pores.sort(key=itemgetter(0))
        sumrulist.sort()
        print 'Number of unique pores     is', len(unique_pores)
        print 'Pores have the following sums: ', unique_pores

        print "Searching for similar pairs but with different distances ..."
        print "number, d1, d2, name,  sumr1, sumr2, dgb1, dgb2; parallel pair with larger distances"

        bname = element_name_inv(target_znucl[1]) + element_name_inv(
            target_znucl[2])
        for i, el1 in enumerate(dlist):

            typ1 = sumrulist.index(el1[3]) + 1  #typ of pore of the first atom
            typ2 = sumrulist.index(el1[4]) + 1
            el1[3] = typ1
            el1[4] = typ2

            if pairtyp == 'gb':
                dlist[i][2] = bname + 'i' + str(i + 1) + '.' + str(
                    el1[3]) + '-' + str(el1[4]) + dlist[i][2]

            elif pairtyp == 'gvol':
                dlist[i][2] = bname + '.v' + str(i + 1) + dlist[i][2]

            print i + 1, el1[:3], el1[-2:], el1[-6], el1[
                -5],  #number, d1, d2, name,  sumr1, sumr2, dgb1, dgb2

            for el2 in dlist:  #this loop looks for pairs which are parallel to the same direction as el1 but have larger interdistances

                if el1 == el2: continue

                mod = el2[0] / el1[0] % 1

                if (mod < 0.005 or mod > 0.995
                    ) and abs(el1[0] - el2[0]) > dlist[0][
                        0]:  #only multiple distances and if difference is larger than smallest distance
                    #if round(el1[2],prec-1) != round(el2[2],prec-1): continue #In either case the sum the distances should be the same for the same direction
                    if el1[0] == el2[1]: continue
                    print el2[0] / el1[
                        0],  # el2, this pair of atoms is analogus to el1 but have larger interdistance
            print
        print 'Total number of structures is', len(dlist)

        if 0:
            print "\n\nSearching for pairs with equal distances by periodic boundary conditions:"
            for el1 in dlist:
                if el1[0] == el1[1]:
                    print el1

            print "\nSearching for pairs with not equal distances by periodic boundary conditions:"
            for el1 in dlist:
                if el1[0] != el1[1]:
                    print el1

            print "\nSearching for pairs with d2/d1>2:"
            for el1 in dlist:
                if el1[1] / el1[0] > 2:
                    print el1

        dlist[0].append(
            unique_pores
        )  # last element of dlist[0] is sum and coordinates of unique pores

        return dlist