Ejemplo n.º 1
0
    def hardness_XX(self, initial_cutoff_radius=0.8, use_laplacian=True):

        bonds, coordination, cutoff_radius = self.bonds_coordination(
            initial_cutoff_radius=initial_cutoff_radius,
            use_laplacian=use_laplacian)

        sigma = 3.0
        c_hard = 1300.0
        xprod = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.structure.species)

        pcm_log.debug('Atomic numbers in the structure : %s' %
                      str(atomicnumbers))

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)

        if f_d == 0:
            pcm_log.debug('Returning zero as hardness. f_d= %10.3f' % f_d)
            return 0.0
        f = 1.0 - (self.structure.nspecies *
                   f_n**(1.0 / self.structure.nspecies) / f_d)**2

        diff_bonds = [x for x in bonds if len(bonds[x]) > 0]

        for pair in diff_bonds:
            i1 = pair[0]
            i2 = pair[1]

            ei = valence(self.structure.symbols[i1]) / covalent_radius(
                self.structure.symbols[i1])
            ej = valence(self.structure.symbols[i2]) / covalent_radius(
                self.structure.symbols[i2])

            for dij in bonds[pair]:
                sij = math.sqrt(
                    ei * ej) / (coordination[i1] * coordination[i2]) / dij
                xprod *= sij

            num_i_j_bonds = len(bonds[pair])
            pcm_log.debug('Number of bonds for pair %s = %d' %
                          (str(pair), num_i_j_bonds))
            tot += num_i_j_bonds

        vol = self.structure.volume

        pcm_log.debug("Structure volume: %7.3f" % vol)
        pcm_log.debug("Total number of bonds: %d" % tot)
        pcm_log.debug("Bonds: %s" % str(bonds))

        hardness_value = (c_hard / vol) * tot * (xprod**(1. / tot)) * math.exp(
            -sigma * f)

        return round(hardness_value, 3), cutoff_radius, coordination
Ejemplo n.º 2
0
    def hardness_XX(self, initial_cutoff_radius=0.8, use_laplacian=True):
        """
        Implementation of Hardness algorithm:
        
        First-principles structural design of superhard materials
        J. Chem. Phys. 138, 114101 (2013); https://doi.org/10.1063/1.4794424
        Xinxin Zhang, et al.
        """

        bonds, coordination, cutoff_radius = self.bonds_coordination(initial_cutoff_radius=initial_cutoff_radius,
                                                                     use_laplacian=use_laplacian)

        sigma = 3.0
        c_hard = 1300.0
        xprod = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.structure.species)

        pcm_log.debug('Atomic numbers in the structure : %s' % str(atomicnumbers))

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)

        if f_d == 0:
            pcm_log.debug('Returning zero as hardness. f_d= %10.3f' % f_d)
            return 0.0
        f = 1.0 - (self.structure.nspecies * f_n ** (1.0 / self.structure.nspecies) / f_d) ** 2

        diff_bonds = [x for x in bonds if len(bonds[x]) > 0]

        for pair in diff_bonds:
            i1 = pair[0]
            i2 = pair[1]

            ei = valence(self.structure.symbols[i1]) / covalent_radius(self.structure.symbols[i1])
            ej = valence(self.structure.symbols[i2]) / covalent_radius(self.structure.symbols[i2])

            for dij in bonds[pair]:
                sij = math.sqrt(ei * ej) / (coordination[i1] * coordination[i2]) / dij
                xprod *= sij

            num_i_j_bonds = len(bonds[pair])
            pcm_log.debug('Number of bonds for pair %s = %d' % (str(pair), num_i_j_bonds))
            tot += num_i_j_bonds

        vol = self.structure.volume

        pcm_log.debug("Structure volume: %7.3f" % vol)
        pcm_log.debug("Total number of bonds: %d" % tot)
        pcm_log.debug("Bonds: %s" % str(bonds))

        hardness_value = (c_hard / vol) * tot * (xprod ** (1. / tot)) * math.exp(-sigma * f)

        return round(hardness_value, 3), cutoff_radius, coordination
Ejemplo n.º 3
0
    def hardness_XX(self, initial_cutoff_radius=0.8, use_laplacian=True):

        bonds, coordination, cutoff_radius = self.bonds_coordination(initial_cutoff_radius=initial_cutoff_radius,
                                                                     use_laplacian=use_laplacian, verbose=True)

        sigma = 3.0
        c_hard = 1300.0
        xprod = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.structure.species)

        pcm_log.debug('Atomic numbers in the structure : %s' % str(atomicnumbers))

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)

        if f_d == 0:
            pcm_log.debug('Returning zero as hardness. f_d= %10.3f' % f_d)
            return 0.0
        f = 1.0 - (self.structure.nspecies * f_n ** (1.0 / self.structure.nspecies) / f_d) ** 2

        diff_bonds = [x for x in bonds if len(bonds[x]) > 0]

        for pair in diff_bonds:
            i1 = pair[0]
            i2 = pair[1]

            ei = valence(self.structure.symbols[i1]) / covalent_radius(self.structure.symbols[i1])
            ej = valence(self.structure.symbols[i2]) / covalent_radius(self.structure.symbols[i2])

            for dij in bonds[pair]:
                sij = math.sqrt(ei * ej) / (coordination[i1] * coordination[i2]) / dij
                xprod *= sij

            num_i_j_bonds = len(bonds[pair])
            pcm_log.debug('Number of bonds for pair %s = %d' % (str(pair), num_i_j_bonds))
            tot += num_i_j_bonds

        vol = self.structure.volume

        pcm_log.debug("Structure volume: %7.3f" % vol)
        pcm_log.debug("Total number of bonds: %d" % tot)
        pcm_log.debug("Bonds: %s" % str(bonds))

        hardness_value = (c_hard / vol) * tot * (xprod ** (1. / tot)) * math.exp(-sigma * f)

        return round(hardness_value, 3), cutoff_radius, coordination
Ejemplo n.º 4
0
    def hardness_old(self, noupdate=False, verbose=False, tolerance=0.05):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param noupdate: (bool) If True, the Laplacian method is used
        :param verbose: (bool) To print some debug info
        :param tolerance: (float)

        :rtype : (float)
        """

        superc = self.structure.copy()
        superc.supercell(2, 2, 2)
        structure_analisys = StructureAnalysis(superc)

        natom = superc.natom
        volume = superc.volume

        max_covalent_radius = max(covalent_radius(superc.symbols))
        if verbose:
            print('Number of atoms', natom)
            print('Volume         ', volume)
            print('Covalent rad max', max_covalent_radius)
        rcut, coord, dis_dic = structure_analisys.get_bonds(2.0 * max_covalent_radius, noupdate, verbose, tolerance)

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        dic_atms = {}
        for i in superc.symbols:
            dic_atms[i] = atomic_number(i)

        for i in dic_atms.keys():
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)
        f = 1.0 - (len(dic_atms) * f_n ** (1.0 / len(dic_atms)) / f_d) ** 2

        if verbose:
            print('BONDS')
            print(dis_dic)
            print('COORDINATION')
            print(coord)

        for i in dis_dic.keys():
            i1 = dis_dic[i][2][0]
            i2 = dis_dic[i][2][1]

            ei = valence(superc.symbols[i1]) / covalent_radius(superc.symbols[i1])
            ej = valence(superc.symbols[i2]) / covalent_radius(superc.symbols[i2])

            sij = math.sqrt(ei * ej) / (coord[i1] * coord[i2]) / dis_dic[i][0]

            tot += dis_dic[i][1]
            x *= sij * dis_dic[i][1]

        if verbose:
            print("V:", volume)
            print("f:", f)
            print("x:", x)

        hardness_value = c_hard / volume * (len(dis_dic) * x ** (1. / (len(dis_dic)))) * math.exp(-sigma * f)

        if verbose:
            print(hardness_value)

        return round(hardness_value, 3)
Ejemplo n.º 5
0
    def hardness(self, verbose=False, initial_cutoff_radius=0.8, ensure_conectivity=False, use_laplacian=True,
                 use_jump=True):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param use_jump:
        :param ensure_conectivity:
        :param verbose: (bool) To print some debug info
        :param initial_cutoff_radius: (float)
        :param use_laplacian: (bool) If True, the Laplacian method is used

        :rtype : (float)
        """
        if self._supercell == (1, 1, 1) and verbose:
            print('''Only internal connectivity can be ensure, for complete connectivity in the crystal you must use a
                  supercell at of (2,2,2)''')

        bonds, coordination, all_distances, tolerances, cutoff_radius = \
            self.get_bonds_coordination(initial_cutoff_radius=initial_cutoff_radius,
                                        ensure_conectivity=ensure_conectivity,
                                        use_laplacian=use_laplacian, verbose=verbose, use_jump=use_jump)

        if verbose:
            print('Structure coordination : ', coordination)

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.structure.species)

        if verbose:
            print('Atomic numbers in the structure :', atomicnumbers)

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)

        # if verbose:
        # print 'fd', f_d
        #    print 'fn', f_n
        #    print atomicnumbers
        if f_d == 0:
            return 0.0
        f = 1.0 - (len(atomicnumbers) * f_n ** (1.0 / len(atomicnumbers)) / f_d) ** 2

        # Selection of different bonds
        diff_bonds = np.unique(np.array(reduce(lambda xx, y: xx + y, bonds)))
        if verbose:
            print('Number of different bonds : ', len(diff_bonds))

        for i in diff_bonds:
            i1 = all_distances[i]['pair'][0]
            i2 = all_distances[i]['pair'][1]

            ei = valence(self.structure.symbols[i1]) / covalent_radius(self.structure.symbols[i1])
            ej = valence(self.structure.symbols[i2]) / covalent_radius(self.structure.symbols[i2])
            # print 'bond ->', sqrt(ei * ej), (coordination[i1] * coordination[i2]), all_distances[i]['distance']

            sij = math.sqrt(ei * ej) / (coordination[i1] * coordination[i2]) / all_distances[i]['distance']
            num_i_j_bonds = len([j for j in diff_bonds if i1 in all_distances[j]['pair'] and
                                 i2 in all_distances[j]['pair']])
            # print 'sij', sij
            # print 'num_i_j_bonds', num_i_j_bonds
            tot += num_i_j_bonds
            x *= sij
            # print 'x', x

        vol = self.structure.volume
        if verbose:
            print("Structure volume:", vol)
            # print("f:", f)
            # print("x:", x)

        # print 'len_bonds', len(diff_bonds
        hardness_value = c_hard / vol * (len(diff_bonds) * x ** (1. / (len(diff_bonds)))) * math.exp(-sigma * f)

        return round(hardness_value, 3), cutoff_radius, coordination
Ejemplo n.º 6
0
 def valence_electrons(self):
     ret = 0
     for key, value in self.composition.items():
         ret += value * valence(key)
     return ret
Ejemplo n.º 7
0
    def hardness_old(self, noupdate=False, verbose=False, tolerance=0.05):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param noupdate: (bool) If True, the Laplacian method is used
        :param verbose: (bool) To print some debug info
        :param tolerance: (float)

        :rtype : (float)
        """

        superc = self.structure.copy()
        superc.supercell(2, 2, 2)
        structure_analisys = StructureAnalysis(superc)

        natom = superc.natom
        volume = superc.volume

        max_covalent_radius = max(covalent_radius(superc.symbols))
        if verbose:
            print('Number of atoms', natom)
            print('Volume         ', volume)
            print('Covalent rad max', max_covalent_radius)
        rcut, coord, dis_dic = structure_analisys.get_bonds(
            2.0 * max_covalent_radius, noupdate, verbose, tolerance)

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        dic_atms = {}
        for i in superc.symbols:
            dic_atms[i] = atomic_number(i)

        for i in dic_atms.keys():
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)
        f = 1.0 - (len(dic_atms) * f_n**(1.0 / len(dic_atms)) / f_d)**2

        if verbose:
            print('BONDS')
            print(dis_dic)
            print('COORDINATION')
            print(coord)

        for i in dis_dic.keys():
            i1 = dis_dic[i][2][0]
            i2 = dis_dic[i][2][1]

            ei = valence(superc.symbols[i1]) / covalent_radius(
                superc.symbols[i1])
            ej = valence(superc.symbols[i2]) / covalent_radius(
                superc.symbols[i2])

            sij = math.sqrt(ei * ej) / (coord[i1] * coord[i2]) / dis_dic[i][0]

            tot += dis_dic[i][1]
            x *= sij * dis_dic[i][1]

        if verbose:
            print("V:", volume)
            print("f:", f)
            print("x:", x)

        hardness_value = c_hard / volume * (
            len(dis_dic) * x**(1. / (len(dis_dic)))) * math.exp(-sigma * f)

        if verbose:
            print(hardness_value)

        return round(hardness_value, 3)
Ejemplo n.º 8
0
    def hardness(self,
                 verbose=True,
                 initial_cutoff_radius=0.8,
                 ensure_conectivity=False,
                 use_laplacian=True,
                 use_jump=True,
                 tol=1E-15):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param use_jump:
        :param ensure_conectivity:
        :param verbose: (bool) To print some debug info
        :param initial_cutoff_radius: (float)
        :param use_laplacian: (bool) If True, the Laplacian method is used
        :param tol: (float) Tolerance for considering two atoms bonded

        :rtype : (float)
        """
        if self._supercell == (1, 1, 1) and verbose:
            print(
                '''Only internal connectivity can be ensure, for complete connectivity in the crystal you must use a
                  supercell at of (2,2,2)''')

        bonds, coordination, all_distances, tolerances, cutoff_radius = \
            self.get_bonds_coordination(initial_cutoff_radius=initial_cutoff_radius,
                                        ensure_conectivity=ensure_conectivity,
                                        use_laplacian=use_laplacian, verbose=verbose, use_jump=use_jump, tol=tol)

        if verbose:
            print('Structure coordination : ', coordination)

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.structure.species)

        if verbose:
            print('Atomic numbers in the structure :', atomicnumbers)

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)

        # if verbose:
        # print 'fd', f_d
        #    print 'fn', f_n
        #    print atomicnumbers
        if f_d == 0:
            return 0.0
        f = 1.0 - (len(atomicnumbers) * f_n**(1.0 / len(atomicnumbers)) /
                   f_d)**2

        # Selection of different bonds
        diff_bonds = np.unique(
            np.array(functools.reduce(lambda xx, y: xx + y, bonds)))
        if verbose:
            print('Number of different bonds : ', len(diff_bonds))

        for i in diff_bonds:
            i1 = all_distances[i]['pair'][0]
            i2 = all_distances[i]['pair'][1]

            ei = valence(self.structure.symbols[i1]) / covalent_radius(
                self.structure.symbols[i1])
            ej = valence(self.structure.symbols[i2]) / covalent_radius(
                self.structure.symbols[i2])
            # print 'bond ->', sqrt(ei * ej), (coordination[i1] * coordination[i2]), all_distances[i]['distance']

            sij = math.sqrt(ei * ej) / (coordination[i1] * coordination[i2]
                                        ) / all_distances[i]['distance']
            num_i_j_bonds = len([
                j for j in diff_bonds if i1 in all_distances[j]['pair']
                and i2 in all_distances[j]['pair']
            ])
            # print 'sij', sij
            # print 'num_i_j_bonds', num_i_j_bonds
            tot += num_i_j_bonds
            x *= sij
            # print 'x', x

        vol = self.structure.volume
        if verbose:
            print("Structure volume:", vol)
            # print("f:", f)
            # print("x:", x)

        # print 'len_bonds', len(diff_bonds
        hardness_value = c_hard / vol * (
            len(diff_bonds) * x**(1. /
                                  (len(diff_bonds)))) * math.exp(-sigma * f)

        return round(hardness_value, 3), cutoff_radius, coordination
Ejemplo n.º 9
0
    def hardness_OLD(self, noupdate=False, verbose=False, tolerance=0.05):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param noupdate: (bool) If True, the Laplacian method is used
        :param verbose: (bool) To print some debug info
        :param tolerance: (float)

        :rtype : (float)
        """

        #from ase.data import covalent_radii

        #atms=atms.repeat([2,2,2])
        spc = self.copy()
        spc.supercell(2, 2, 2)
        natom = spc.natom
        volume = spc.volume

        #max_covalent_radius = max([covalent_radii[i.number] for i in atms])
        max_covalent_radius = max(covalent_radius(spc.symbols))
        if verbose:
            print('Number of atoms', natom)
            print('Volume         ', volume)
            print('Covalent rad max', max_covalent_radius)
        #rcut, coord, dis_dic  = get_bonds(atms,2.0*max_covalent_radius, noupdate,verbose,tolerance)
        rcut, coord, dis_dic = spc.get_bonds(2.0 * max_covalent_radius, noupdate, verbose, tolerance)

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        dic_atms = {}
        #for i in atms:
        #    dic_atms[i.symbol] = i.number
        for i in spc.symbols:
            dic_atms[i] = atomic_number(i)

        #for i in dic_atms.keys():
        #    f_d += Z[i] / covalent_radii[dic_atms[i]]
        #    f_n *= Z[i] / covalent_radii[dic_atms[i]]
        #f = 1.0 - (len(dic_atms)*f_n**(1.0/len(dic_atms)) / f_d)**2

        for i in dic_atms.keys():
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)
        f = 1.0 - (len(dic_atms) * f_n ** (1.0 / len(dic_atms)) / f_d) ** 2

        if verbose:
            print 'BONDS'
            print dis_dic
            print 'COORDINATION'
            print coord

        for i in dis_dic.keys():
            i1 = dis_dic[i][2][0]
            i2 = dis_dic[i][2][1]

            #ei = Z[atms[i1].symbol] / covalent_radii[atms[i1].number]
            #ej = Z[atms[i2].symbol] / covalent_radii[atms[i2].number]
            ei = valence(spc.symbols[i1]) / covalent_radius(spc.symbols[i1])
            ej = valence(spc.symbols[i2]) / covalent_radius(spc.symbols[i2])


            #print 'bond ->', sqrt(ei * ej), (coord[i1] * coord[i2]), dis_dic[i][0]

            #        print atms[i1].symbol, ei, atms[i2].symbol, ej
            sij = sqrt(ei * ej) / (coord[i1] * coord[i2]) / dis_dic[i][0]
            #print 'sij', sij
            #print 'num_i_j_bonds', dis_dic[i][1]

            tot += dis_dic[i][1]
            x *= sij * dis_dic[i][1]
            #print 'x', x

        if verbose:
            print("V:", volume)
            print("f:", f)
            print("x:", x)

        #print 'len_bonds', len(dis_dic)
        #print 'hardness_value =', c_hard, volume, (len(dis_dic)), (  x ** (1. / (len(dis_dic)))), exp(-sigma * f)
        hardness_value = c_hard / volume * (len(dis_dic) * x ** (1. / (len(dis_dic)))) * exp(-sigma * f)

        if verbose:
            print hardness_value

        return round(hardness_value, 3)
Ejemplo n.º 10
0
    def hardness(self, noupdate=False, verbose=False, tolerance=1):
        """
        Calculates the hardness of a structure based in the model of XX
        We use the covalent radii from pychemia.utils.periodic.
        If noupdate=False
        the Laplacian matrix method is not used and rcut is 2*max(cov_radii)

        :param noupdate: (bool) If True, the Laplacian method is used
        :param verbose: (bool) To print some debug info
        :param tolerance: (float)

        :rtype : (float)
        """

        bonds, coordination, all_distances, tolerances = self.get_bonds_coordination(tolerance=tolerance, ensure_conectivity=True)

        if verbose:
            print 'BONDS'
            print bonds
            print 'COORDINATION'
            print coordination

        sigma = 3.0
        c_hard = 1300.0
        x = 1.
        tot = 0.0
        f_d = 0.0
        f_n = 1.0
        atomicnumbers = atomic_number(self.get_composition().species)

        if verbose:
            print atomicnumbers

        for i in atomicnumbers:
            f_d += valence(i) / covalent_radius(i)
            f_n *= valence(i) / covalent_radius(i)
        f = 1.0 - (len(atomicnumbers) * f_n ** (1.0 / len(atomicnumbers)) / f_d) ** 2

        # Selection of different bonds
        diff_bonds = _np.unique(_np.array(reduce(lambda x, y: x+y, bonds)))
        for i in diff_bonds:
            i1 = all_distances[i]['pair'][0]
            i2 = all_distances[i]['pair'][1]

            ei = valence(self.symbols[i1]) / covalent_radius(self.symbols[i1])
            ej = valence(self.symbols[i2]) / covalent_radius(self.symbols[i2])
            #print 'bond ->', sqrt(ei * ej), (coordination[i1] * coordination[i2]), all_distances[i]['distance']

            sij = sqrt(ei * ej) / (coordination[i1] * coordination[i2]) / all_distances[i]['distance']
            num_i_j_bonds = len([j for j in diff_bonds if i1 in all_distances[j]['pair'] and i2 in all_distances[j]['pair']])
            #print 'sij', sij
            #print 'num_i_j_bonds', num_i_j_bonds
            tot += num_i_j_bonds
            x *= sij
            #print 'x', x

        if verbose:
            print("V:", self.volume)
            print("f:", f)
            print("x:", x)

        #print 'len_bonds', len(diff_bonds)
        #print 'hardness_value =', c_hard, self.volume, (len(diff_bonds)), ( x ** (1. / (len(diff_bonds)))), exp(-sigma * f)
        hardness_value = c_hard / self.volume * (len(diff_bonds) * x ** (1. / (len(diff_bonds)))) * exp(-sigma * f)

        if verbose:
            print hardness_value

        return round(hardness_value, 3)
Ejemplo n.º 11
0
 def valence_electrons(self):
     ret = 0
     for key, value in self.composition.items():
         ret += value * valence(key)
     return ret