Esempio n. 1
0
    def distance(self, entry_id, entry_jd, rcut=50):
        """
        Return a measure of the distance between two clusters by computing
        a n-dimensional vector of the distances between each atom to the
        origin and

        :param rcut:
        :param entry_id: The id of one population entry
        :param entry_jd: The id of another population entry
        :return: (int) The distance between two clusters
        """

        ids_pair = tuple(np.sort([entry_id, entry_jd]))
        distance_entry = self.distancer.get_distance(ids_pair)

        if distance_entry is None:
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = ClusterAnalysis(structure)
                    x, ys = analysis.discrete_radial_distribution_function()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(k[0])
                        atomic_number2 = atomic_number(k[1])
                        pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                        self.fingerprinter.set_fingerprint(fingerprint)
                    else:
                        self.fingerprinter.update(entry_ijd, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[entry_ijd] = self.fingerprinter.get_fingerprint(entry_ijd)

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    vect1 = fingerprints[entry_id][pair]
                    vect2 = fingerprints[entry_jd][pair]
                    if len(vect1) < len(vect2):
                        tmp = np.zeros(len(vect2))
                        tmp[:len(vect1)] = vect1
                        vect1 = tmp
                    elif len(vect1) > len(vect2):
                        tmp = np.zeros(len(vect1))
                        tmp[:len(vect2)] = vect2
                        vect2 = tmp
                    uvect1 = unit_vector(vect1)
                    uvect2 = unit_vector(vect2)
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.distancer.set_distance(ids_pair, distance)
        else:
            distance = distance_entry['distance']
        return distance
Esempio n. 2
0
    def all_distances_by_species(self):

        all_distances = self.all_distances()
        ret = OrderedDict()

        atom_numbers = atomic_number(self.structure.species)
        a = list(itertools.combinations_with_replacement(atom_numbers, 2))
        keys = sorted([tuple(sorted(list(x))) for x in a])
        for key in keys:
            ret[key] = []

        for ipair in all_distances:
            key = tuple(
                sorted(
                    atomic_number([
                        self.structure.symbols[ipair[0]],
                        self.structure.symbols[ipair[1]]
                    ])))
            if self.structure.is_periodic:
                ret[key] = np.concatenate(
                    (ret[key], all_distances[ipair]['distance']))
            else:
                ret[key].append(all_distances[ipair])

        # Sorting arrays
        for key in ret:
            ret[key].sort()
            ret[key] = np.array(ret[key])

        return ret
Esempio n. 3
0
    def distance(self, entry_id, entry_jd, rcut=50):

        ids_pair = [entry_id, entry_jd]
        ids_pair.sort()
        distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair},
                                                         {'distance': 1})
        self.pcdb.db.distances.create_index([("pair", ASCENDING)])

        if distance_entry is None:
            print('Distance not in DB')
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd
                                                       }) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = StructureAnalysis(structure, radius=rcut)
                    x, ys = analysis.fp_oganov()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(structure.species[k[0]])
                        atomic_number2 = atomic_number(structure.species[k[1]])
                        pair = '%06d' % min(
                            atomic_number1 * 1000 + atomic_number2,
                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd
                                                           }) is None:
                        self.pcdb.db.fingerprints.insert(fingerprint)
                    else:
                        self.pcdb.db.fingerprints.update({'_id': entry_ijd},
                                                         fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[
                        entry_ijd] = self.pcdb.db.fingerprints.find_one(
                            {'_id': entry_ijd})

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    uvect1 = unit_vector(fingerprints[entry_id][pair])
                    uvect2 = unit_vector(fingerprints[entry_jd][pair])
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.pcdb.db.distances.insert({
                'pair': ids_pair,
                'distance': distance
            })
        else:
            distance = distance_entry['distance']
        return distance
Esempio n. 4
0
 def species_encoded(self, base):
     ret = 0
     i = 0
     for atom_number in sorted(atomic_number(self.species)):
         ret += atom_number * (base ** i)
         i += 1
     return ret
Esempio n. 5
0
    def match(self):

        species = self.structure1.species
        species = list(np.array(species)[np.array(atomic_number(species)).argsort()])

        permutation = np.zeros(len(self.structure1.positions), dtype=int)
        num = 0
        for ispecie in species:

            pos1 = self.structure1.positions[np.array(self.structure1.symbols) == ispecie]
            pos2 = self.structure2.positions[np.array(self.structure2.symbols) == ispecie]
            dm = scipy.spatial.distance_matrix(pos1, pos2)

            match_list = np.zeros(len(pos1))
            maxdis = np.max(dm.flatten())
            for i in range(len(pos1)):
                match = dm[i, :].argmin()
                # print " %3s %3d %9.3f %9.3f %9.3f" % (ispecie, match, np.linalg.norm(pos1[i]),
                # np.linalg.norm(pos1[match]), dm[i,match])
                match_list[i] = match
                dm[:, match] = maxdis + 1

            match_list += num
            permutation[num:num + len(pos1)] = match_list
            num += len(pos1)

        # print permutation
        self.structure2.sort_sites_using_list(permutation)
Esempio n. 6
0
 def species_encoded(self, base):
     ret = 0
     i = 0
     for atom_number in sorted(atomic_number(self.species)):
         ret += atom_number * (base**i)
         i += 1
     return ret
Esempio n. 7
0
 def species_hex(self):
     spec_hex = 0
     i = 0
     for atom_number in sorted(atomic_number(self.species)):
         spec_hex += atom_number * (256 ** i)
         i += 1
     return spec_hex
Esempio n. 8
0
    def center_mass(self, list_of_atoms=None):
        """
        Computes the center of mass (CM) of the XYZ object or
        a partial list of atoms. The default is to compute the
        CM of all the atoms in the object, if a list
        is enter only those in the list will be included for the CM
        Return the CM as a numpy array
        """
        if list_of_atoms is None:
            list_of_atoms = range(self.natom)

        total_mass = 0.0
        center_of_mass = np.zeros(3)
        if self.natom == 0:
            return center_of_mass

        atomicnumber = atomic_number(list(self.symbols))

        for i in range(self.natom):
            if i in list_of_atoms:
                total_mass = total_mass + mass(atomicnumber[i])
                center_of_mass = center_of_mass + mass(
                    atomicnumber[i]) * self.positions[i]

        return center_of_mass / total_mass
Esempio n. 9
0
    def match(self):

        species = self.structure1.species
        species = list(np.array(species)[np.array(atomic_number(species)).argsort()])

        permutation = np.zeros(len(self.structure1.positions))
        num = 0
        for ispecie in species:

            pos1 = self.structure1.positions[np.array(self.structure1.symbols) == ispecie]
            pos2 = self.structure2.positions[np.array(self.structure2.symbols) == ispecie]
            dm = scipy.spatial.distance_matrix(pos1, pos2)

            match_list = np.zeros(len(pos1))
            maxdis = np.max(dm.flatten())
            for i in range(len(pos1)):
                match = dm[i, :].argmin()
                # print " %3s %3d %9.3f %9.3f %9.3f" % (ispecie, match, np.linalg.norm(pos1[i]),
                # np.linalg.norm(pos1[match]), dm[i,match])
                match_list[i] = match
                dm[:, match] = maxdis + 1

            match_list += num
            permutation[num:num + len(pos1)] = match_list
            num += len(pos1)

        # print permutation
        self.structure2.sort_sites_using_list(list(permutation))
Esempio n. 10
0
    def create_pov(self):

        ret = """
#version 3.7;
#include "colors.inc"    // The include files contain
#include "stones.inc"    // pre-defined scene elements
#include "glass.inc"
background{rgb 0}

"""
        if self.structure.is_crystal:
            self.distance = max(self.structure.lattice.lengths)
        else:
            self.distance = 10

        ret += "#declare r=%7.3f;\n #declare s=%7.3f;" % (self.distance, self.distance)

        ret += "camera {\n"
        ret += "\tlocation <%7.3f, %7.3f, %7.3f>\n" % (1.3 * self.distance, 1.3 * self.distance, -1.3 * self.distance)
        ret += "\tlook_at  <%7.3f, %7.3f, %7.3f>\n" % tuple(0.5 * sum(self.structure.cell[:]))
        ret += "}\n\n"

        if self.structure.nsites > 0:
            d = self.distance
            ret += "light_source { <%7.3f, %7.3f, %7.3f> color White}\n" % (2 * d, 2 * d, 2 * d)

        for imagx in np.arange(-1, 2):
            for imagy in np.arange(-1, 2):
                for imagz in np.arange(-1, 2):

                    for site in self.structure:
                        for symbol in site.symbols:
                            cell = self.structure.cell
                            x = site.position[0] - imagx * cell[0, 0] - imagy * cell[1, 0] - imagz * cell[2, 0]
                            y = site.position[1] - imagx * cell[0, 1] - imagy * cell[1, 1] - imagz * cell[2, 1]
                            z = site.position[2] - imagx * cell[0, 2] - imagy * cell[1, 2] - imagz * cell[2, 2]
                            if (x - self.distance) ** 2 + (y - self.distance) ** 2 + (z + self.distance) ** 2 < 2:
                                continue
                            cr = 0.5 * covalent_radius(symbol)
                            rgb = cpk_colors[atomic_number(symbol)]
                            color = 'rgb < %7.3f, %7.3f, %7.3f>' % (rgb[0], rgb[1], rgb[2])
                            ret += "sphere {\n"
                            ret += "\t<%7.3f, %7.3f, %7.3f>, %7.3f\n\ttexture {\n" % (x, y, z, cr)
                            ret += "\t\tpigment { color %s filter 0.4 transmit %7.3f}\n" % \
                                   (color, 1 - 0.9 * np.exp(-0.1 * (abs(imagx) + abs(imagy) + abs(imagz))))
                            ret += "\t\tnormal { bumps 0.8 scale 0.1 }\n\t\tfinish { phong %7.3f }\n\t}\n}\n\n" % \
                                   np.exp(-0.1 * (abs(imagx) + abs(imagy) + abs(imagz)))

                            if self.structure.nsites <= 0:
                                ret += "light_source { <%7.3f, %7.3f, %7.3f> color White}\n" % (x, y, z)

        ret += """union{
#include "cell.pov"
    scale 1
    rotate <0, 0, 0>
    pigment{rgb <0.3,0.3,0.9>} finish{phong 0.9 ambient 0.42 reflection 0.1}
}
"""
        return ret
Esempio n. 11
0
    def test(self):
        """
        DocTests exceptions (pychemia.utils)                         :
        """
        from pychemia.utils.periodic import atomic_number
        with self.assertRaises(Exception) as context:
            atomic_number(['H', u'A'])
        # self.assertTrue(u'Atomic symbol not found' == context.exception)

        from pychemia.utils.computing import read_file
        with self.assertRaises(Exception) as context:
            read_file('/dev/abc')
        # self.assertTrue('Could not open file: /dev/abc' in context.exception)

        from pychemia.utils.computing import get_float
        with self.assertRaises(Exception) as context:
            get_float('3i')
Esempio n. 12
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
Esempio n. 13
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
Esempio n. 14
0
    def distance(self, entry_id, entry_jd, rcut=50):

        ids_pair = [entry_id, entry_jd]
        ids_pair.sort()
        distance_entry = self.pcdb.db.distances.find_one({'pair': ids_pair}, {'distance': 1})
        self.pcdb.db.distances.create_index([("pair", pymongo.ASCENDING)])

        if distance_entry is None:
            print('Distance not in DB')
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = StructureAnalysis(structure, radius=rcut)
                    x, ys = analysis.fp_oganov()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(structure.species[k[0]])
                        atomic_number2 = atomic_number(structure.species[k[1]])
                        pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.pcdb.db.fingerprints.find_one({'_id': entry_ijd}) is None:
                        self.pcdb.db.fingerprints.insert(fingerprint)
                    else:
                        self.pcdb.db.fingerprints.update({'_id': entry_ijd}, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[entry_ijd] = self.pcdb.db.fingerprints.find_one({'_id': entry_ijd})

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    uvect1 = unit_vector(fingerprints[entry_id][pair])
                    uvect2 = unit_vector(fingerprints[entry_jd][pair])
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.pcdb.db.distances.insert({'pair': ids_pair, 'distance': distance})
        else:
            distance = distance_entry['distance']
        return distance
Esempio n. 15
0
    def sort_sites(self):

        # First: Sort sites using the distance to the origin
        sorted_indices = np.array([np.linalg.norm(self.positions[i]) for i in range(self.nsites)]).argsort()
        # print sorted_indices
        self.sort_sites_using_list(sorted_indices)

        # Second: Sort again using the atomic number
        if len(self.species) > 1:
            sorted_indices = np.array([atomic_number(x) for x in self.symbols]).argsort()
            self.sort_sites_using_list(sorted_indices)
Esempio n. 16
0
    def view_projections(self):
        """
        Show the 3 projections of the molecule in a single
        figure
        """
        import matplotlib.patches as mpatches
        from matplotlib.collections import PatchCollection
        from matplotlib.pylab import subplots

        fig, ax = subplots(nrows=1, ncols=3)
        fig.set_size_inches(15, 4)
        color = ['r', 'g', 'b']
        j = 0

        structure = self.get_structure()

        for i in structure.cell:
            ax[0].plot([0, i[0]], [0, i[1]], color[j] + '-', lw=3)
            ax[1].plot([0, i[1]], [0, i[2]], color[j] + '-', lw=3)
            ax[2].plot([0, i[2]], [0, i[0]], color[j] + '-', lw=3)
            j += 1

        proj = [[0, 1], [1, 2], [2, 0]]
        labels = [['x', 'y'], ['y', 'z'], ['z', 'x']]

        for j in range(3):

            patches = []
            for i in range(structure.natom):
                radius = 0.5 * covalent_radius(
                    atomic_number(structure.symbols[i]))
                pos = structure.positions[i]
                art = mpatches.Circle((pos[proj[j][0]], pos[proj[j][1]]),
                                      radius,
                                      fc='g',
                                      ec='g')
                patches.append(art)

            collection = PatchCollection(patches, color='k', alpha=0.5)

            col = ax[j].add_collection(collection)
            ax[j].set_xlim(
                min(structure.positions[:, proj[j][0]]) - 1,
                max(structure.positions[:, proj[j][0]]) + 1)
            ax[j].set_ylim(
                min(structure.positions[:, proj[j][1]]) - 1,
                max(structure.positions[:, proj[j][1]]) + 1)
            ax[j].set_aspect('equal', adjustable='datalim')
            ax[j].set_xlabel(labels[j][0])
            ax[j].set_ylabel(labels[j][1])

        return fig, ax
Esempio n. 17
0
def write_geometry_bas(structure, filename):
    wf = open(filename, 'w')
    wf.write('%3d\n' % structure.natom)
    for i in range(structure.natom):
        if structure.is_periodic:
            x = structure.reduced[i, 0]
            y = structure.reduced[i, 1]
            z = structure.reduced[i, 2]
        else:
            x = structure.positions[i, 0]
            y = structure.positions[i, 1]
            z = structure.positions[i, 2]
        wf.write('%3d %13.7f %13.7f %13.7f\n' % (atomic_number(structure.symbols[i]), x, y, z))
    wf.close()
Esempio n. 18
0
    def sort_sites(self):

        # First: Sort sites using the distance to the origin
        sorted_indices = np.array([
            np.linalg.norm(self.positions[i]) for i in range(self.nsites)
        ]).argsort()
        # print sorted_indices
        self.sort_sites_using_list(sorted_indices)

        # Second: Sort again using the atomic number
        if len(self.species) > 1:
            sorted_indices = np.array([atomic_number(x)
                                       for x in self.symbols]).argsort()
            self.sort_sites_using_list(sorted_indices)
Esempio n. 19
0
def write_geometry_bas(structure, filename):
    wf = open(filename, 'w')
    wf.write('%3d\n' % structure.natom)
    for i in range(structure.natom):
        if structure.is_periodic:
            x = structure.reduced[i, 0]
            y = structure.reduced[i, 1]
            z = structure.reduced[i, 2]
        else:
            x = structure.positions[i, 0]
            y = structure.positions[i, 1]
            z = structure.positions[i, 2]
        wf.write('%3d %13.7f %13.7f %13.7f\n' % (atomic_number(structure.symbols[i]), x, y, z))
    wf.close()
Esempio n. 20
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
Esempio n. 21
0
    def all_distances_by_species(self):

        all_distances = self.all_distances()
        ret = OrderedDict()

        atom_numbers = atomic_number(self.structure.species)
        a = list(itertools.combinations_with_replacement(atom_numbers, 2))
        keys=sorted([tuple(sorted(list(x))) for x in a])
        for key in keys:
            ret[key] = []

        for ipair in all_distances:
            key = tuple(sorted(atomic_number([self.structure.symbols[ipair[0]], self.structure.symbols[ipair[1]]])))
            if self.structure.is_periodic:
                ret[key] = np.concatenate((ret[key], all_distances[ipair]['distance']))
            else:
                ret[key].append(all_distances[ipair])

        # Sorting arrays
        for key in ret:
            ret[key].sort()
            ret[key] = np.array(ret[key])

        return ret
Esempio n. 22
0
    def species_encoded(self, base):
        """Encode the list of species with a number

        :return: Encodes the species as a number.
        :param base: Integer used as base for encoding.
        :rtype: int

        >>> cp = Composition('H2O')
        >>> cp.species_encoded(100)
        801
        """
        ret = 0
        i = 0
        for atom_number in sorted(atomic_number(self.species)):
            ret += atom_number * (base**i)
            i += 1
        return ret
Esempio n. 23
0
    def view_projections(self):
        """
        Show the 3 projections of the molecule in a single
        figure
        """
        import matplotlib.patches as mpatches
        from matplotlib.collections import PatchCollection
        from matplotlib.pylab import subplots

        fig, ax = subplots(nrows=1, ncols=3)
        fig.set_size_inches(15, 4)
        color = ['r', 'g', 'b']
        j = 0

        structure = self.get_structure()

        for i in structure.cell:
            ax[0].plot([0, i[0]], [0, i[1]], color[j] + '-', lw=3)
            ax[1].plot([0, i[1]], [0, i[2]], color[j] + '-', lw=3)
            ax[2].plot([0, i[2]], [0, i[0]], color[j] + '-', lw=3)
            j += 1

        proj = [[0, 1], [1, 2], [2, 0]]
        labels = [['x', 'y'], ['y', 'z'], ['z', 'x']]

        for j in range(3):

            patches = []
            for i in range(structure.natom):
                radius = 0.5 * covalent_radius(atomic_number(structure.symbols[i]))
                pos = structure.positions[i]
                art = mpatches.Circle((pos[proj[j][0]], pos[proj[j][1]]), radius, fc='g', ec='g')
                patches.append(art)

            collection = PatchCollection(patches, color='k', alpha=0.5)

            col = ax[j].add_collection(collection)
            ax[j].set_xlim(min(structure.positions[:, proj[j][0]]) - 1, max(structure.positions[:, proj[j][0]]) + 1)
            ax[j].set_ylim(min(structure.positions[:, proj[j][1]]) - 1, max(structure.positions[:, proj[j][1]]) + 1)
            ax[j].set_aspect('equal', adjustable='datalim')
            ax[j].set_xlabel(labels[j][0])
            ax[j].set_ylabel(labels[j][1])

        return fig, ax
Esempio n. 24
0
    def from_structure(self, structure):
        """
        Set input variables for a given structure

        :param structure: (pychemia.Structure) Structure to set ABINIT input variables
        :return:
        """
        natom = structure.natom
        ntypat = len(structure.species)
        znucl = atomic_number(structure.species)
        typat_dict = {}
        index = 1
        for ispec in structure.species:
            typat_dict[ispec] = index
            index += 1
        typat = [typat_dict[i] for i in structure.symbols]
        xcart = angstrom_bohr * structure.positions.flatten()
        acell = angstrom_bohr * np.array(structure.lattice.lengths)
        rprim = unit_vectors(structure.cell).T.flatten()
        for i in ['natom', 'ntypat', 'znucl', 'typat', 'xcart', 'acell', 'rprim']:
            self.set_value(i, eval(i))
Esempio n. 25
0
    def from_structure(self, structure):
        """
        Set input variables for a given structure

        :param structure: (pychemia.Structure) Structure to set ABINIT input variables
        :return:
        """
        natom = structure.natom
        ntypat = len(structure.species)
        znucl = atomic_number(structure.species)
        typat_dict = {}
        index = 1
        for ispec in structure.species:
            typat_dict[ispec] = index
            index += 1
        typat = [typat_dict[i] for i in structure.symbols]
        xcart = angstrom_bohr * structure.positions.flatten()
        acell = angstrom_bohr * np.array(structure.lattice.lengths)
        rprim = unit_vectors(structure.cell).T.flatten()
        for i in ['natom', 'ntypat', 'znucl', 'typat', 'xcart', 'acell', 'rprim']:
            self.set_value(i, eval(i))
Esempio n. 26
0
    def center_mass(self, list_of_atoms=None):
        """
        Computes the center of mass (CM) of the XYZ object or
        a partial list of atoms. The default is to compute the
        CM of all the atoms in the object, if a list
        is enter only those in the list will be included for the CM
        Return the CM as a numpy array
        """
        if list_of_atoms is None:
            list_of_atoms = range(self.natom)

        total_mass = 0.0
        center_of_mass = np.zeros(3)
        if self.natom == 0:
            return center_of_mass

        atomicnumber = atomic_number(list(self.symbols))

        for i in range(self.natom):
            if i in list_of_atoms:
                total_mass = total_mass + mass(atomicnumber[i])
                center_of_mass = center_of_mass + mass(atomicnumber[i]) * self.positions[i]

        return center_of_mass / total_mass
Esempio n. 27
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)
Esempio n. 28
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
Esempio n. 29
0
    def distance(self, entry_id, entry_jd, rcut=50):
        """
        Return a measure of the distance between two clusters by computing
        a n-dimensional vector of the distances between each atom to the
        origin and

        :param rcut:
        :param entry_id: The id of one population entry
        :param entry_jd: The id of another population entry
        :return: (int) The distance between two clusters
        """

        ids_pair = tuple(np.sort([entry_id, entry_jd]))
        distance_entry = self.distancer.get_distance(ids_pair)

        if distance_entry is None:
            fingerprints = {}
            for entry_ijd in [entry_id, entry_jd]:

                if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                    structure = self.get_structure(entry_ijd)
                    analysis = ClusterAnalysis(structure)
                    x, ys = analysis.discrete_radial_distribution_function()
                    fingerprint = {'_id': entry_ijd}
                    for k in ys:
                        atomic_number1 = atomic_number(k[0])
                        atomic_number2 = atomic_number(k[1])
                        pair = '%06d' % min(
                            atomic_number1 * 1000 + atomic_number2,
                            atomic_number2 * 1000 + atomic_number1)
                        fingerprint[pair] = list(ys[k])

                    if self.fingerprinter.get_fingerprint(entry_ijd) is None:
                        self.fingerprinter.set_fingerprint(fingerprint)
                    else:
                        self.fingerprinter.update(entry_ijd, fingerprint)
                    fingerprints[entry_ijd] = fingerprint
                else:
                    fingerprints[
                        entry_ijd] = self.fingerprinter.get_fingerprint(
                            entry_ijd)

            dij = []
            for pair in fingerprints[entry_id]:
                if pair in fingerprints[entry_jd] and pair != '_id':
                    vect1 = fingerprints[entry_id][pair]
                    vect2 = fingerprints[entry_jd][pair]
                    if len(vect1) < len(vect2):
                        tmp = np.zeros(len(vect2))
                        tmp[:len(vect1)] = vect1
                        vect1 = tmp
                    elif len(vect1) > len(vect2):
                        tmp = np.zeros(len(vect1))
                        tmp[:len(vect2)] = vect2
                        vect2 = tmp
                    uvect1 = unit_vector(vect1)
                    uvect2 = unit_vector(vect2)
                    dij.append(0.5 * (1.0 - np.dot(uvect1, uvect2)))
            distance = float(np.mean(dij))
            self.distancer.set_distance(ids_pair, distance)
        else:
            distance = distance_entry['distance']
        return distance
Esempio n. 30
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)
Esempio n. 31
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
Esempio n. 32
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)
Esempio n. 33
0
def worker(db_settings, entry_id, workdir, target_forces, relaxator_params):
    pcdb = get_database(db_settings)
    pcm_log.info('[%s]: Starting relaxation. Target forces: %7.3e' %
                 (str(entry_id), target_forces))

    if pcdb.is_locked(entry_id):
        return
    else:
        pcdb.lock(entry_id)
    structure = pcdb.get_structure(entry_id)
    structure = structure.scale()
    print('relaxator_params', relaxator_params)
    relaxer = IonRelaxation(structure,
                            workdir=workdir,
                            target_forces=target_forces,
                            waiting=False,
                            binary=relaxator_params['binary'],
                            encut=1.3,
                            kp_grid=None,
                            kp_density=1E4,
                            relax_cell=True,
                            max_calls=10)
    print('relaxing on:', relaxer.workdir)
    relaxer.run(relaxator_params['nmpiparal'])
    pcm_log.info('[%s]: Finished relaxation. Target forces: %7.3e' %
                 (str(entry_id), target_forces))

    filename = workdir + os.sep + 'OUTCAR'
    if os.path.isfile(filename):

        forces, stress, total_energy = relaxer.get_forces_stress_energy()

        if forces is not None:
            magnitude_forces = np.apply_along_axis(np.linalg.norm, 1, forces)
            print('Forces: Max: %9.3e Avg: %9.3e' %
                  (np.max(magnitude_forces), np.average(magnitude_forces)))
            print('Stress: ', np.max(np.abs(stress.flatten())))

        if forces is None:
            pcm_log.error('No forces found on %s' % filename)
        if stress is None:
            pcm_log.error('No stress found on %s' % filename)
        if total_energy is None:
            pcm_log.error('No total_energy found on %s' % filename)

        new_structure = relaxer.get_final_geometry()

        if forces is not None and stress is not None and total_energy is not None and new_structure is not None:
            pcm_log.info('[%s]: Updating properties' % str(entry_id))
            pcdb.update(entry_id, structure=new_structure)
            te = total_energy
            pcdb.entries.update({'_id': entry_id}, {
                '$set': {
                    'status.relaxation':
                    'succeed',
                    'status.target_forces':
                    target_forces,
                    'properties.forces':
                    generic_serializer(forces),
                    'properties.stress':
                    generic_serializer(stress),
                    'properties.energy':
                    te,
                    'properties.energy_pa':
                    te / new_structure.natom,
                    'properties.energy_pf':
                    te / new_structure.get_composition().gcd
                }
            })

            # Fingerprint
            # Update the fingerprints only if the two structures are really different
            diffnatom = structure.natom != new_structure.natom
            diffcell = np.max(
                np.abs((structure.cell - new_structure.cell).flatten()))
            diffreduced = np.max(
                np.abs((structure.reduced - new_structure.reduced).flatten()))
            if diffnatom != 0 or diffcell > 1E-7 or diffreduced > 1E-7:
                analysis = StructureAnalysis(new_structure, radius=50)
                x, ys = analysis.fp_oganov(delta=0.01, sigma=0.01)
                fingerprint = {'_id': entry_id}
                for k in ys:
                    atomic_number1 = atomic_number(new_structure.species[k[0]])
                    atomic_number2 = atomic_number(new_structure.species[k[1]])
                    pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                        atomic_number2 * 1000 + atomic_number1)
                    fingerprint[pair] = list(ys[k])

                if pcdb.db.fingerprints.find_one({'_id': entry_id}) is None:
                    pcdb.db.fingerprints.insert(fingerprint)
                else:
                    pcdb.db.fingerprints.update({'_id': entry_id}, fingerprint)
            else:
                pcm_log.debug('Original and new structures are very similar.')
                pcm_log.debug('Max diff cell: %10.3e' % np.max(
                    np.absolute(
                        (structure.cell - new_structure.cell).flatten())))
                if structure.natom == new_structure.natom:
                    pcm_log.debug(
                        'Max diff reduced coordinates: %10.3e' % np.max(
                            np.absolute((structure.reduced -
                                         new_structure.reduced).flatten())))

        else:
            pcdb.entries.update({'_id': entry_id},
                                {'$set': {
                                    'status.relaxation': 'failed'
                                }})
            pcm_log.error(
                'Bad data after relaxation. Tagging relaxation as failed')
    else:
        pcm_log.error('ERROR: File not found %s' % filename)
    pcm_log.info('[%s]: Unlocking the entry' % str(entry_id))
    pcdb.unlock(entry_id)
def worker(db_settings, entry_id, workdir, target_forces, relaxator_params):
    pcdb = get_database(db_settings)
    pcm_log.info('[%s]: Starting relaxation. Target forces: %7.3e' % (str(entry_id), target_forces))

    if pcdb.is_locked(entry_id):
        return
    else:
        pcdb.lock(entry_id)
    structure = pcdb.get_structure(entry_id)
    structure = structure.scale()
    print('relaxator_params', relaxator_params)
    relaxer = IonRelaxation2(structure, workdir=workdir, target_forces=target_forces, waiting=False,
                             binary=relaxator_params['binary'], encut=1.3, kp_grid=None, kp_density=1E4,
                             relax_cell=True)
    print('relaxing on:', relaxer.workdir)
    relaxer.run(relaxator_params['nmpiparal'])
    pcm_log.info('[%s]: Finished relaxation. Target forces: %7.3e' % (str(entry_id), target_forces))

    filename = workdir + os.sep + 'OUTCAR'
    if os.path.isfile(filename):

        forces, stress, total_energy = relaxer.get_forces_stress_energy()

        if forces is not None:
            magnitude_forces = np.apply_along_axis(np.linalg.norm, 1, forces)
            print('Forces: Max: %9.3e Avg: %9.3e' % (np.max(magnitude_forces), np.average(magnitude_forces)))
            print('Stress: ', np.max(np.abs(stress.flatten())))

        if forces is None:
            pcm_log.error('No forces found on %s' % filename)
        if stress is None:
            pcm_log.error('No stress found on %s' % filename)
        if total_energy is None:
            pcm_log.error('No total_energy found on %s' % filename)

        new_structure = relaxer.get_final_geometry()

        if forces is not None and stress is not None and total_energy is not None and new_structure is not None:
            pcm_log.info('[%s]: Updating properties' % str(entry_id))
            pcdb.update(entry_id, structure=new_structure)
            te = total_energy
            pcdb.entries.update({'_id': entry_id},
                                {'$set': {'status.relaxation': 'succeed',
                                          'status.target_forces': target_forces,
                                          'properties.forces': generic_serializer(forces),
                                          'properties.stress': generic_serializer(stress),
                                          'properties.energy': te,
                                          'properties.energy_pa': te / new_structure.natom,
                                          'properties.energy_pf': te / new_structure.get_composition().gcd}})

            # Fingerprint
            # Update the fingerprints only if the two structures are really different
            diffnatom = structure.natom != new_structure.natom
            diffcell = np.max(np.abs((structure.cell - new_structure.cell).flatten()))
            diffreduced = np.max(np.abs((structure.reduced - new_structure.reduced).flatten()))
            if diffnatom != 0 or diffcell > 1E-7 or diffreduced > 1E-7:
                analysis = StructureAnalysis(new_structure, radius=50)
                x, ys = analysis.fp_oganov(delta=0.01, sigma=0.01)
                fingerprint = {'_id': entry_id}
                for k in ys:
                    atomic_number1 = atomic_number(new_structure.species[k[0]])
                    atomic_number2 = atomic_number(new_structure.species[k[1]])
                    pair = '%06d' % min(atomic_number1 * 1000 + atomic_number2,
                                        atomic_number2 * 1000 + atomic_number1)
                    fingerprint[pair] = list(ys[k])

                if pcdb.db.fingerprints.find_one({'_id': entry_id}) is None:
                    pcdb.db.fingerprints.insert(fingerprint)
                else:
                    pcdb.db.fingerprints.update({'_id': entry_id}, fingerprint)
            else:
                pcm_log.debug('Original and new structures are very similar.')
                pcm_log.debug('Max diff cell: %10.3e' % np.max(np.absolute((structure.cell -
                                                                            new_structure.cell).flatten())))
                if structure.natom == new_structure.natom:
                    pcm_log.debug('Max diff reduced coordinates: %10.3e' %
                                  np.max(np.absolute((structure.reduced - new_structure.reduced).flatten())))

        else:
            pcdb.entries.update({'_id': entry_id}, {'$set': {'status.relaxation': 'failed'}})
            pcm_log.error('Bad data after relaxation. Tagging relaxation as failed')
    else:
        pcm_log.error('ERROR: File not found %s' % filename)
    pcm_log.info('[%s]: Unlocking the entry' % str(entry_id))
    pcdb.unlock(entry_id)
Esempio n. 35
0
 def species_bin(self):
     spec_bin = 0
     for i in atomic_number(self.species):
         spec_bin += 2 ** i
     return spec_bin
Esempio n. 36
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)