10.17. lo — Orbital localization and analysis tools

The lo module implements various orbital localizations, such as intrinsic atomic orbitals and natural atomic orbitals.

For example, to obtain the natural atomic orbital coefficients (in terms of the original atomic orbitals):

import numpy
from pyscf import gto, scf, lo

x = .63
mol = gto.M(atom=[['C', (0, 0, 0)],
                  ['H', (x ,  x,  x)],
                  ['H', (-x, -x,  x)],
                  ['H', (-x,  x, -x)],
                  ['H', ( x, -x, -x)]],
            basis='ccpvtz')
mf = scf.RHF(mol).run()

# C matrix stores the AO to localized orbital coefficients
C = lo.orth_ao(mf, 'nao')

10.17.1. Examples

Relevant examples examples/local_orb/01-pop_with_meta_lowdin.py examples/local_orb/01-pop_with_nao.py examples/local_orb/02-pop_with_iao.py examples/local_orb/03-split_localization.py examples/local_orb/04-ibo_benzene_cubegen.py examples/local_orb/05-ibo_periodic_diamond_cubegen.py examples/local_orb/10-modify_valence_space_for_meta_lowdin.py examples/local_orb/40-hubbard_model_PM_localization.py examples/local_orb/nlocal.py examples/local_orb/pmloc.py examples/local_orb/ulocal.py

10.17.2. Program reference

10.17.3. Foster-Boys, Edmiston-Ruedenberg, Pipek-Mezey localization

Foster-Boys localization

pyscf.lo.boys.BF

alias of pyscf.lo.boys.Boys

class pyscf.lo.boys.Boys(mol, mo_coeff=None)[source]

The Foster-Boys localization optimizer that maximizes the orbital dipole

sum_i | <i| r |i> |^2

Args:

mol : Mole object

Kwargs:
mo_coeffsize (N,N) np.array

The orbital space to localize for Boys localization. When initializing the localization optimizer bopt = Boys(mo_coeff),

Note these orbitals mo_coeff may or may not be used as initial guess, depending on the attribute .init_guess . If .init_guess is set to None, the mo_coeff will be used as initial guess. If .init_guess is ‘atomic’, a few atomic orbitals will be constructed inside the space of the input orbitals and the atomic orbitals will be used as initial guess.

Note when calling .kernel(orb) method with a set of orbitals as argument, the orbitals will be used as initial guess regardless of the value of the attributes .mo_coeff and .init_guess.

Attributes for Boys class:
verboseint

Print level. Default value equals to Mole.verbose.

max_memoryfloat or int

Allowed memory in MB. Default value equals to Mole.max_memory.

conv_tolfloat

Converge threshold. Default 1e-6

conv_tol_gradfloat

Converge threshold for orbital rotation gradients. Default 1e-3

max_cycleint

The max. number of macro iterations. Default 100

max_itersint

The max. number of iterations in each macro iteration. Default 20

max_stepsizefloat

The step size for orbital rotation. Small step (0.005 - 0.05) is prefered. Default 0.03.

init_guessstr or None

Initial guess for optimization. If set to None, orbitals defined by the attribute .mo_coeff will be used as initial guess. If set to ‘atomic’, atomic orbitals will be used as initial guess. Default is ‘atomic’

Saved results

mo_coeffndarray

Localized orbitals

get_init_guess(key='atomic')[source]

Generate initial guess for localization.

Kwargs:
keystr or bool

If key is ‘atomic’, initial guess is based on the projected atomic orbitals. False

pyscf.lo.boys.FB

alias of pyscf.lo.boys.Boys

Edmiston-Ruedenberg localization

pyscf.lo.edmiston.ER

alias of pyscf.lo.edmiston.EdmistonRuedenberg

pyscf.lo.edmiston.Edmiston

alias of pyscf.lo.edmiston.EdmistonRuedenberg

class pyscf.lo.edmiston.EdmistonRuedenberg(mol, mo_coeff=None)[source]

Pipek-Mezey localization

ref. JCTC, 10, 642 (2014); DOI:10.1021/ct401016x

pyscf.lo.pipek.PM

alias of pyscf.lo.pipek.PipekMezey

pyscf.lo.pipek.Pipek

alias of pyscf.lo.pipek.PipekMezey

class pyscf.lo.pipek.PipekMezey(mol, mo_coeff=None, mf=None)[source]

The Pipek-Mezey localization optimizer that maximizes the orbital population

Args:

mol : Mole object

Kwargs:
mo_coeffsize (N,N) np.array

The orbital space to localize for PM localization. When initializing the localization optimizer bopt = PM(mo_coeff),

Note these orbitals mo_coeff may or may not be used as initial guess, depending on the attribute .init_guess . If .init_guess is set to None, the mo_coeff will be used as initial guess. If .init_guess is ‘atomic’, a few atomic orbitals will be constructed inside the space of the input orbitals and the atomic orbitals will be used as initial guess.

Note when calling .kernel(orb) method with a set of orbitals as argument, the orbitals will be used as initial guess regardless of the value of the attributes .mo_coeff and .init_guess.

Attributes for PM class:
verboseint

Print level. Default value equals to Mole.verbose.

max_memoryfloat or int

Allowed memory in MB. Default value equals to Mole.max_memory.

conv_tolfloat

Converge threshold. Default 1e-6

conv_tol_gradfloat

Converge threshold for orbital rotation gradients. Default 1e-3

max_cycleint

The max. number of macro iterations. Default 100

max_itersint

The max. number of iterations in each macro iteration. Default 20

max_stepsizefloat

The step size for orbital rotation. Small step (0.005 - 0.05) is prefered. Default 0.03.

init_guessstr or None

Initial guess for optimization. If set to None, orbitals defined by the attribute .mo_coeff will be used as initial guess. If set to ‘atomic’, atomic orbitals will be used as initial guess. Default ‘atomic’

pop_methodstr

How the orbital population is calculated. By default, meta-lowdin population (JCTC, 10, 3784) is used. It can be set to ‘mulliken’, or ‘lowdin’ for other population definition

exponentint

The power to define norm. It can be 2 or 4. Default 2.

Saved results

mo_coeffndarray

Localized orbitals

atomic_pops(mol, mo_coeff, method=None)[source]
Kwargs:
methodstring

The atomic population projection scheme. It can be mulliken, lowdin, meta_lowdin, iao, or becke

Returns:

A 3-index tensor [A,i,j] indicates the population of any orbital-pair density |i><j| for each species (atom in this case). This tensor is used to construct the population and gradients etc.

You can customize the PM localization wrt other population metric, such as the charge of a site, the charge of a fragment (a group of atoms) by overwriting this tensor. See also the example pyscf/examples/loc_orb/40-hubbard_model_PM_localization.py for the PM localization of site-based population for hubbard model.

pyscf.lo.pipek.atomic_pops(mol, mo_coeff, method='meta_lowdin', mf=None)[source]
Kwargs:
methodstring

The atomic population projection scheme. It can be mulliken, lowdin, meta_lowdin, iao, or becke

Returns:

A 3-index tensor [A,i,j] indicates the population of any orbital-pair density |i><j| for each species (atom in this case). This tensor is used to construct the population and gradients etc.

You can customize the PM localization wrt other population metric, such as the charge of a site, the charge of a fragment (a group of atoms) by overwriting this tensor. See also the example pyscf/examples/loc_orb/40-hubbard_model_PM_localization.py for the PM localization of site-based population for hubbard model.

10.17.4. Meta-Lowdin

pyscf.lo.orth.lowdin(s)[source]

new basis is |mu> c^{lowdin}_{mu i}

pyscf.lo.orth.orth_ao(mf_or_mol, method='meta_lowdin', pre_orth_ao=None, scf_method=None, s=None)[source]

Orthogonalize AOs

Kwargs:
methodstr

One of | lowdin : Symmetric orthogonalization | meta-lowdin : Lowdin orth within core, valence, virtual space separately (JCTC, 10, 3784) | NAO

pre_orth_ao: numpy.ndarray

Coefficients to restore AO characters for arbitrary basis. If not given, the coefficients are generated based on ANO basis. You can skip this by setting pre_orth_ao to identity matrix, e.g. np.eye(mol.nao).

pyscf.lo.orth.pre_orth_ao(mol, method='ANO')[source]

Restore AO characters. Possible methods include the ANO/MINAO projection or fraction-averaged atomic RHF calculation

pyscf.lo.orth.pre_orth_project_ano(mol, basname)

projected AO = |bas><bas|ANO>

pyscf.lo.orth.project_to_atomic_orbitals(mol, basname)[source]

projected AO = |bas><bas|ANO>

pyscf.lo.orth.restore_ao_character(mol, method='ANO')

Restore AO characters. Possible methods include the ANO/MINAO projection or fraction-averaged atomic RHF calculation

pyscf.lo.orth.vec_lowdin(c, s=1)[source]

lowdin orth for the metric c.T*s*c and get x, then c*x

pyscf.lo.orth.vec_schmidt(c, s=1)[source]

schmidt orth for the metric c.T*s*c and get x, then c*x

pyscf.lo.orth.weight_orth(s, weight)[source]

new basis is |mu> c_{mu i}, c = w[(wsw)^{-1/2}]

10.17.5. Natural atomic orbitals

Natural atomic orbitals Ref:

  1. Weinhold et al., J. Chem. Phys. 83(1985), 735-746

pyscf.lo.nao.set_atom_conf(element, description)[source]

Change the default atomic core and valence configuration to the one given by “description”. See data/elements.py for the default configuration.

Args:
elementstr or int

Element symbol or nuclear charge

descriptionstr or a list of str
“double p” : double p shell
“double d” : double d shell
“double f” : double f shell
“polarize” : add one polarized shell
“1s1d” : keep core unchanged and set 1 s 1 d shells for valence
(“3s2p”,”1d”) : 3 s, 2 p shells for core and 1 d shells for valence

10.17.6. Intrinsic Atomic Orbitals

Intrinsic Atomic Orbitals ref. JCTC, 9, 4834

pyscf.lo.iao.fast_iao_mullikan_pop(mol, dm, iaos, verbose=5)[source]
Args:

mol : the molecule or cell object

iaos2D array

(orthogonal or non-orthogonal) IAO orbitals

Returns:

mullikan population analysis in the basis IAO

pyscf.lo.iao.iao(mol, orbocc, minao='minao', kpts=None)[source]

Intrinsic Atomic Orbitals. [Ref. JCTC, 9, 4834]

Args:

mol : the molecule or cell object

orbocc2D array

occupied orbitals

Returns:

non-orthogonal IAO orbitals. Orthogonalize them as C (C^T S C)^{-1/2}, eg using orth.lowdin()

>>> orbocc = mf.mo_coeff[:,mf.mo_occ>0]
>>> c = iao(mol, orbocc)
>>> numpy.dot(c, orth.lowdin(reduce(numpy.dot, (c.T,s,c))))
pyscf.lo.iao.reference_mol(mol, minao='minao')[source]

Create a molecule which uses reference minimal basis

10.17.7. Intrinsic Bond Orbitals

Intrinsic Bonding Orbitals ref. JCTC, 9, 4834

Below here is work done by Paul Robinson. much of the code below is adapted from code published freely on the website of Gerald Knizia Ref: JCTC, 2013, 9, 4834-4843

pyscf.lo.ibo.MakeAtomIbOffsets(Atoms)[source]

calcualte offset of first orbital of individual atoms in the valence minimal basis (IB)

pyscf.lo.ibo.PM(mol, orbocc, iaos, s, exponent)

Note this localization is slightly different to Knizia’s implementation. The localization here reserves orthogonormality during optimization. Orbitals are projected to IAO basis first and the Mulliken pop is calculated based on IAO basis (in function atomic_pops). A series of unitary matrices are generated and applied on the input orbitals. The intemdiate orbitals in the optimization and the finally localized orbitals are all orthogonormal.

Examples:

>>> from pyscf import gto, scf
>>> from pyscf.lo import ibo
>>> mol = gto.M(atom='H 0 0 0; F 0 0 1', >>> basis='unc-sto3g')
>>> mf = scf.RHF(mol).run()
>>> pm = ibo.PM(mol, mf.mo_coeff[:,mf.mo_occ>0])
>>> loc_orb = pm.kernel()
pyscf.lo.ibo.Pipek(mol, orbocc, iaos, s, exponent)

Note this localization is slightly different to Knizia’s implementation. The localization here reserves orthogonormality during optimization. Orbitals are projected to IAO basis first and the Mulliken pop is calculated based on IAO basis (in function atomic_pops). A series of unitary matrices are generated and applied on the input orbitals. The intemdiate orbitals in the optimization and the finally localized orbitals are all orthogonormal.

Examples:

>>> from pyscf import gto, scf
>>> from pyscf.lo import ibo
>>> mol = gto.M(atom='H 0 0 0; F 0 0 1', >>> basis='unc-sto3g')
>>> mf = scf.RHF(mol).run()
>>> pm = ibo.PM(mol, mf.mo_coeff[:,mf.mo_occ>0])
>>> loc_orb = pm.kernel()
pyscf.lo.ibo.PipekMezey(mol, orbocc, iaos, s, exponent)[source]

Note this localization is slightly different to Knizia’s implementation. The localization here reserves orthogonormality during optimization. Orbitals are projected to IAO basis first and the Mulliken pop is calculated based on IAO basis (in function atomic_pops). A series of unitary matrices are generated and applied on the input orbitals. The intemdiate orbitals in the optimization and the finally localized orbitals are all orthogonormal.

Examples:

>>> from pyscf import gto, scf
>>> from pyscf.lo import ibo
>>> mol = gto.M(atom='H 0 0 0; F 0 0 1', >>> basis='unc-sto3g')
>>> mf = scf.RHF(mol).run()
>>> pm = ibo.PM(mol, mf.mo_coeff[:,mf.mo_occ>0])
>>> loc_orb = pm.kernel()
pyscf.lo.ibo.ibo(mol, orbocc, locmethod='IBO', iaos=None, s=None, exponent=4, grad_tol=1e-08, max_iter=200, verbose=3)[source]

Intrinsic Bonding Orbitals

This function serves as a wrapper to the underlying localization functions ibo_loc and PipekMezey to create IBOs.

Args:

mol : the molecule or cell object

orbocc : occupied molecular orbital coefficients

Kwargs:
locmethodstring

the localization method ‘PM’ for Pipek Mezey localization or ‘IBO’ for the IBO localization

iaos2D array

the array of IAOs

s2D array

the overlap array in the ao basis

Returns:

IBOs in the basis defined in mol object.

pyscf.lo.ibo.ibo_loc(mol, orbocc, iaos, s, exponent, grad_tol, max_iter, verbose=3)[source]

Intrinsic Bonding Orbitals. [Ref. JCTC, 9, 4834]

This implementation follows Knizia’s implementation execept that the resultant IBOs are symmetrically orthogonalized. Note the IBOs of this implementation do not strictly maximize the IAO Mulliken charges.

IBOs can also be generated by another implementation (see function pyscf.lo.ibo.PM). In that function, PySCF builtin Pipek-Mezey localization module was used to maximize the IAO Mulliken charges.

Args:

mol : the molecule or cell object

orbocc2D array or a list of 2D array

occupied molecular orbitals or crystal orbitals for each k-point

Kwargs:
iaos2D array

the array of IAOs

exponentinteger

Localization power in PM scheme

grad_tolfloat

convergence tolerance for norm of gradients

Returns:

IBOs in the big basis (the basis defined in mol object).

pyscf.lo.ibo.shell_str(l, n_cor, n_val)[source]

Help function to define core and valence shells for shell with different l