Multi-Configuration Self-Consistent Field

The MultiConfigurationScf algorithm in QDK/Chemistry performs Multi-Configurational Self-Consistent Field (MCSCF) calculations to optimize both molecular orbital coefficients and configuration interaction coefficients simultaneously. Following QDK/Chemistry’s algorithm design principles, it takes initial Orbitals, a CI calculator, a HamiltonianConstructor and the number of electrons as input and produces an optimized Wavefunction as output. Its primary purpose is to optimize the orbitals and wavefunction for systems with strong electron correlation effects, which cannot be adequately described by single-reference methods.

Overview

MCSCF methods extend beyond both mean-field and configuration interaction approaches by simultaneously optimizing molecular orbitals and multi-configurational wavefunctions. Unlike Hartree-Fock, which optimizes orbitals for a single configuration, or CI calculations, which only optimize configuration coefficients with fixed orbitals, MCSCF performs a full variational optimization of both components.

As a prerequisite, an active space must be defined, typically using an ActiveSpaceSelector. The MCSCF procedure alternates between:

  • Configuration interaction: Solving the CI problem in the active space with fixed orbitals

  • Orbital optimization: Updating molecular orbital coefficients while keeping CI coefficients fixed

Due to the relaxation of the orbitals, MCSCF can capture both static and some dynamic correlation effects more effectively and hence results in lower energies than CI calculations.

Running an MCSCF calculation

Note

This algorithm is currently available only in the Python API.

This section demonstrates how to create, configure, and run an MCSCF calculation. The run method takes initial Orbitals, a HamiltonianConstructor, a MultiConfigurationCalculator, and the number of electrons as input and returns an optimized Wavefunction object along with its associated energy.

Input requirements

The MultiConfigurationScf requires the following inputs:

Orbitals

Initial Orbitals containing orbital coefficients and active space information.

HamiltonianConstructor

A HamiltonianConstructor instance that builds the Hamiltonian for the CI step.

MultiConfigurationCalculator

A MultiConfigurationCalculator for solving the CI problem in the active space.

Number of alpha electrons

The number of alpha (spin-up) electrons in the active space.

Number of beta electrons

The number of beta (spin-down) electrons in the active space.

Creating an MCSCF solver

The MultiConfigurationScf is created using the factory pattern.

from qdk_chemistry.algorithms import create

# Create a HamiltonianConstructor
ham_constructor = create("hamiltonian_constructor")

# Create a MC calculator
mc_calculator = create("multi_configuration_calculator", "macis_cas")

# Create the default MultiConfigurationScf instance
mcscf = create("multi_configuration_scf", "pyscf")

Configuring settings

The required algorithms can be configured through their settings, which can be modified using the settings() object. See Available implementations below for implementation-specific options.

# Configure the MC calculator using the settings interface
mc_calculator.settings().set("ci_residual_tolerance", 1.0e-6)
mc_calculator.settings().set("calculate_one_rdm", True)
mc_calculator.settings().set("calculate_two_rdm", True)

# Configure the Hamiltonian constructor
ham_constructor.settings().set("eri_method", "direct")

# Configure the MCSCF solver
mcscf.settings().set("max_cycle_macro", 50)

Running the calculation

from pathlib import Path
from qdk_chemistry.data import Structure
from qdk_chemistry.utils import compute_valence_space_parameters

# Load nitrogen molecule structure
structure = Structure.from_xyz_file(
    Path(__file__).parent / "../data/n2_stretched.structure.xyz"
)
charge = 0

# First, run SCF to get molecular orbitals
scf_solver = create("scf_solver")
E_scf, scf_wavefunction = scf_solver.run(
    structure, charge=charge, spin_multiplicity=1, basis_or_guess="cc-pvdz"
)

# Select active space based on valence orbitals
valence_selector = create("active_space_selector", "qdk_valence")
nele, norb = compute_valence_space_parameters(scf_wavefunction, charge)
valence_selector.settings().set("num_active_electrons", nele)
valence_selector.settings().set("num_active_orbitals", norb)
active_wavefunction = valence_selector.run(scf_wavefunction)

# Run MCSCF calculation
nalpha, nbeta = active_wavefunction.get_active_num_electrons()
E_mcscf, mcscf_wfn = mcscf.run(
    active_wavefunction.get_orbitals(), ham_constructor, mc_calculator, nalpha, nbeta
)

print(f"SCF Energy: {E_scf:.10f} Hartree")
print(f"MCSCF Energy: {E_mcscf:.10f} Hartree")
print(f"Correlation energy: {E_mcscf - E_scf:.10f} Hartree")

Available settings

Note

Because only one implementation of the algorithm is currently available through the PySCF plugin, only its implementation-specific settings (such as max_cycle_macro) are listed in the table below.

See Settings for a more general treatment of settings in QDK/Chemistry.

Note

Additional settings for the CI calculation step are configured through the MultiConfigurationCalculator object and settings for the Hamiltonian constructor are configured through the Hamiltonian constructor object. See MultiConfigurationCalculator settings and HamiltonianConstructor settings for more details.

Available implementations

QDK/Chemistry’s MultiConfigurationScf provides a unified interface for MCSCF calculations. You can discover available implementations programmatically:

from qdk_chemistry.algorithms import registry

print(registry.available("multi_configuration_scf"))
# ['pyscf']

PySCF

Factory name: "pyscf" (default)

The current MultiConfigurationScf implementation in QDK/Chemistry uses PySCF’s CASSCF framework.

Key features of the PySCF implementation:

  • Restricted orbitals: Currently requires restricted orbitals with identical alpha/beta active and inactive spaces

  • Flexible CI solver: Any QDK MC calculator can be used as the CI solver (e.g., full CI, selected CI)

  • Standard CASSCF: Implements the standard CASSCF algorithm with micro and macro iteration cycles

  • Optimized output: Returns a Wavefunction object containing both optimized orbital coefficients and CI coefficients

Note

The current implementation in QDK/Chemistry uses PySCF’s CASSCF framework as the underlying engine for the MCSCF procedure. This implementation does not yet utilize the provided Hamiltonian constructor, and uses the integrals directly from PySCF.

Settings

Setting

Type

Default

Description

max_cycle_macro

int

50

Maximum number of MCSCF macro iterations (orbital optimization cycles)

Further reading

  • The above examples can be downloaded as a complete Python script.

  • ActiveSpaceSelector: Helps identify important orbitals for the active space

  • Settings: Configuration settings for algorithms

  • Factory Pattern: Understanding algorithm creation