(Iterative) Hirshfeld method

In this tutorial, we will introduce how to use the horton_part API method to execute (iterative) Hirshfeld partitioning methods.

First, we import the required libraries.

[1]:
import numpy as np
from gbasis.evals.eval import evaluate_basis
from gbasis.wrappers import from_iodata
from grid import AtomGrid, ExpRTransform, UniformInteger
from iodata import load_one
from setup import prepare_grid_and_dens, print_results

from horton_part import HirshfeldIWPart, HirshfeldWPart, ProAtomDB, ProAtomRecord

np.set_printoptions(precision=3, linewidth=np.inf, suppress=True)

In (iterative) Hirshfeld methods, a database of atomic radial density profiles is required. Therefore, different single-atom DFT or other ab initio calculations should be executed. Here, we use the Gaussian package. The checkpoint files, in fchk format, are generated using Gaussian tools as well.

Next, the radial atomic density is obtained by computing the spherical average of the atomic density. This process can be applied using the gbasis and grid packages.

[2]:
def prepare_record(filename):
    """Prepare molecular grid and density."""
    mol = load_one(filename)

    # Specify the integration grid
    rtf = ExpRTransform(5e-4, 2e1, 120 - 1)
    uniform_grid = UniformInteger(120)
    rgrid = rtf.transform_1d_grid(uniform_grid)

    # Get the spin-summed density matrix
    one_rdm = mol.one_rdms.get("post_scf", mol.one_rdms.get("scf"))
    basis = from_iodata(mol)
    assert len(mol.atnums) == 1
    grid = AtomGrid.from_preset(atnum=mol.atnums[0], preset="fine", rgrid=rgrid)

    basis_grid = evaluate_basis(basis, grid.points)
    rho = np.einsum("ab,bp,ap->p", one_rdm, basis_grid, basis_grid, optimize=True)
    spline = grid.spherical_average(rho)
    radial_rho = spline(rgrid.points)

    record = ProAtomRecord(mol.atnums[0], mol.charge, mol.energy, rgrid, radial_rho)
    return record

In this tutorial, we focus on the water molecule and therefore only need data for hydrogen and oxygen atoms. It should be noted that data for both cations and anions are also used.

[3]:
h_1 = prepare_record("./data/atoms/001__h_001_q+00/mult02/atom.fchk")
h_2 = prepare_record("./data/atoms/001__h_002_q-01/mult01/atom.fchk")
o_7 = prepare_record("./data/atoms/008__o_007_q+01/mult04/atom.fchk")
o_8 = prepare_record("./data/atoms/008__o_008_q+00/mult03/atom.fchk")
o_9 = prepare_record("./data/atoms/008__o_009_q-01/mult02/atom.fchk")

records = [h_1, h_2, o_7, o_8, o_9]
db = ProAtomDB(records)

Next, we prepare the molecular grid and densities as described in the Basic Usage section. It should be noted that the radial grids for atoms in the water molecule should match the atomic radial grids used for the corresponding single atoms in the atomic database calculations.

[4]:
def prepare_argument_dict(mol, grid, rho):
    """Prepare basic input arguments for all AIM methods."""
    kwargs = {
        "coordinates": mol.atcoords,
        "numbers": mol.atnums,
        "pseudo_numbers": mol.atnums,
        "grid": grid,
        "moldens": rho,
        "lmax": 3,
        "proatomdb": db,
    }
    return kwargs

Hirshfeld method

The Hirshfeld method can be executed using the HirshfeldWPart class.

[5]:
mol, grid, rho = prepare_grid_and_dens("data/h2o.fchk")
kwargs = prepare_argument_dict(mol, grid, rho)
h = HirshfeldWPart(**prepare_argument_dict(mol, grid, rho))
h.do_all()
print_results(h)
The number of electrons: 10.000003764139395
Coordinates of the atoms
 [[ 0.     0.     0.224]
 [-0.     1.457 -0.896]
 [-0.    -1.457 -0.896]]
Atomic numbers of the atom
 [8 1 1]

================================================================================
Information of integral grids.
--------------------------------------------------------------------------------
Grid size of molecular grid: 18460
************************************ Atom 0 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18
          18 18 18 18 18 18 26 26 26 26 38 38 38 38 38 50 50 50 50 50
          86 86 110 110 110 110 170 194 194 434 590 590 434 434 434 302 302 302 194 194
          170 110 110 110 110 110 110 110 110 110 110 110 86 50 50 18 18 18 18 18

************************************ Atom 1 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 18 18 18 18 18
          18 18 18 18 18 18 18 18 18 26 26 26 38 38 38 38 38 38 38 50
          50 50 50 50 50 86 86 86 110 110 110 170 170 170 194 194 194 194 170 170
          170 110 110 110 110 110 110 110 110 110 110 86 86 50 50 50 18 18 18 18

************************************ Atom 2 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 18 18 18 18 18
          18 18 18 18 18 18 18 18 18 26 26 26 38 38 38 38 38 38 38 50
          50 50 50 50 50 86 86 86 110 110 110 170 170 170 194 194 194 194 170 170
          170 110 110 110 110 110 110 110 110 110 110 86 86 50 50 50 18 18 18 18

--------------------------------------------------------------------------------
================================================================================

Performing a density-based AIM analysis with a wavefunction as input.
  Molecular grid    : MolGrid
  Using local grids : True
Initialized: HirshfeldWPart
  Scheme       : Hirshfeld
  Proatomic DB : <horton_part.core.proatomdb.ProAtomDB object at 0x107d43190>
Computing atomic populations.
Computing atomic charges.
Computing density decomposition for atom 0
Computing density decomposition for atom 1
Computing density decomposition for atom 2
Computing cartesian and pure AIM multipoles and radial AIM moments.
Computing atomic dispersion coefficients.
Storing proatom density spline for atom 0.
Storing proatom density spline for atom 1.
Storing proatom density spline for atom 2.
charges:
[-0.305  0.153  0.153]
cartesian multipoles:
[[-0.305 -0.    -0.    -0.253 -4.416 -0.    -0.    -3.647 -0.    -4.093 -0.    -0.    -0.637 -0.    -0.    -0.    -0.    -0.247 -0.    -1.401]
 [ 0.153 -0.     0.167 -0.131 -0.758 -0.    -0.    -0.643  0.035 -0.689 -0.     0.206 -0.2   -0.    -0.    -0.     0.468 -0.127  0.164 -0.454]
 [ 0.153  0.    -0.167 -0.131 -0.758  0.     0.    -0.643 -0.035 -0.689 -0.    -0.206 -0.2   -0.    -0.    -0.    -0.468 -0.127 -0.164 -0.454]]

Iterative Hirshfeld method

The iterative Hirshfeld method can be executed using HirshfeldIWpart class.

[6]:
hi = HirshfeldIWPart(**prepare_argument_dict(mol, grid, rho))
hi.do_all()
print_results(hi)

================================================================================
Information of integral grids.
--------------------------------------------------------------------------------
Grid size of molecular grid: 18460
************************************ Atom 0 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18
          18 18 18 18 18 18 26 26 26 26 38 38 38 38 38 50 50 50 50 50
          86 86 110 110 110 110 170 194 194 434 590 590 434 434 434 302 302 302 194 194
          170 110 110 110 110 110 110 110 110 110 110 110 86 50 50 18 18 18 18 18

************************************ Atom 1 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 18 18 18 18 18
          18 18 18 18 18 18 18 18 18 26 26 26 38 38 38 38 38 38 38 50
          50 50 50 50 50 86 86 86 110 110 110 170 170 170 194 194 194 194 170 170
          170 110 110 110 110 110 110 110 110 110 110 86 86 50 50 50 18 18 18 18

************************************ Atom 2 ************************************
   |-- Radial grid size: 120
   |-- Angular grid sizes:
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
          6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 18 18 18 18 18
          18 18 18 18 18 18 18 18 18 26 26 26 38 38 38 38 38 38 38 50
          50 50 50 50 50 86 86 86 110 110 110 170 170 170 194 194 194 194 170 170
          170 110 110 110 110 110 110 110 110 110 110 86 86 50 50 50 18 18 18 18

--------------------------------------------------------------------------------
================================================================================

Performing a density-based AIM analysis with a wavefunction as input.
  Molecular grid    : MolGrid
  Using local grids : True
Initialized: HirshfeldIWPart
  Scheme                : Hirshfeld-I
  Convergence threshold : 1.0e-06
  Maximum iterations    : 500
  Proatomic DB          : <horton_part.core.proatomdb.ProAtomDB object at 0x107d43190>
Iteration       Change      Entropy
        1   4.91894e-02   2.00489e-01
        2   3.09349e-02   1.80862e-01
        3   1.95877e-02   1.90830e-01
        4   1.26979e-02   2.03872e-01
        5   8.40308e-03   2.14964e-01
        6   5.64913e-03   2.23432e-01
        7   3.84155e-03   2.29631e-01
        8   2.63387e-03   2.34078e-01
        9   1.81637e-03   2.37237e-01
       10   1.25775e-03   2.39468e-01
       11   8.73435e-04   2.41038e-01
       12   6.07777e-04   2.42140e-01
       13   4.23518e-04   2.42912e-01
       14   2.95413e-04   2.43453e-01
       15   2.06199e-04   2.43832e-01
       16   1.43998e-04   2.44098e-01
       17   1.00594e-04   2.44283e-01
       18   7.02895e-05   2.44413e-01
       19   4.91226e-05   2.44503e-01
       20   3.43338e-05   2.44567e-01
       21   2.39993e-05   2.44611e-01
       22   1.67764e-05   2.44642e-01
       23   1.17278e-05   2.44664e-01
       24   8.19875e-06   2.44679e-01
       25   5.73174e-06   2.44690e-01
       26   4.00710e-06   2.44697e-01
       27   2.80143e-06   2.44702e-01
       28   1.95853e-06   2.44706e-01
       29   1.36925e-06   2.44709e-01
       30   9.57279e-07   2.44710e-01

Computing atomic populations.
Computing atomic charges.
Computing density decomposition for atom 0
Computing density decomposition for atom 1
Computing density decomposition for atom 2
Computing cartesian and pure AIM multipoles and radial AIM moments.
Computing atomic dispersion coefficients.
Storing proatom density spline for atom 0.
Storing proatom density spline for atom 1.
Storing proatom density spline for atom 2.
charges:
[-0.862  0.431  0.431]
cartesian multipoles:
[[-0.862  0.    -0.     0.189 -5.147 -0.    -0.    -4.812 -0.    -5.012 -0.    -0.    -0.105  0.     0.     0.     0.     0.58  -0.     0.174]
 [ 0.431 -0.     0.077 -0.04  -0.392 -0.    -0.    -0.389  0.02  -0.375 -0.     0.088 -0.057  0.     0.    -0.     0.264 -0.039  0.083 -0.136]
 [ 0.431  0.    -0.077 -0.04  -0.392  0.     0.    -0.389 -0.02  -0.375  0.    -0.088 -0.057  0.    -0.     0.    -0.264 -0.039 -0.083 -0.136]]
[ ]: