Orbital bases#

Creating an orbital basis#

An intermediary step in-between the creation of a Molecule object and the calculation of the integrals for this molecule, is the initialization of an orbital basis. In molecular electronic structure theory based on wave function models, we often express a set of orthonormal spinors or spin-orbitals as linear combinations of basis functions.

Here’s where the spinor-basis objects come into play. They encapsulate the expansion coefficients, together with the atomic orbital basis. You can create a restricted spin-orbital basis (RSpinOrbitalBasis) by specifying the molecule and the name of the basisset that you would like to use.

spinor_basis = RSpinOrbitalBasis(molecule, "STO-3G")
const GQCP::RSpinOrbitalBasis<double, GQCP::GTOShell> spinor_basis {molecule, "STO-3G"};  // note that you have to specify the type of shell that underlies this spin-orbital basis

The constructor then places scalar AOs on every nucleus in the molecule, according to the basisset specification.

Note: Spinor bases constructed in this way represent non-orthogonal spin-orbital bases.

Additional information: For more theoretical information, please visit our knowdes on spinor bases, spin-orbital bases and on quantizing one- and two-electron operators.

Calculating integrals#

One of the most important ingredients for any quantum chemical method are its one- and two-electron integrals. Calculating the integrals, which is actually short for calculating the matrix representation of various first-quantized one- and two-electron operators in a spinor basis, is made fairly simple. If you are acquainted with the modern electronic structure framework of second quantization, you will find it very natural to use.

SpinorBases are responsible for expressing spinors in the underlying scalar orbitals. Subsequently, a SpinorBasis instance provides .quantize() methods that can create second-quantized representations of the corresponding first-quantized operators. More or less, this means that SpinorBasis instances provide the interface to calculate the matrix representations of one- and two-electron integrals.

Below, we can find examples how the overlap, kinetic energy, potential energy and interelectronic repulsion energy operators can be expressed in the recently initialized spinor_basis. The process of expressing these first-quantized one- and two-electron integrals in the spinor basis is what we call quantizing.

S_op = spinor_basis.quantize(gqcpy.OverlapOperator())
T_op = spinor_basis.quantizeKineticOperator()
V_op = spinor_basis.quantizeNuclearAttractionOperator(molecule.nuclearFramework())  # the nuclear attraction operator is defined with respect to the molecule's nuclear framework

g_op = spinor_basis.quantizeCoulombRepulsionOperator()
const auto S = spinor_basis.quantize(GQCP::OverlapOperator());
const auto T = spinor_basis.quantize(GQCP::KineticOperator());
const auto V = spinor_basis.quantize(GQCP::NuclearAttractionOperator(molecule.nuclearFramework()));  // the nuclear attraction operator is defined with respect to the molecule's nuclear framework

const auto g = spinor_basis.quantize(GQCP::CoulombRepulsionOperator());

The instances S_op, T_op, V_op and g_op represent the second-quantized representations of the overlap, kinetic energy, nuclear attraction and interelectronic repulsion operators and they encapsulate the corresponding matrix representations of the integrals. We can access the raw matrix representations using the .parameters() method.

S = S_op.parameters()
T = T_op.parameters()
V = V_op.parameters()

g = g_op.parameters()
const auto S = S_op.parameters();
const auto T = T_op.parameters();
const auto V = V_op.parameters();

const auto g = g_op.parameters();

Note: The matrices/tensors that we have calculated here are associated to the non-orthogonal AO basis.