コード例 #1
0
ファイル: ocpd_calc.py プロジェクト: ulissigroup/al_mlp
    def calculate(self,
                  atoms=None,
                  properties=None,
                  system_changes=all_changes):
        """
        Calculate properties including: energy, forces, uncertainties.

        Args:
            atoms: ase Atoms object
        """
        MLPCalc.calculate(self,
                          atoms=atoms,
                          properties=properties,
                          system_changes=system_changes)

        ocp_descriptor = self.get_descriptor(atoms)
        energy, forces, energy_uncertainty, force_uncertainties = self.calculate_ml(
            ocp_descriptor)

        self.results["energy"] = energy
        self.results["forces"] = forces
        self.results["stds"] = [energy_uncertainty, force_uncertainties]
        self.results["force_stds"] = force_uncertainties
        self.results["energy_stds"] = energy_uncertainty
        atoms.info["energy_stds"] = self.results["energy_stds"]
        atoms.info["max_force_stds"] = self.results["force_stds"]
        # atoms.info["max_force_stds"] = np.nanmax(self.results["force_stds"])
        return
コード例 #2
0
 def calculate(self, atoms=None, properties=None, system_changes=...):
     MLPCalc.calculate(self,
                       atoms=atoms,
                       properties=properties,
                       system_changes=system_changes)
     return super().calculate(atoms=atoms,
                              properties=properties,
                              system_changes=system_changes)
コード例 #3
0
    def calculate(self,
                  atoms=None,
                  properties=None,
                  system_changes=all_changes):
        """
        Calculate properties including: energy, forces, uncertainties.

        Args:
            atoms: ase Atoms object
        """
        MLPCalc.calculate(self,
                          atoms=atoms,
                          properties=properties,
                          system_changes=system_changes)

        energy, forces, energy_uncertainty, force_uncertainties = self.calculate_ml(
            atoms, properties, system_changes)

        self.results["energy"] = energy
        self.results["forces"] = forces
        self.results["stds"] = [energy_uncertainty, force_uncertainties]
        self.results["force_stds"] = force_uncertainties
        self.results["energy_stds"] = energy_uncertainty
        atoms.info["energy_stds"] = self.results["energy_stds"]

        if atoms.constraints:
            constraints_index = atoms.constraints[0].index
        else:
            constraints_index = []

        abs_force_uncertainty = np.average(
            np.abs(np.delete(
                force_uncertainties,
                constraints_index,
                axis=0,
            ))).item()

        avg_forces = np.average(
            np.abs(np.delete(
                forces,
                constraints_index,
                axis=0,
            ))).item()

        atoms.info["max_force_stds"] = abs_force_uncertainty / avg_forces
        # atoms.info["max_force_stds"] = np.nanmax(self.results["force_stds"])
        return
コード例 #4
0
    def calculate(self, atoms, properties, system_changes):
        MLPCalc.calculate(self,
                          atoms=atoms,
                          properties=properties,
                          system_changes=system_changes)
        energies = []
        forces = []
        for calc in self.trained_calcs:
            energies.append(calc.get_potential_energy(atoms))
            forces.append(calc.get_forces(atoms))

        energies = np.array(energies)
        forces = np.array(forces)
        energy_pred, force_pred, max_forces_var, energy_var = self.calculate_stats(
            energies, forces)

        self.results["energy"] = energy_pred
        self.results["forces"] = force_pred
        atoms.info["energy_stds"] = energy_var**0.2
        atoms.info["max_force_stds"] = max_forces_var**0.5
コード例 #5
0
    def calculate(self, atoms, properties, system_changes):
        MLPCalc.calculate(self,
                          atoms=atoms,
                          properties=properties,
                          system_changes=system_changes)
        energies = []
        forces = []
        for predictor in self.trained_trainers:
            prediction = predictor.predict(atoms)
            energies.append(prediction["energy"].data.numpy()[0])
            forces.append(prediction["forces"].data.numpy())

        energies = np.array(energies)
        forces = np.array(forces)
        energy_pred, force_pred, max_forces_var, energy_var = self.calculate_stats(
            energies, forces)

        self.results["energy"] = energy_pred
        self.results["forces"] = force_pred
        atoms.info["energy_stds"] = energy_var**0.2
        atoms.info["max_force_stds"] = max_forces_var**0.5
コード例 #6
0
    def calculate(self,
                  atoms=None,
                  properties=None,
                  system_changes=all_changes):
        """
        Calculate properties including: energy, local energies, forces,
            stress, uncertainties.
        """

        MLPCalc.calculate(self,
                          atoms=atoms,
                          properties=properties,
                          system_changes=system_changes)

        # Create structure descriptor.
        structure_descriptor = self.get_structure_descriptor(atoms)

        #         Predict on structure.
        if self.gp_model.variance_type == "SOR":
            self.gp_model.sparse_gp.predict_SOR(structure_descriptor)
        elif self.gp_model.variance_type == "DTC":
            self.gp_model.sparse_gp.predict_DTC(structure_descriptor)
        elif self.gp_model.variance_type == "local":
            self.gp_model.sparse_gp.predict_local_uncertainties(
                structure_descriptor)

        self.results["energy"] = structure_descriptor.mean_efs[0]
        self.results["forces"] = structure_descriptor.mean_efs[1:-6].reshape(
            -1, 3)

        # Convert stress to ASE format.
        flare_stress = structure_descriptor.mean_efs[-6:]
        ase_stress = -np.array([
            flare_stress[0],
            flare_stress[3],
            flare_stress[5],
            flare_stress[4],
            flare_stress[2],
            flare_stress[1],
        ])
        self.results["stress"] = ase_stress

        # Report negative variances, which can arise if there are numerical
        # instabilities.
        if (self.gp_model.variance_type
                == "SOR") or (self.gp_model.variance_type == "DTC"):
            variances = structure_descriptor.variance_efs[1:-6]
            energy_var = structure_descriptor.variance_efs[0]
            energy_std = np.sqrt(np.abs(energy_var))
            stds = np.zeros(len(variances))
            for n in range(len(variances)):
                var = variances[n]
                if var > 0:
                    stds[n] = np.sqrt(var)
                else:
                    stds[n] = -np.sqrt(np.abs(var))
            self.results["force_stds"] = stds.reshape(-1, 3)
            self.results["energy_stds"] = energy_std
            atoms.info["energy_stds"] = energy_std
        # The "local" variance type should be used only if the model has a
        # single atom-centered descriptor.
        # TODO: Generalize this variance type to multiple descriptors.
        elif self.gp_model.variance_type == "local":
            variances = structure_descriptor.local_uncertainties[0]
            sorted_variances = self.sort_variances(structure_descriptor,
                                                   variances)
            stds = np.zeros(len(sorted_variances))
            for n in range(len(sorted_variances)):
                var = sorted_variances[n]
                if var > 0:
                    stds[n] = np.sqrt(var)
                else:
                    stds[n] = -np.sqrt(np.abs(var))
            stds_full = np.zeros((len(sorted_variances), 3))

            # Divide by the signal std to get a unitless value.
            stds_full[:, 0] = stds / self.gp_model.hyps[0]
            self.results["force_stds"] = stds_full

        atoms.info["max_force_stds"] = np.nanmax(self.results["force_stds"])