Source code for moha.system.operator.two_electron

from moha.system.operator.base import OperatorNames, BaseOperator
from moha.system.molecule import Molecule
from moha.system.basis.basis_set import BasisSet
import numpy as np

[docs]class TwoElectronOperator(BaseOperator): """Two electron operator class. Attributes ---------- name : str Name of the operator. nspatial : int Number of the spatial orbitals. nelectron : int Number of electrons. integral : np.ndarray Integral of the operator. Property -------- npsin : int Number of spin orbitals. dtype : Data type of the integrals. spin_orbital_basis_integral Return integral matrix in spin orbitals basis. Methods ------- __init__(self,name,nspatial,integral) Initialize the Operator. assign_name(self,name) Assign name to the operator. assign_nspatial(self,nspatial) Assign number of spatial orbitals for the operator. assign_nelectron(self,nelectron) Assign number of elctrons involved in the integral. assign_integral(self,integral) Assign integral value for the operator. basis_transformation(self,matrix): Rotate orbitals with a transformation matrix. """ def __init__(self, integral, name): """Initialize the operator Parameters ---------- integral : ndarray Integral value for the operator. name : OperatorNames Name of the operator. """ super().__init__(integral, name) @property def nspatial(self): """Number of spatial orbitals. Returns ------- nspatial : int Number of spatial orbitals. """ return self.shape[0] @property def nspin(self): """Number of spin orbitals. Returns ------- nspin : int Number of spin orbitals. """ return self.shape[0]*2 @property def spin_orbital_basis_integral(self): """Return integral in spin orbitals basis. Returns ------- integral : np.ndarray Integral of the operator in spin orbital basis. """ nspin = self.nspin integral = np.zeros((nspin,nspin,nspin,nspin)) for i in range(nspin): for j in range(nspin): for k in range(nspin): for l in range(nspin): if i%2==k%2 and j%2==l%2: integral[i,j,k,l] = self[int(i/2),int(k/2),int(j/2),int(l/2)] return integral
[docs] @classmethod def zeros(cls, shape, dtype=float): """generate instance with zeros elements ndarray. Parameters ---------- shape : tuple/list Shape of the ndarray. Raises ------ ValueError If shape is not two dimension. """ if not len(shape)==4: raise ValueError("Shape of the ndarray must be four dimension") super().zeros(shape, dtype=float)
[docs] @classmethod def ones(cls, shape, dtype=float): """generate instance with ones elements ndarray. Parameters ---------- shape : tuple/list Shape of the ndarray. Raises ------ ValueError If shape is not two dimension. """ if not len(shape)==4: raise ValueError("Shape of the ndarray must be four dimension") super().ones(shape, dtype=float)
[docs] @classmethod def random(cls, shape, dtype=float): """generate instance with random elements ndarray. Parameters ---------- shape : tuple/list Shape of the ndarray. Raises ------ ValueError If shape is not two dimension. """ if not len(shape)==4: raise ValueError("Shape of the ndarray must be four dimension") super().random(shape, dtype=float)
[docs] def basis_transformation(self,matrix): """Rotate orbitals with a transformation matrix. .. math:: \widetilde{h}_{ab} &= \sum_{ij} C^\dagger_{ai} h_{ij} C_{jb}\\ \widetilde{g}_{abcd} &= \sum_{ijkl} C^\dagger_{ai} C^\dagger_{bj} g_{ijkl} C_{kc} C_{ld} Parameters ---------- matrix : np.ndarray(K, L) Transformation matrix. Raises ------ TypeError If matrix is not a numpy array. ValueError If shape of matrix does not match up with the shape of the integrals. """ if not isinstance(matrix, np.ndarray): raise TypeError("Transformation matrix must be given as a numpy array.") if matrix.ndim != 2: raise ValueError("Transformation matrix must be two-dimensional.") if matrix.shape[0] != self.shape[0]: raise ValueError( "Shape of the transformation matrix must match with the shape of the " "integrals." ) integral = np.einsum("ijkl,ia->ajkl", self, matrix) integral = np.einsum("ajkl,jb->abkl", integral, matrix) integral = np.einsum("abkl,kc->abcl", integral, matrix) integral = np.einsum("abcl,ld->abcd", integral, matrix) self[:] = integral[:] return self
[docs]class ElectronRepulsionOperator(TwoElectronOperator): """Electron repulsion operator class. Attributes ---------- name : str Name of the operator. nspatial : int Number of the spatial orbitals. nelectron : int Number of electrons. integral : np.ndarray Integral of the operator. Property -------- npsin : int Number of spin orbitals. spin_orbital_basis_integral(self) Return integral matrix in spin orbitals basis. Methods ------- __init__(self,name,nspatial,integral) Initialize the Operator. assign_name(self,name) Assign name to the operator. assign_nspatial(self,nspatial) Assign number of spatial orbitals for the operator. assign_nelectron(self,nelectron) Assign number of elctrons involved in the integral. assign_integral(self,integral) Assign integral value for the operator. basis_transformation(self,matrix) Rotate orbitals with a transformation matrix. """ def __init__(self, integral, name=OperatorNames.Eri): """Initialize the operator Parameters ---------- integral : ndarray Integral value for the operator. name : OperatorNames name of the operator. """ super().__init__(integral, name)
[docs] @classmethod def build(cls,basis_set): """Build the nuclear repulsion operator. Parameters ---------- basis_set : BasisSet Hatree Fock basis set instance. Raises ------ TypeError If basis_set parameter is not a BasisSet instance. """ from moha.system.integral.electron_repulsion import electron_repulsion from moha.system.auxiliary import eint if not isinstance(basis_set, BasisSet): raise TypeError("basis_set parameter must be a BasisSet instance") nspatial = len(basis_set) integral_list = [] integral = np.zeros((nspatial,nspatial,nspatial,nspatial)) for i,oi in enumerate(basis_set): for j,oj in enumerate(basis_set[0:i+1]): for k,ok in enumerate(basis_set[0:i+1]): for l,ol in enumerate(basis_set[0:k+1]): ij = i*(i+1)*0.5+j kl = k*(k+1)*0.5+l if ij>=kl: integral_list.append(electron_repulsion(oi,oj,ok,ol)) for i in range(nspatial): for j in range(nspatial): for k in range(nspatial): for l in range(nspatial): integral[i,j,k,l] = integral_list[eint(i,j,k,l)] operator = cls(integral,OperatorNames.Eri) return operator
@property def coulomb(self): """Coulomb integral. Returns ------- integral : np.ndarray Coulomb integral. """ nspatial = self.nspatial integral = np.zeros((nspatial,nspatial)) for i in range(nspatial): for j in range(nspatial): integral[i,j] = self[i,i,j,j] return integral @property def exchange(self): """Exchange integral. Returns ------- integral : np.ndarray Exchange integral. """ nspatial = self.nspatial integral = np.zeros((nspatial,nspatial)) for i in range(nspatial): for j in range(nspatial): integral[i,j] = self[i,j,i,j] return integral @property def double_bar(self): """Antisymmetrized two electron integral. Returns ------- integral : np.ndarray Antisymmetrized two electron integral. """ nspin = self.nspin integral = np.zeros((nspin,nspin,nspin,nspin)) spin_integral = self.spin_orbital_basis_integral for i in range(nspin): for j in range(nspin): for k in range(nspin): for l in range(nspin): integral[i,j,k,l] = spin_integral[i,j,k,l] - spin_integral[i,j,l,k] return integral