========================== Use LOSC library in psi4 ========================== ------------ Introduction ------------ ``psi4_losc`` is a Python module that extends the `psi4 `_, an open-source package for quantum chemistry calculations, to perform the calculations of LOSC method. The ``psi4_losc`` module interacts with the ``psi4`` package via its Python interface. Using this ``psi4_losc`` module along with ``psi4`` (the `python model `_ of psi4), you can perform post-SCF-LOSC [#losc1]_ [#losc2]_ and SCF-LOSC [#scf-losc]_ calculations for aufbau/non-aufbau systems with integer/fractional numbers of electrons. --------------------- --------------- Installing psi4 --------------- .. Warning:: ``psi4_losc`` module is developed based on psi4 version ``1.3.2``. To have stable performance, it would be better to install this version of psi4. Other versions of ``psi4`` are not tested. To perform LOSC calculation with ``psi4_losc`` in ``psi4``, you need to install ``psi4`` package first. If never use psi4 before, you are suggested to just install the conda binary package of psi4: .. code-block:: bash conda install psi4=1.3.2 -c psi4 If you want to set up psi4 from the scratch, you can get more guidance for the installation of psi4 from its `documentation `_. --------------------- ----------- Basic Guide ----------- LOSC can significantly eliminate the delocalization error exisiting in conventional density functional approximations (DFAs), such as local density approximations (LDA), generalized gradient approximations (GGAs) and hybrid functionals like B3LYP. With minimal delocalization error from LOSC-DFA calculations, you can expect good description of physical properties, such as the ionization potentials (IPs), electron affinities (EAs), the photoemision spectra. For most cases, you would be interested in performing LOSC calculations for aufbau systems (ground-state) with integer number of electrons. There are two ways to apply LOSC to an associated DFA: 1. the post-SCF-LOSC approach [#losc1]_ [#losc2]_ Directly applying LOSC correction to the SCF-DFA calculations. In this approach, the total energy and orbital energies from the associated DFA are corrected. The electron density is not corrected from LOSC. 2. the SCF-LOSC approach [#scf-losc]_ Using the LOSC effective Hamiltonian to correct the associated DFA Hamiltonian and perform the SCF calculation for LOSC-DFA. In this approach, the total energy, orbital energies and electron densities are all corrected. To perform the calculation of LOSC via ``psi4_losc``, always import following: .. code-block:: python import psi4 import psi4_losc No matter doing SCF-LOSC or post-SCF-LOSC, an SCF calculation for the associated DFA should be performed in advance to generate the corresponding converged psi4 wavefunction object. .. note:: Although psi4 supports calculations with point group symmetry, LOSC does not support symmetry because the usage of localized orbitals. So you need to turn off the symmetry in psi4 calculation (set ``symettr c1`` for the system). Now, taking a simple molecule, a stretched H2 molecule, as an example. You first calculate the SCF-DFA in psi4. .. code-block:: python :emphasize-lines: 6 # A stretched H2 molecule with 10A bond length with symmetry turned off. mol = psi4.geometry(""" 0 1 H 0 0 0 H 10 0 0 symmetry c1 # turn off symmetry """) # some basic setting in psi4. psi4.set_options({'basis': '6-31g', 'guess': 'core', 'reference': 'uks'}) # Here we do a b3lyp calculation and let psi4 return the wfn object. E_dfa, dfa_wfn = psi4.energy('b3lyp', return_wfn=True) print(E_dfa) # You would see E_dfa = -0.8923613725795544 post-SCF-LOSC for integer system with aufbau occupation ------------------------------------------------------- Following the aforementioned H2 example, you can do a post-SCF-LOSC calculation via calling ``psi4_losc.post_scf_losc()`` function. There are two key arguments you need to specify: the first one is the DFA functional type, and the second one the corresponding converged DFA wavefunction object. ``psi4_losc.post_scf_losc()`` will return two variables: the corrected total energy and orbital energies. .. code-block:: python :emphasize-lines: 1-3 # do post-SCF-LOSC-B3LYP calculation to obtain corrected total energy # and the orbital energies. E_losc, Orb_losc = psi4_losc.post_scf_losc(psi4_losc.B3LYP, dfa_wfn) # You would see total energies: # E_losc = -0.758073589993662 # E_losc - E_dfa = 0.13428778258589236 print(E_losc) print(E_losc - E_dfa) # You would see all LOSC corrected orbital energies in a.u. for # both alpha and beta spin: # [array([-6.98665404, -5.54668941, 24.04349262, 24.04349294]), # array([-6.98665404, -5.54668941, 24.04349262, 24.04349294])] print(Orb_losc) SCF-LOSC for integer system with aufbau occupation -------------------------------------------------- Following the aforementioned H2 example, you can do an SCF-LOSC calculation via calling ``psi4_losc.scf_losc()`` function. The input arguments are very similar to ``psi4_losc.post_scf_losc()`` function. But the return type is a psi4 wavefunction object. .. code-block:: python :emphasize-lines: 1-2 # do SCF-LOSC-B3LYP calculation to obtain a LOSC-B3LYP wavefunction object. losc_wfn = psi4_losc.scf_losc(psi4_losc.B3LYP, dfa_wfn) # You would see total energies: # E_losc = -0.7578046520485341 # E_losc - E_dfa = 0.1345567205310203 E_losc = losc_wfn.energy() print(E_losc) print(E_losc - E_dfa) # You would see all LOSC corrected orbital energies in a.u. for alpha spin. # Orb_losc = [-0.25675479 -0.20383709 0.91139381 0.91139408] import numpy as np Orb_losc = np.asarray(losc_wfn.epsilon_a()) print(Orb_losc) --------------------- -------- Advanced -------- Configure LOSC calculations with options ---------------------------------------- You can configure the options for the LOSC calculations in ``psi4_losc`` module. These configurations include option settings related to LOSC curvatures, localizations and so on. To configure the options, use the defined variable ``psi4_losc.options``, which is an object of class ``psi4_losc.losc_options.Options``. The basic methods of ``psi4_losc.options`` are the following ================================== ==================== Method Description ================================== ==================== ``psi4_losc.options.get_param()`` get a LOSC parameter. ``psi4_losc.options.set_param()`` set a LOSC parameter. ``psi4_losc.options.set_params()`` set a number of LOSC parameters. ================================== ==================== Following are some examples of configuring the LOSC options. .. code-block:: python # set LOSC curvature version 2. psi4_losc.options.set_param('curvature', 'version', 2) # set LOSC localizer version 2. psi4_losc.options.set_param('localizer', 'version', 2) # set both curvature and localizer version in one call. psi4_losc.options.set_params({ 'localizer': {'version': 2}, 'curvature': {'version': 2}, }) # get LOSC curvature version. version = psi4_losc.options.get_param('curvature', 'version') # get LOSC localizer version. version = psi4_losc.options.get_param('localizer', 'version') See all the supported options in :ref:`this section `. Setting energy window for LOSC calculation ------------------------------------------ The LOSC corrections are constructed from a set of localized orbitals (LOs). These LOs are obtained by a unitary transformation from a set of canonical orbitals (COs) from the associated DFA. In default (for ``psi4_losc.post_scf_losc`` and ``psi4_losc.scf_losc``), all the COs (the same number of basis sets) are involved to perform the localization. As results, LOSC corrects all the orbital energies. To simplify the calculation, you can only select a subset of COs to perform the LOSC calculation, and you should expect this simplified approach to produce similar results from the calculation will all COs localized. ``psi4_losc`` module accepts the selection of COs with an energy window (**in eV**) setting, that is selecting all the COs whose orbital energies are inside the window. To enable the window, you use the `window` key argument. .. code-block:: python # do post-SCF-LOSC-B3LYP calculation with setting a window of -30 - 10 eV. E_losc, Orb_losc = psi4_losc.post_scf_losc(psi4_losc.B3LYP, dfa_wfn, window=[-30, 10]) # do SCF-LOSC-B3LYP calculation with setting a window of -30 - 10 eV. losc_wfn = psi4_losc.scf_losc(psi4_losc.B3LYP, dfa_wfn, window=[-30, 10]) .. note:: Using window setting in the calculation of LOSC reduces the space of LOs and makes the calculation much faster. However, keep in mind that doing so would only produce corrections to orbital energies of the selected COs. **The orbital energies of non-selected COs will not be touched.** **To use the window setting, you should select most of the valence orbitals.** The usual energy window is -30 - 10 eV. Using this window should give you very similar results in total energy, orbital energies and electron density to the ones calculated from all COs localized. Excluding the core orbitals to the localization is a reasonble choice. This is because: (1) core orbitals usually are already localized, thus, they do not contribute the total energy correction because of the integer occupation number (see the LOSC energy correction formular [#losc1]_); (2) the core orbital energies are not as much interesting as the valence orbital energies. --------------------- Systems with fractional numbers of electrons or non-aufbau occupation --------------------------------------------------------------------- Psi4 mainly supports the calculations of systems with integer number of electrons and aufbau occupations. However, it would be interesting to calculate systems with fractional number of electrons (such as study of the delocalization error) or non-aufbau occupation (such as :math:`\Delta`-SCF calculations). ``psi4_losc.scf`` module provides the extended SCF procedure to enable calculations for systems with fractional numbers of electrons or non-aufbau occupation. See :ref:`this ` for more details. ---------- References ---------- **psi4_losc Module** -------------------- .. This includes the full list of psi4 API used in psi4_losc module. .. include:: psi4_api_ref__psi4_losc.rst **API of psi4_losc module** *************************** .. autodata:: psi4_losc.B3LYP .. autodata:: psi4_losc.BLYP .. autodata:: psi4_losc.PBE .. autodata:: psi4_losc.PBE0 .. autodata:: psi4_losc.GGA .. autofunction:: psi4_losc.post_scf_losc .. autofunction:: psi4_losc.scf_losc ------------ **psi4_losc.scf Module** ------------------------ .. This includes the full list of psi4 API used in psi4_losc.scf module. .. include:: psi4_api_ref__psi4_losc__scf.rst .. _psi4_losc__scf_label: **API of psi4_losc.scf module** ******************************* .. Warning:: This module is not fully tested. Use it with caution. .. automodule:: psi4_losc.scf :members: :inherited-members: -------------------- .. _psi4_losc__options_label: **Configure LOSC options in psi4_losc** --------------------------------------- The configuration of LOSC calculation for `psi4_losc` module is controlled by `psi4_losc.options` variable. These configurations include the adjustments to the LOSC curvature, and localizations. The details are shown below. .. autodata:: psi4_losc.options .. autoclass:: psi4_losc.losc_options.Options :members: **Literature** -------------- .. [#losc1] Li, C.; Zheng, X.; Su, N. Q.; Yang, W. Localized Orbital Scaling Correction for System- atic Elimination of Delocalization Error in Density Functional Approximations. `Natl. Sci. Rev. 2018, 5, 203−215. 203-215. `_ .. [#losc2] Su, N. Q.; Mahler, A.; Yang, W. Preserving Symmetry and Degeneracy in the Localized Orbital Scaling Correction Approach. J. `Phys. Chem. Lett. 2020, 11, 1528−1535. `_ .. [#scf-losc] Mei, Y.; Chen, Z.; Yang, W. Self-Consistent Calculation of the Localized Orbital Scaling Correction for Correct Electron Densities and Energy-Level Alignments in Density Functional Theory. `J. Phys. Chem. Lett. 2020, 11, 23, 10269–10277. `_