CASCI and CASSCF
PyQED provides native active-space methods for multireference quantum chemistry. CASCI optimizes CI coefficients in a fixed active orbital space. CASSCF additionally optimizes the orbitals.
Basic CASSCF
from pyqed.qchem import CASSCF, Molecule
mol = Molecule(atom="Li 0 0 0; H 0 0 1.6", unit="angstrom", basis="sto-3g")
mol.build(driver="builtin", eri="factors")
mf = mol.RHF().run()
mc = CASSCF(mf, ncas=2, nelecas=2).run()
print(mc.e_tot)
ncas is the number of active spatial orbitals. nelecas is the number
of active electrons, either as an integer for closed-shell active spaces or as
(nalpha, nbeta) for explicit spin sectors.
Active Space Selection
By default, PyQED places the active block after the inactive core orbitals. You can provide explicit zero-based MO indices:
mc = CASSCF(mf, ncas=4, nelecas=4).run(
active_orbitals=[2, 3, 4, 5],
)
Use active orbital selection when:
the chemically important orbitals are not contiguous,
the active space changes character along a scan,
you need to match a PySCF or external active-space reference,
you want to preserve a manually localized or reordered active block.
The helper checks that the number of active orbital indices equals ncas and
that there are no duplicates.
First-Order CASSCF
CASSCF is the lightweight native orbital optimizer. It:
solves the active-space CI problem with the native CASCI solver,
builds spin-traced active-space RDMs,
forms a generalized Fock matrix,
computes the nonredundant orbital gradient,
updates orbitals with diagonal preconditioning and line search.
This path is useful for small and medium active spaces, quick scans, and testing dense/factorized integral code.
Second-Order CASSCF
SecondOrderCASSCF adds a stronger orbital-optimization path with
microiterations:
from pyqed.qchem import SecondOrderCASSCF
mc = SecondOrderCASSCF(
mf,
ncas=4,
nelecas=4,
coupling="full",
max_micro_cycle=8,
).run()
The second-order implementation supports several coupling modes:
coupling="full"uses the production full coupling path by default.coupling="qn"uses a quasi-Newton-like orbital path.coupling="simultaneous"performs joint CI-orbital microiterations.coupling="simultaneous_reduced"or"simultaneous_partial"uses a reduced simultaneous coupling.
For routine work, start with coupling="full". Use simultaneous coupling for
experiments where CI and orbital variables must relax together in the
microiteration.
State Averaging
State-averaged CASSCF optimizes orbitals for a weighted average of multiple CASCI roots:
weights = [0.5, 0.5]
mc = CASSCF(mf, ncas=4, nelecas=4)
mc.state_average(weights).run(nstates=2)
State averaging is useful near avoided crossings or when multiple electronic states must share a consistent orbital basis.
Factorized Integrals
CASSCF can use factorized AO ERIs from the RHF reference:
mol.build(driver="builtin", eri="factors")
mf = mol.RHF().run()
mc = SecondOrderCASSCF(mf, ncas=4, nelecas=4).run()
In factorized mode, the CASSCF code avoids constructing dense transformed MO ERI tensors when the active-space contraction can be performed directly with pair factors:
This is the recommended path for larger basis sets and larger active spaces.
Convergence Controls
Important options:
max_cyclecontrols macroiterations.max_micro_cyclecontrols second-order microiterations.conv_tolcontrols energy convergence.conv_tol_gradcontrols strict orbital-gradient convergence.conv_tol_grad_relaxedallows convergence when the energy is stable and the gradient is small enough for practical scans.conv_tol_stepcontrols orbital-step convergence.
For production calculations, prefer a slightly larger max_cycle and monitor
both energy and gradient norms. If the active space changes character along a
scan, use explicit active_orbitals or orbital-overlap analysis.
QN vs Simultaneous Microiterations
The quasi-Newton-style path treats the CI response and orbital response in a more decoupled way. It is usually faster and often robust enough.
The simultaneous path updates CI and orbital variables together inside the microiteration. It is closer to a fully coupled second-order formulation, but it is more expensive and more sensitive to trust-region/acceptance settings.
Use this practical rule:
use
fullorqnfor normal calculations,use
simultaneouswhen testing paper-faithful coupled CI-orbital behavior,fall back to
fullif simultaneous microiterations become too slow or reject too many steps.
Examples
Relevant examples:
examples/qchem/casscf.pyexamples/qchem/sa_casscf_factor.pyexamples/qchem/casscf_factor_vs_dense.pyexamples/qchem/mcscf/secondorder_casscf.pyexamples/qchem/benchmark_second_order_casscf.pyexamples/qchem/lif_casscf_scan.py