15.1. Localization of molecular orbitals
In general, the localization algorithm optimizes some localization function by an orthogonal transformation of the orbitals. Given orbitals \(\vert i \rangle\), the localized orbital \(\vert \tilde{i} \rangle\) can be obtained by some transformation
where
and \(\kappa_{kl}\) is determined by the optimization of the localization function.
Many of the localization schemes, and thus the result of the localization, differ by the localization function. The localization function somehow measures the localization of the orbitals. So far, PyBEST only supports the Pipek-Mezey localization. [pipek1989]
15.1.1. Pipek-Mezey localization
In the Pipek-Mezey scheme, the Pipek-Mezey localization function, \(D\), is maximized.
where \(\mathbf{Q}^A\) is the atomic population matrix. The atomic population matrix can be obtained from the overlap of the atomic basis, the molecular orbitals from the atomic basis, the occupation of each molecular orbital, and some weighted projection of atomic basis function within each atom.
For example, if the Mulliken population analysis is used, the projectors are
obtained through get_mulliken_operators()
.
The Pipek-Mezey localization is initialized through a series of
PipekMezey
function calls,
__call__()
.
Note
The virtual and occupied blocks are localized separately. Thus, each block requires a separate function call.
The code snippet below summarizes all required steps (see also Orbital localization, where all arguments are explained)
###############################################################################
## Define Mulliken projectors #################################################
###############################################################################
mulliken = get_mulliken_operators(gobasis)
###############################################################################
## Pipek-Mezey localizaton ####################################################
###############################################################################
loc = PipekMezey(lf, occ_model, mulliken)
###############################################################################
## occupied block #############################################################
###############################################################################
loc(hf_output, "occ")
###############################################################################
## virtual block ##############################################################
###############################################################################
loc(hf_output, "virt")
15.1.2. Example Python scripts
15.1.2.1. Pipek-Mezey localization of restricted Hartree-Fock orbitals for the water molecule
This is a basic example on how to perform a Pipek-Mezey localization in PyBEST. This script performs a Pipek-Mezey localization for the water molecule using the cc-pVDZ basis set and Mulliken projectors. The localized orbitals are then dump to disk in the molden file format (see also Generating molden files).
from pybest import context
from pybest.gbasis import get_gobasis
from pybest.gbasis.gobasis import (
compute_eri,
compute_kinetic,
compute_nuclear,
compute_nuclear_repulsion,
compute_overlap,
)
from pybest.io.iodata import IOData
from pybest.linalg.dense import DenseLinalgFactory
from pybest.localization import PipekMezey
from pybest.part.mulliken import get_mulliken_operators
from pybest.scf import AufbauOccModel
from pybest.wrappers.hf import RHF
###############################################################################
## Set up molecule, define basis set ##########################################
###############################################################################
# Use the XYZ file from PyBEST's test data directory.
fn_xyz = context.get_fn("test/water.xyz")
gobasis = get_gobasis("cc-pvdz", fn_xyz)
###############################################################################
## Define Occupation model, expansion coefficients and overlap ################
###############################################################################
lf = DenseLinalgFactory(gobasis.nbasis)
occ_model = AufbauOccModel(5)
orb_a = lf.create_orbital(gobasis.nbasis)
olp = compute_overlap(gobasis)
###############################################################################
## Construct Hamiltonian ######################################################
###############################################################################
kin = compute_kinetic(gobasis)
na = compute_nuclear(gobasis)
er = compute_eri(gobasis)
external = compute_nuclear_repulsion(gobasis)
###############################################################################
## Do a Hartree-Fock calculation ##############################################
###############################################################################
hf = RHF(lf, occ_model)
hf_output = hf(kin, na, er, external, olp, orb_a)
###############################################################################
## Define Mulliken projectors #################################################
###############################################################################
mulliken = get_mulliken_operators(gobasis)
###############################################################################
## Pipek-Mezey localizaton ####################################################
###############################################################################
loc = PipekMezey(lf, occ_model, mulliken)
###############################################################################
## occupied block #############################################################
###############################################################################
loc(hf_output, "occ")
###############################################################################
## virtual block ##############################################################
###############################################################################
loc(hf_output, "virt")
###############################################################################
## dump Molden file; hf_ already contains the orb_a attribute #################
###############################################################################
hf_output.gobasis = gobasis
hf_output.to_file("water.molden")
15.1.2.2. Pipek-Mezey localization of restricted Hartree-Fock orbitals for the water molecule and a frozen core
This is a basic example on how to perform a Pipek-Mezey localization in PyBEST. This script performs a Pipek-Mezey localization for the water molecule using the cc-pVDZ basis set and Mulliken projectors and one frozen core orbital. This frozen core orbital is not localized during the optimization procedure. The localized orbitals are then dump to disk in the molden file format (see also Generating molden files).
from pybest import context
from pybest.gbasis import get_gobasis
from pybest.gbasis.gobasis import (
compute_eri,
compute_kinetic,
compute_nuclear,
compute_nuclear_repulsion,
compute_overlap,
)
from pybest.io.iodata import IOData
from pybest.linalg.dense import DenseLinalgFactory
from pybest.localization import PipekMezey
from pybest.part.mulliken import get_mulliken_operators
from pybest.scf import AufbauOccModel
from pybest.wrappers.hf import RHF
###############################################################################
## Set up molecule, define basis set ##########################################
###############################################################################
# Use the XYZ file from PyBEST's test data directory.
fn_xyz = context.get_fn("test/water.xyz")
gobasis = get_gobasis("cc-pvdz", fn_xyz)
###############################################################################
## Define Occupation model, expansion coefficients and overlap ################
###############################################################################
lf = DenseLinalgFactory(gobasis.nbasis)
occ_model = AufbauOccModel(5)
orb_a = lf.create_orbital(gobasis.nbasis)
olp = compute_overlap(gobasis)
###############################################################################
## Construct Hamiltonian ######################################################
###############################################################################
kin = compute_kinetic(gobasis)
na = compute_nuclear(gobasis)
er = compute_eri(gobasis)
external = compute_nuclear_repulsion(gobasis)
###############################################################################
## Do a Hartree-Fock calculation ##############################################
###############################################################################
hf = RHF(lf, occ_model)
hf_output = hf(kin, na, er, external, olp, orb_a)
###############################################################################
## Define Mulliken projectors #################################################
###############################################################################
mulliken = get_mulliken_operators(gobasis)
###############################################################################
## Pipek-Mezey localizaton ####################################################
###############################################################################
loc = PipekMezey(lf, occ_model, mulliken)
###############################################################################
## occupied block #############################################################
###############################################################################
loc(hf_output, "occ")
###############################################################################
## virtual block ##############################################################
###############################################################################
loc(hf_output, "virt")
###############################################################################
## dump Molden file; hf_ already contains the orb_a attribute #################
###############################################################################
hf_output.gobasis = gobasis
hf_output.to_file("water.molden")