Esempio n. 1
0
    def build_grid(self, start, num, ncores=1):
        """ Build the mapped 2-body potential. 
        Calculates the energy predicted by the GP for two atoms at distances that range from
        start to r_cut, for a total of num points. These energies are stored and a 1D spline
        interpolation is created, which can be used to predict the energy and, through its
        analytic derivative, the force associated to any couple of atoms.
        The total force or local energy can then be calculated for any atom by summing the 
        pairwise contributions of every other atom within a cutoff distance r_cut.
        The prediction is done by the ``calculator`` module which is built to work within 
        the ase python package.

        Args:
            start (float): smallest interatomic distance for which the energy is predicted
                by the GP and stored inn the 2-body mapped potential
            num (int): number of points to use in the grid of the mapped potential   

        """

        self.grid_start = start
        self.grid_num = num

        dists = np.linspace(start, self.r_cut, num)

        confs = np.zeros((num, 1, 5))
        confs[:, 0, 0] = dists
        confs[:, 0, 3], confs[:, 0, 4] = self.element, self.element
        confs = list(confs)

        grid_data = self.gp.predict_energy(confs, ncores=ncores, mapping=True)
        if self.rep_sig:
            grid_data += utility.get_repulsive_energies(confs,
                                                        self.rep_sig,
                                                        mapping=True)
        self.grid = interpolation.Spline1D(dists, grid_data)
Esempio n. 2
0
File: eam.py Progetto: kcl-tscm/mff
    def build_grid(self, num, ncores=1):
        """ Build the mapped eam potential. 
        Calculates the energy predicted by the GP for a configuration which eam descriptor
        is evalued between start and end. These energies are stored and a 1D spline
        interpolation is created, which can be used to predict the energy and, through its
        analytic derivative, the force associated to any embedded atom.
        The prediction is done by the ``calculator`` module which is built to work within 
        the ase python package.

        Args:
            num (int): number of points to use in the grid of the mapped potential   
            ncores (int): number of CPUs to use for the gram matrix evaluation
        """

        if 'force' in self.gp.fitted:
            self.grid_start = 3.0 * \
                get_max_eam(self.gp.X_train_, self.r_cut,
                            self.gp.kernel.theta[2])
        else:
            self.grid_start = 3.0 * \
                 get_max_eam_energy(self.gp.X_glob_train_, self.r_cut,
                             self.gp.kernel.theta[2])

        self.grid_end = 0
        self.grid_num = num

        dists = list(np.linspace(self.grid_start, self.grid_end,
                                 self.grid_num))

        for el in self.elements:
            grid_data = self.gp.predict_energy(dists,
                                               ncores=ncores,
                                               mapping=True,
                                               alpha_1_descr=el)
            self.grid[(el)] = interpolation.Spline1D(dists, grid_data)
Esempio n. 3
0
    def build_grid(self, dists, element1):
        num = len(dists)
        confs = np.zeros((num, 1, 5))

        confs[:, 0, 0] = dists
        confs[:, 0, 3], confs[:, 0, 4] = element1, element1

        grid_2b = self.predict_energy(confs)

        return interpolation.Spline1D(dists, grid_2b)
Esempio n. 4
0
    def build_grid(self, start, num_2b, num_3b, ncores=1):
        """Function used to create the three different 2-body energy grids for 
        atoms of elements 0-0, 0-1, and 1-1, and the four different 3-body energy grids for 
        atoms of elements 0-0-0, 0-0-1, 0-1-1, and 1-1-1. The function calls the
        ``build_grid_3b`` function for each of the 3-body grids to build.

        Args:
            start (float): smallest interatomic distance for which the energy is predicted
                by the GP and stored inn the 3-body mapped potential
            num (int): number of points to use in the grid of the 2-body mapped potentials
            num_3b (int): number of points to use to generate the list of distances used to
                generate the triplets of atoms for the 3-body mapped potentials
            ncores (int): number of CPUs to use to calculate the energy predictions
        """

        self.grid_start = start
        self.grid_num_2b = num_2b
        self.grid_num_3b = num_2b

        perm_list_2b = list(combinations_with_replacement(self.elements, 2))
        perm_list_3b = list(combinations_with_replacement(self.elements, 3))

        dists_2b = np.linspace(start, self.r_cut, num_2b)
        confs_2b = np.zeros((num_2b, 1, 5))
        confs_2b[:, 0, 0] = dists_2b

        for pair in perm_list_2b:  # in this for loop, predicting then save for each individual one
            confs_2b[:, 0, 3], confs_2b[:, 0,
                                  4] = pair[0], pair[1]

            mapped_energies = self.gp_2b.predict_energy(
                list(confs_2b), ncores=ncores, mapping=True)
            if self.rep_sig:
                mapped_energies += utility.get_repulsive_energies(
                    confs_2b, self.rep_sig, mapping=True)
            self.grid_2b[pair] = interpolation.Spline1D(dists_2b, mapped_energies)


        dists_3b = np.linspace(start, self.r_cut, num_3b)

        for trip in perm_list_3b:

            self.grid_3b[trip] = self.build_grid_3b(
                dists_3b,  trip[0],  trip[1],  trip[2], ncores = ncores)
Esempio n. 5
0
    def build_grid(self, start, num_2b, num_3b, ncores=1):
        """ Build the mapped 2- and 3-body potentials. 
        Calculates the energy predicted by the GP for two and three atoms at all possible combination 
        of num distances ranging from start to r_cut. The energy for the 3-body mapped grid is 
        calculated only for ``valid`` triplets of atoms, i.e. sets of three distances which 
        form a triangle (this is checked via the triangle inequality). 
        The grid building exploits all the permutation invariances to reduce the number of energy
        calculations needed to fill the grid.
        The computed 2-body energies are stored in an array of values, and a 1D spline interpolation is created.
        The computed 3-body energies are stored in a 3D cube of values, and a 3D spline interpolation is 
        created.
        The total force or local energy can then be calculated for any atom by summing the pairwise and
        triplet contributions of every valid couple and triplet of atoms of which one is always the central one.
        The prediction is done by the ``calculator`` module, which is built to work within 
        the ase python package.

        Args:
            start (float): smallest interatomic distance for which the energy is predicted
                by the GP and stored inn the 3-body mapped potential
            num_2b (int):number of points to use in the grid of the 2-body mapped potential 
            num_3b (int): number of points to use to generate the list of distances used to
                generate the triplets of atoms for the 2-body mapped potential
            ncores (int): number of CPUs to use to calculate the energy predictions
        """

        dists_2b = np.linspace(start, self.r_cut, num_2b)

        confs = np.zeros((num_2b, 1, 5))
        confs[:, 0, 0] = dists_2b
        confs[:, 0, 3], confs[:, 0, 4] = self.element, self.element

        grid_data = self.gp_2b.predict_energy(
            confs, ncores=ncores, mapping=True)
        if self.rep_sig:
            grid_data += utility.get_repulsive_energies(
                confs, self.rep_sig, mapping=True)
        grid_2b = interpolation.Spline1D(dists_2b, grid_data)

        # Mapping 3 body part
        dists_3b = np.linspace(start, self.r_cut, num_3b)
        inds, r_ij_x, r_ki_x, r_ki_y = self.generate_triplets(dists_3b)

        confs = np.zeros((len(r_ij_x), 2, 5))
        confs[:, 0, 0] = r_ij_x  # Element on the x axis
        confs[:, 1, 0] = r_ki_x  # Reshape into confs shape: this is x2
        confs[:, 1, 1] = r_ki_y  # Reshape into confs shape: this is y2

        # Permutations of elements
        confs[:, :, 3] = self.element  # Central element is always element 1
        # Element on the x axis is always element 2
        confs[:, 0, 4] = self.element
        # Element on the xy plane is always element 3
        confs[:, 1, 4] = self.element

        grid_3b = np.zeros((num_3b, num_3b, num_3b))

        grid_3b[inds] = self.gp_3b.predict_energy(
            confs, ncores=ncores, mapping=True).flatten()

        for ind_i in range(num_3b):
            for ind_j in range(ind_i + 1):
                for ind_k in range(ind_j + 1):
                    grid_3b[ind_i, ind_k, ind_j] = grid_3b[ind_i, ind_j, ind_k]
                    grid_3b[ind_j, ind_i, ind_k] = grid_3b[ind_i, ind_j, ind_k]
                    grid_3b[ind_j, ind_k, ind_i] = grid_3b[ind_i, ind_j, ind_k]
                    grid_3b[ind_k, ind_i, ind_j] = grid_3b[ind_i, ind_j, ind_k]
                    grid_3b[ind_k, ind_j, ind_i] = grid_3b[ind_i, ind_j, ind_k]

        grid_3b = interpolation.Spline3D(dists_3b, dists_3b, dists_3b, grid_3b)

        self.grid_2b = grid_2b
        self.grid_3b = grid_3b
        self.grid_num_2b = num_2b
        self.grid_num_3b = num_3b
        self.grid_start = start