Non Orthogonal Configuration Interaction#
In this example we will show how a NOCI calculation can be performed with GQCP.
Import dependancies#
# Force the local gqcpy to be imported
import sys
sys.path.insert(0, '../../build/gqcpy/')
import gqcpy
import numpy as np
We start by creating the molecule and an associated spinor basis.
molecule = gqcpy.Molecule.HChain(2, 2.5, 0)
N = molecule.numberOfElectrons()
spinor_basis = gqcpy.GSpinorBasis_d(molecule, "6-31G")
In this general spinor basis, we can do two more things we will need for our NOCI calculation:
Quantize the overlap operator, which will serve as a metric in the NOCI basis
Quantize the Hamiltonian, which we will need for the eventual calculation
fq_hamiltonian = gqcpy.FQMolecularHamiltonian(molecule)
hamiltonian = spinor_basis.quantize(fq_hamiltonian)
S = spinor_basis.quantize(gqcpy.OverlapOperator())
Next, we will select our basis states. In this example, we will use generalized states. These can be calcluated with any of the QC methods present in the package, but we will define our basis states by hand.
state_1 = gqcpy.GTransformation_d(np.array([[-0.07443693, 0.12036042, -0.13557067, 0.15517005, 0.133151, -0.03074946, -0.92997876, -0.93718779],
[-0.07874922, 0.15086478, -0.68085546, 0.77423311, 0.08712373, 0.25266303, 0.848079 , 0.89108911],
[-0.24580188, 0.26338108, 0.09556297, -0.12178159, 0.91319299, 0.90475733, -0.03994767, 0.12839983],
[-0.38944259, 0.4101685 , 0.45214166, -0.58335985, -0.90125958, -0.93270816, -0.16410814, -0.32074956],
[-0.26338108, -0.24580188, -0.12178159, -0.09556297, -0.90475733, 0.91319299, -0.12839983, -0.03994767],
[-0.4101685 , -0.38944259, -0.58335985, -0.45214166, 0.93270817, -0.90125958, 0.32074956, -0.16410814],
[-0.12036042, -0.07443693, 0.15517005, 0.13557067, 0.03074946, 0.13315101, 0.93718779, -0.92997876],
[-0.15086478, -0.07874922, 0.77423311, 0.68085546, -0.25266303, 0.08712373, -0.89108911, 0.848079 ]]))
state_2 = gqcpy.GTransformation_d(np.array([[ 0.25851329, -0.14539151, -0.17177142, -0.01126487, 0.81289875, -0.77260907, 0.50167389, -0.44422385],
[ 0.36593356, -0.28669343, -0.84796858, -0.13503625, -0.62437698, 0.96771154, -0.55231929, 0.30317456],
[ 0.25853403, 0.14539669, 0.17176599, -0.01126146, 0.81450567, 0.7709918 , -0.501289 , -0.44451308],
[ 0.36597032, 0.28670189, 0.847938 , -0.13501526, -0.62639487, -0.96647128, 0.5520554 , 0.30349133],
[ 0.10076798, -0.23874662, 0.04823423, 0.17685836, 0.42013282, -0.48352714, -0.79642816, 0.8239984 ],
[ 0.16561668, -0.35007843, 0.19502141, 0.90182842, -0.55545195, 0.39170258, 0.56753639, -0.94408827],
[-0.10075937, -0.23872464, 0.0482368 , -0.17686313, -0.42104909, -0.4826058 , -0.79588057, -0.82460595],
[-0.16560552, -0.35003836, 0.19503259, -0.9018579 , 0.55619574, 0.39048771, 0.56690551, 0.94451894]]))
state_3 = gqcpy.GTransformation_d(np.array([[-0.265842 , 0.17716735, -0.15969328, -0.00308706, 0.84741422, -0.81942223, 0.41366608, -0.36889812],
[-0.36278694, 0.36406651, -0.80340861, -0.13144475, -0.65133121, 1.03324716, -0.44428872, 0.24605534],
[-0.26584976, -0.17716927, 0.15969112, -0.00308558, 0.84933355, 0.81745234, -0.41355441, -0.36897416],
[-0.36280035, -0.36406982, 0.80339638, -0.13143372, -0.65375477, -1.0317334 , 0.4442138 , 0.24613641],
[-0.09736842, 0.22594293, 0.06676532, 0.17043252, 0.3439281 , -0.39253422, -0.84701679, 0.86052195],
[-0.15038318, 0.32968947, 0.23916148, 0.91374992, -0.47007004, 0.32909412, 0.60131983, -0.98100354],
[ 0.0973641 , 0.22593416, 0.06676626, -0.17043417, -0.34482098, -0.39170837, -0.84682078, -0.86073623],
[ 0.15037797, 0.32967347, 0.2391655 , -0.91376119, 0.47081908, 0.32796701, 0.60109455, 0.98115454]])
)
basis_state_vector = [state_1, state_2, state_3]
We can now create our non-orthogonal basis for NOCI from these states.
non_orthogonal_basis = gqcpy.GNonOrthogonalStateBasis_d(basis_state_vector, S, N)
With this basis, we can set up the NOCI calculation.
environment = gqcpy.NOCIEnvironment.Dense_d(hamiltonian, non_orthogonal_basis, molecule)
solver = gqcpy.GeneralizedEigenproblemSolver.Dense_d()
We now possess the tools to optimize the NOCI problem. We do not specify the number of states we want to calculate, so we will only get the ground state.
qc_structure = gqcpy.NOCI_d(non_orthogonal_basis).optimize(solver, environment)
energy = qc_structure.groundStateEnergy()
print(energy)
-1.0474986523211276