.. : PyBEST: Pythonic Black-box Electronic Structure Tool : Copyright (C) 2016-- The PyBEST Development Team : : This file is part of PyBEST. : : PyBEST is free software; you can redistribute it and/or : modify it under the terms of the GNU General Public License : as published by the Free Software Foundation; either version 3 : of the License, or (at your option) any later version. : : PyBEST is distributed in the hope that it will be useful, : but WITHOUT ANY WARRANTY; without even the implied warranty of : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the : GNU General Public License for more details. : : You should have received a copy of the GNU General Public License : along with this program; if not, see : -- .. _orbital_energies_intro: Orbital Energies ################ This section documents how to compute orbital energies for closed-shell molecules using Koopmans-based methods. The Koopmans' theorem approximates ionization energies and electron affinities by the orbital energies of a system. Before proceeding, please ensure you're familiar with the basics of pCCD models in PyBEST (:ref:`user_pccd`). Supported Models ================ - **Koopmans' theorem** (:ref:`koopmans'-theorem`): Calculate and store single and pair orbital energies from Koopmans' theorem. - **Modified Koopmans' theorem** (:ref:`modified-koopmans'`): Calculate and store single and pair orbital energies from Modified Koopmans' theorem. - **Extended Koopmans' theorem**: Calculate and store orbital energies from Extended Koopmans' theorem (unreleased). .. note:: The Koopmans theorem is implemented for a restricted Hartree–Fock or pCCD reference (:ref:`user_pccd`) to calculate orbital energies. The modified version only supports a pCCD reference. Theoretical Framework ===================== .. _koopmans'-theorem: Koopmans' Theorem ================= Koopmans' theorem provides an approximate link between orbital energies and electron addition/removal processes within the RHF framework. The theorem states that the negative of an occupied orbital's energy approximates the ionization potential (IP), while that of a virtual orbital estimates the electron affinity (EA). These expressions derive from differences in total energies when electrons are added or removed, and are evaluated from the diagonal elements of the Fock matrix. Extensions to double ionization potentials (DIPs) and double electron affinities (DEAs) are also possible, including electron–electron repulsion terms. .. _modified-koopmans': Modified Koopmans' Theorem ========================== The modified Koopmans' theorem extends the original theorem by incorporating correlation effects through a multi-determinant pCCD reference. It replaces the bare Hamiltonian with a similarity-transformed version, :math:`\hat{H}^{(\mathrm{pCCD})} = e^{-\hat{T}_p} \hat{H} e^{\hat{T}_p}`, where :math:`\hat{T}_p` is the pCCD cluster operator. IPs and EAs are then evaluated as commutators and expectation values using this transformed Hamiltonian, capturing additional correlation contributions localized to specific orbitals. These corrections refine the orbital energies beyond the Hartree–Fock approximation. For example, the modified IP expression becomes :math:`-\!f_{ii} - \sum_c t^{c\bar{c}}_{i\bar{i}} \langle i\bar{i} | c\bar{c} \rangle`, explicitly accounting for the correlation energy lost when removing an electron from orbital :math:`i`. The corresponding EA is defined analogously with respect to a virtual orbital. Summary of Koopmans' and Modified Koopmans' equations for IPs, EAs, DIPs, and DEAs ================================================================================== .. table:: Summary of Koopmans' and Modified Koopmans' Equations for IPs, EAs, DIPs, and DEAs :widths: auto :align: center +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | Orbital Energy | Koopmans' | Modified Koopmans' | +=====================+===========================================================+=============================================================================================================+ | IP | :math:`f_{ii}` | :math:`-f_{ii} - \sum\limits_{c} t^{c\bar{c}}_{i\bar{i}} \langle i\bar{i} \vert c\bar{c} \rangle` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | EA | :math:`-f_{aa}` | :math:`-f_{aa} + \sum\limits_{k} t^{a\bar{a}}_{k\bar{k}} \langle k\bar{k} \vert a\bar{a} \rangle` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | DIP (:math:`m_s=1`) | :math:`f_{ii} + f_{jj} - \langle ij \Vert ij \rangle` | :math:`-f_{ii} - f_{jj} + V_{ijij}` | | | | :math:`- \sum\limits_{c} t^{c\bar{c}}_{i\bar{i}} \langle i\bar{i} \vert c\bar{c} \rangle` | | | | :math:`- \sum\limits_{c} t^{c\bar{c}}_{j\bar{j}} \langle j\bar{j} \vert c\bar{c} \rangle` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | DIP (:math:`m_s=0`) | :math:`f_{ii} + f_{\bar{j}\bar{j}}` | :math:`-f_{ii} - f_{\bar{j}\bar{j}} + V_{i\bar{j}i\bar{j}}` | | | :math:`- \langle i\bar{j} \vert i\bar{j} \rangle` | :math:`- \sum\limits_{c} t^{c\bar{c}}_{i\bar{i}} \langle i\bar{i} \vert c\bar{c} \rangle` | | | | :math:`- \sum\limits_{c} t^{c\bar{c}}_{j\bar{j}} \langle j\bar{j} \vert c\bar{c} \rangle` | | | | :math:`+ \sum\limits_{c} t^{c\bar{c}}_{i\bar{i}} \langle i\bar{i} \vert c\bar{c} \rangle \delta_{ij}` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | DEA (:math:`m_s=1`) | :math:`f_{aa} + f_{bb} + \langle ab \Vert ab \rangle` | :math:`-f_{aa} - f_{bb} - V_{abab}` | | | | :math:`+ \sum\limits_{k} t^{a\bar{a}}_{k\bar{k}} \langle k\bar{k} \vert a\bar{a} \rangle` | | | | :math:`+ \sum\limits_{k} t^{b\bar{b}}_{k\bar{k}} \langle k\bar{k} \vert b\bar{b} \rangle` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ | DEA (:math:`m_s=0`) | :math:`f_{aa} + f_{\bar{b}\bar{b}}` | :math:`-f_{aa} - f_{\bar{b}\bar{b}} - V_{a\bar{b}a\bar{b}}` | | | :math:`+ \langle a\bar{b} \vert a\bar{b} \rangle` | :math:`+ \sum\limits_{k} t^{a\bar{a}}_{k\bar{k}} \langle k\bar{k} \vert a\bar{a} \rangle` | | | | :math:`+ \sum\limits_{k} t^{b\bar{b}}_{k\bar{k}} \langle k\bar{k} \vert b\bar{b} \rangle` | | | | :math:`- \sum\limits_{k} t^{a\bar{a}}_{k\bar{k}} \langle k\bar{k} \vert a\bar{a} \rangle \delta_{ab}` | +---------------------+-----------------------------------------------------------+-------------------------------------------------------------------------------------------------------------+ .. _orbital_energies_guide: Quick Guide: Koopmans-based orbital energies ============================================ If you use this part of the code, please cite [jahani2025a]_ and [jahani2025b]_. PyBEST allows the user to calculate orbital energies using various flavors of Koopmans theorem. The current version of PyBEST supports the Koopmans-based methods for a closed-shell RHF (see :ref:`user_hf`) or pCCD wavefunction (see :ref:`user_pccd`). We assume you have performed an RHF or pCCD calculation whose results are stored in some output container. Furthermore, we will assume the following names for all PyBEST objects :lf: A :py:class:`~pybest.linalg.base.LinalgFactory` instance (see :ref:`user_linalg_intro`). :occ_model: An Aufbau occupation model of the :py:class:`~pybest.scf.occ.AufbauOccModel` class :kin: The kinetic energy integrals :ne: The nucleus-electron attraction integrals :eri: The two-electron repulsion integrals How to: Koopmans' orbital energies ---------------------------------- The code snippet below shows how to perform a Koopmans' orbital energy calculation in PyBEST, .. code-block:: python orbital_energy = Koopmans(lf, occ_model) e_orb_output = orbital_energy(kin, ne, eri, pccd_output) where ``pccd_output`` is some output container containing the results of a pCCD calculations. Replacing it with an RHF output container will give you the orbital energies for an RHF reference function. How to: Modified Koopmans' orbital energies ------------------------------------------- The code snippet below shows how to perform a Modified Koopmans' orbital energy calculation in PyBEST, .. code-block:: python orbital_energy = ModifiedKoopmans(lf, occ_model) e_orb_output = orbital_energy(kin, ne, eri, pccd_output) .. note:: The modified Koopmans' theorem requires a pCCD reference function and is not supported for RHF. .. _orbital_energies_output: Output Attributes ================= In addition to calculating the orbital energies from Koopmans-based method, the following attributes are provided: :e_orb_ks: single (s) orbital energies based on Koopmans' (k) theorem :e_orb_kp_0: diagonal singlet and off-diagonal open-shell singlet pair (p) orbital energies based on Koopmans' (k) theorem :e_orb_kp_1: diagonal triplet and off-diagonal open-shell triplet pair (p) orbital energies based on Koopmans' (k) theorem :e_orb_mks: modification (m) 'e_orb_ks' to single (s) orbital energies based on Koopmans' (k) theorem :e_orb_mkp_0: modification (m) 'e_orb_kp_0' to diagonal singlet and off-diagonal open-shell singlet pair (p) orbital energies based on Koopmans' (k) theorem :e_orb_mkp_1: modification (m) 'e_orb_kp_1' to diagonal triplet and off-diagonal open-shell triplet (p) orbital energies based on Koopmans' (k) theorem :e_orb_ek: orbital energies based on Extended Koopmans' (ek) theorem (unreleased). .. _orbital_energies_keywords: Summary of Keyword Arguments ============================ The :py:class:`~pybest.properties.koopmans.Koopmans` and :py:class:`~pybest.properties.modified_koopmans.ModifiedKoopmans` modules support various keyword arguments that allow us to set the ranges for printing the ionization potentials and electron affinities. In the following, all supported keyword arguments are listed together with their default values. Orbital Energies Property Options --------------------------------- :printoptions: (dictionary) print level: :orb_range_o: (int): Specifies the range of occupied orbital energies to display. Default is 10. :orb_range_v: (int): Specifies the range of virtual orbital energies to display. Default is 20. :all: (str): Controls the range of all orbital energies. Specific values may vary depending on the calculation requirements. :warning: (boolean) if ``True``, (scipy) solver-specific warnings are printed (default ``False``). :indextrans: (str) 4-index transformation. The choice between ``cupy``, ``tensordot`` (default) and ``einsum``. ``tensordot`` is faster than ``einsum``. If ``DenseLinalgFactory`` is used, the memory requirement scales roughly as :math:`3N^4`. Due to the storage of the two-electron integrals, the total amount of memory increases to :math:`4N^4` .. note:: If Cupy is not available or unsuccessful, ``td`` is selected instead. .. _orbital_energies_example: Example Usage ============= Example Python scripts for orbital energies ------------------------------------------- Several examples are provided in ``data/examples/properties``. Orbital energies for water using RHF orbitals (cc-pVDZ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example calculates single and pair orbital energies based on Koopmans-type methods and RHF orbitals using the pCCD method. .. literalinclude:: ../src/pybest/data/examples/properties/water_orbital_energy_pccd.py :caption: data/examples/properties/water_orbital_energy_pccd.py :lines: 3- Orbital energies for water using pCCD-optimized orbitals (cc-pVDZ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example calculates single and pair orbital energies based on Koopmans-type methods using an OOpCCD wavefunction. .. literalinclude:: ../src/pybest/data/examples/properties/water_orbital_energy_oopccd.py :caption: data/examples/properties/water_orbital_energy_oopccd.py :lines: 3-