Ejemplo n.º 1
0
    def __init__(self, dict_population, n_max=None, global_softness=None):
        r"""Initialize linear density model to compute local reactivity descriptors.

        Parameters
        ----------
        dict_population : dict
            Dictionary of number of electrons (keys) and corresponding atomic populations array
            (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): {N_A \left(N_0 - 1\right)},
            N_0: {N_A \left(N_0\right)}, (N_0 + 1): {N_A \left(N_0 + 1\right)}`.
            The :math:`N_0` value is considered as the reference number of electrons.
        n_max : float, optional
            Maximum number of electrons that system can accept, i.e. :math:`N_{\text{max}}`.
            See :attr:`BaseGlobalTool.n_max`.
        global_softness : float, optional
            Global softness. See :attr:`BaseGlobalTool.softness`.
        """
        # check number of electrons & density values
        n_ref, pop_m, pop_0, pop_p = check_dict_values(dict_population)
        # compute atomic ff+, ff- & ff0
        self._ff_plus = pop_p - pop_0
        self._ff_minus = pop_0 - pop_m
        self._ff_zero = 0.5 * (pop_p - pop_m)
        super(LinearCondensedTool, self).__init__(n_ref, n_max,
                                                  global_softness)
        self.dict_population = dict_population
Ejemplo n.º 2
0
    def __init__(self, dict_energy):
        r"""Initialize linear energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.

        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)
        # calculate parameters a, b, a' and b' of linear energy model
        param_b = energy_0 - energy_m
        param_a = energy_0 - n_ref * param_b
        param_b_prime = energy_p - energy_0
        param_a_prime = energy_0 - n_ref * param_b_prime
        self._params = [param_a, param_b, param_a_prime, param_b_prime]
        # calculate N_max
        if energy_0 < energy_p:
            n_max = n_ref
        else:
            n_max = None
        super(LinearGlobalTool, self).__init__(n_ref, n_max)
        self.dict_energy = dict_energy
Ejemplo n.º 3
0
    def __init__(self, dict_energy):
        r"""Initialize quadratic energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.

        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)
        # calculate parameters a, b, c of quadratic energy model
        energy_m, energy_0, energy_p = [
            dict_energy[n] for n in sorted(dict_energy.keys())
        ]
        param_c = 0.5 * (energy_m - 2 * energy_0 + energy_p)
        param_b = 0.5 * (energy_p - energy_m) - 2 * param_c * n_ref
        param_a = energy_0 - param_b * n_ref - param_c * (n_ref**2)
        self._params = [param_a, param_b, param_c]
        # calculate N_max (number of electrons for which energy is minimum)
        n_max = -param_b / (2 * param_c)
        super(QuadraticGlobalTool, self).__init__(n_ref, n_max)
        self.dict_energy = dict_energy
Ejemplo n.º 4
0
    def __init__(self, dict_density, n_max=None, global_softness=None):
        r"""Initialize linear density model to compute local reactivity descriptors.

        Parameters
        ----------
        dict_density : dict
            Dictionary of number of electrons (keys) and corresponding density array (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): \rho_{N_0 - 1}\left(\mathbf{
            r}\right), N_0: \rho_{N_0}\left(\mathbf{r}\right), (N_0 + 1): \rho_{N_0 + 1}\left(
            \mathbf{r}\right)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.
        n_max : float, optional
            Maximum number of electrons that system can accept, i.e. :math:`N_{\text{max}}`.
            See :attr:`base.BaseGlobalTool.n_max`.
        global_softness : float, optional
            Global softness. See :attr:`base.BaseGlobalTool.softness`.
        """
        # check number of electrons & density values
        n_ref, dens_m, dens_0, dens_p = check_dict_values(dict_density)
        # compute ff+, ff- & ff0
        self._ff_plus = dens_p - dens_0
        self._ff_minus = dens_0 - dens_m
        self._ff_zero = 0.5 * (dens_p - dens_m)
        super(LinearLocalTool, self).__init__(n_ref, n_max, global_softness)
        self.dict_density = dict_density
Ejemplo n.º 5
0
    def __init__(self, dict_energy, omega=0.5):
        r"""Initialize cubic energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.
        omega : float
            Value of omega parameter in the energy model.
        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)
        # compute parameters of energy model
        param_a = energy_0
        param_b = -omega * energy_m + 2. * omega * energy_0 - omega * energy_p
        param_b += energy_p - energy_0
        param_c = (energy_m - 2. * energy_0 + energy_p) / 2.
        param_d = (2. * omega - 1.) * (energy_m - 2. * energy_0 + energy_p) / 2.
        self._omega = omega
        self._params = np.array([param_a, param_b, param_c, param_d])
        super(CubicGlobalTool, self).__init__(n_ref, None)
        self.dict_energy = dict_energy
Ejemplo n.º 6
0
    def __init__(self, dict_energy):
        r"""Initialize exponential energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.

        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)
        # check energy values
        if not energy_m > energy_0 > energy_p:
            energies = [energy_m, energy_0, energy_p]
            raise ValueError(
                "For exponential model, the energy values for consecutive number of "
                "electrons should be monotonic! E={0}".format(energies))
        # calculate parameters A, B, gamma parameters of the exponential model
        param_a = (energy_m - energy_0) * (energy_0 - energy_p)
        param_a /= (energy_m - 2 * energy_0 + energy_p)
        param_b = energy_0 - param_a
        param_g = (energy_m - 2 * energy_0 + energy_p) / (energy_p - energy_0)
        param_g = math.log(1. - param_g)
        self._params = [param_a, param_g, param_b]
        # calculate N_max
        n_max = float("inf")
        super(ExponentialGlobalTool, self).__init__(n_ref, n_max)
        self.dict_energy = dict_energy
Ejemplo n.º 7
0
    def __init__(self, dict_energy):
        r"""Initialize rational energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.
        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)
        # check energy values
        if not energy_m > energy_0 >= energy_p:
            energies = [energy_m, energy_0, energy_p]
            raise ValueError(
                "For rational model, the energy values for consecutive number of "
                "electrons should be monotonic! E={0}".format(energies))
        # calculate parameters a0, a1 and b1 of rational energy model
        param_b1 = -(energy_p - 2 * energy_0 + energy_m)
        param_b1 /= ((n_ref + 1) * energy_p - 2 * n_ref * energy_0 +
                     (n_ref - 1) * energy_m)
        param_a1 = (1 + param_b1 * n_ref) * (energy_p - energy_0) + (param_b1 *
                                                                     energy_p)
        param_a0 = -param_a1 * n_ref + energy_0 * (1 + param_b1 * n_ref)
        self._params = [param_a0, param_a1, param_b1]
        # calculate N_max
        n_max = float('inf')
        super(RationalGlobalTool, self).__init__(n_ref, n_max)
        self.dict_energy = dict_energy
Ejemplo n.º 8
0
    def __init__(self, dict_energy):
        r"""Initialize the square-root energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.
        """
        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)

        # Compute The Coefficients
        param2 = (energy_p - 2. * energy_0 + energy_m) / \
                 (np.sqrt(n_ref + 1) - 2. * np.sqrt(n_ref) + np.sqrt(n_ref - 1))
        param3 = (energy_p - energy_m) / 2. - param2 * (np.sqrt(n_ref + 1) - np.sqrt(n_ref - 1)) / 2
        param1 = energy_0 - param2 * np.sqrt(n_ref) - param3 * n_ref
        self._params = [param1, param2, param3]
        n_max = self._compute_nmax()
        super(SquareRootGlobalTool, self).__init__(n_ref, n_max)
Ejemplo n.º 9
0
    def __init__(self, dict_energy, omega, nth_order=5, weight=0., eps=1e-3):
        r"""Initialize the least-norm energy model to compute global reactivity descriptors.

        Parameters
        ----------
        dict_energy : dict
            Dictionary of number of electrons (keys) and corresponding energy (values).
            This model expects three energy values corresponding to three consecutive number of
            electrons differing by one, i.e. :math:`\{(N_0 - 1): E(N_0 - 1), N_0: E(N_0),
            (N_0 + 1): E(N_0 + 1)\}`. The :math:`N_0` value is considered as the reference number
            of electrons.
        omega : float, default=0.5
            The parameter :math:`\omega` in the energy model. Reasonable choices are between 0 and 1
            see reference for more details.
        nth_order : int, default=5
            The nth degree for the taylor polynomial.
        weight : float, default=0.
            The weight between 0 and 1 for the weighted least norm energy model. The weight with
            value zero gives the un-weighted least norm model.
        eps : float, default=1e-3
            The accuracy for computing the hyper-parameters :math: '\alpha_x' and :math: '\beta_x',
            only needed for the weighted model.
        """
        if weight > 1. or weight < 0.:
            raise ValueError(
                "Weights have to be between 0 and 1. It is {0}".format(weight))
        if not isinstance(nth_order, int):
            raise ValueError("The nth order should be integer")

        # check number of electrons & energy values
        n_ref, energy_m, energy_0, energy_p = check_dict_values(dict_energy)

        self._omega = omega
        self._weight = weight
        self._nth_order = nth_order
        # Default coefficients for the first two terms.
        self.dict_energy = dict_energy

        # Need these to initially define the parameters
        ionization = energy_m - energy_0
        affinity = energy_0 - energy_p
        diff = ionization - affinity
        self._params = [
            energy_0, -(omega * ionization + (1 - omega) * affinity)
        ]

        # Compute the coefficients up-to nth order, specified by `nth_order` argument.
        if weight != 0.:
            # If weighted model, compute the weighted coefficients.
            alpha, beta = self._hyperparameters(eps)
            self._params += [
                self._coefficients_weighted(j, alpha, beta) * diff /
                factorial(j) for j in range(2, self._nth_order + 1)
            ]
        else:
            self._params += [
                self._coefficients_unweighted(j) * diff / factorial(j)
                for j in range(2, self._nth_order + 1)
            ]

        self._n_max = self._compute_n_max()
        super(LeastNormGlobalTool, self).__init__(n_ref, self._n_max)