Hamiltonian construction
The HamiltonianConstructor algorithm in QDK/Chemistry constructs electronic Hamiltonians for quantum chemistry calculations.
Following QDK/Chemistry’s algorithm design principles, it takes an Orbitals instance as input and produces a Hamiltonian instance as output.
It generates the one- and two-electron integrals that define the energy operator for the electronic structure.
Overview
The electronic Hamiltonian describes the energy of a system of electrons in the field of atomic nuclei.
It consists of kinetic energy terms, electron-nucleus attraction terms, and electron-electron repulsion terms.
The HamiltonianConstructor algorithm computes the matrix elements of this operator in a given orbital basis, which can be the full orbital space or an active subspace.
Using the HamiltonianConstructor
This section demonstrates how to create, configure, and run a Hamiltonian construction. The run method returns a Hamiltonian object containing the one- and two-electron integrals.
Input requirements
The HamiltonianConstructor requires the following input:
- Orbitals
An Orbitals instance describing the single orbital basis in which to express the many-body Hamiltonian. This object contains information about the molecular structure, basis set, and orbital coefficients.
Note
The Orbitals object carries all the information needed for integral transformation, including the basis set and molecular structure. Active space indices, if present, determine which orbitals are included in the output Hamiltonian.
Creating a constructor
// Create the default HamiltonianConstructor instance
auto hamiltonian_constructor = HamiltonianConstructorFactory::create();
# List available Hamiltonian constructor implementations
available_constructors = available("hamiltonian_constructor")
print(f"Available Hamiltonian constructors: {available_constructors}")
# Create the default HamiltonianConstructor instance
hamiltonian_constructor = create("hamiltonian_constructor")
Configuring settings
Settings can be modified using the settings() object.
See Available implementations below for implementation-specific options.
Note
All orbital indices in QDK/Chemistry are 0-based, following the convention used in most programming languages.
// Configure settings (check available options)
// Note: Available settings can be inspected at runtime
// Set ERI method if needed
hamiltonian_constructor->settings().set("eri_method", "direct");
# Configure settings (check available options)
print(f"Available settings: {hamiltonian_constructor.settings().keys()}")
# Set ERI method if needed
hamiltonian_constructor.settings().set("eri_method", "direct")
Running the calculation
// Load structure from XYZ file
auto structure = std::make_shared<Structure>(
Structure::from_xyz_file("../data/h2.structure.xyz"));
// Run a SCF to get orbitals
auto scf_solver = ScfSolverFactory::create();
scf_solver->settings().set("basis_set", "sto-3g");
auto [E_scf, wfn] = scf_solver->run(structure, 0, 1);
auto orbitals = wfn->get_orbitals();
// Construct the Hamiltonian from orbitals
auto hamiltonian = hamiltonian_constructor->run(orbitals);
// Access the resulting integrals
auto [h1_a, h1_b] = hamiltonian->get_one_body_integrals();
auto [h2_aaaa, h2_aabb, h2_bbbb] = hamiltonian->get_two_body_integrals();
auto core_energy = hamiltonian->get_core_energy();
std::cout << "One-body integrals shape: " << h1_a.rows() << "x" << h1_a.cols()
<< std::endl;
std::cout << "Two-body integrals shape: " << h2_aaaa.dimension(0) << "x"
<< h2_aaaa.dimension(1) << "x" << h2_aaaa.dimension(2) << "x"
<< h2_aaaa.dimension(3) << std::endl;
std::cout << "Core energy: " << std::fixed << std::setprecision(10)
<< core_energy << " Hartree" << std::endl;
std::cout << hamiltonian->get_summary() << std::endl;
# Load a structure from XYZ file
structure = Structure.from_xyz_file(Path(__file__).parent / "../data/h2.structure.xyz")
# Run a SCF to get orbitals
scf_solver = create("scf_solver")
E_scf, wfn = scf_solver.run(
structure, charge=0, spin_multiplicity=1, basis_or_guess="sto-3g"
)
orbitals = wfn.get_orbitals()
# Construct the Hamiltonian from orbitals
hamiltonian = hamiltonian_constructor.run(orbitals)
# Access the resulting integrals
h1_a, h1_b = hamiltonian.get_one_body_integrals()
h2_aaaa, h2_aabb, h2_bbbb = hamiltonian.get_two_body_integrals()
core_energy = hamiltonian.get_core_energy()
print(f"One-body integrals shape: {h1_a.shape}")
print(f"Two-body integrals shape: {h2_aaaa.shape}")
print(f"Core energy: {core_energy:.10f} Hartree")
print(hamiltonian.get_summary())
Available implementations
QDK/Chemistry’s HamiltonianConstructor provides a unified interface for Hamiltonian construction methods.
You can discover available implementations programmatically:
auto names = HamiltonianConstructorFactory::available();
for (const auto& name : names) {
std::cout << name << std::endl;
}
from qdk_chemistry.algorithms import registry # noqa: E402
print(registry.available("hamiltonian_constructor"))
# ['qdk']
QDK (Native)
Factory name: "qdk" (default)
The native QDK/Chemistry implementation for Hamiltonian construction. Transforms molecular orbitals from AO to MO basis and computes one- and two-electron integrals.
Settings
Setting |
Type |
Description |
|---|---|---|
|
string |
Method for computing electron repulsion integrals (“direct” or “incore”) |
|
string |
Type of SCF reference (“rhf”, “rohf”, or “uhf”) |
Further reading
The above examples can be downloaded as complete Python or C++ scripts.
ActiveSpaceSelector: Provides active orbital indices
MCCalculator: Uses the Hamiltonian for correlation calculations
Settings: Configuration settings for algorithms
Factory Pattern: Understanding algorithm creation