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]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