Skip to content

Wavefunction methods

.oqp control reference

Use canonical routes and controls in input files. Raw names identify implementation storage. A control without an accepted canonical spelling is not available in .oqp files.

OpenQP provides native determinant-space FCI, CASCI, CASSCF, state-averaged CASSCF, and second-order multireference perturbation methods. These workflows require an RHF reference: leave input.functional empty and use scf.type=rhf with multiplicity=1.

All of them run runtype=energy. State-specific method=casscf and dedicated method=sa-casscf use analytic nuclear gradients, and so do single-state CASPT2/MRMP2, MCQDPT2, XMS-CASPT2/XMCQDPT2, and the single-state strongly contracted NEVPT2 variant (SC-NEVPT2). SA-CASSCF provides the gradient of either the weighted objective or an individual averaged root; the latter includes the coupled orbital and CI response through a Z-vector. The compatibility spelling method=casscf with state_average.enabled=true, multi-set MS-CASPT2, and partially contracted NEVPT2 use Cartesian central differences of converged total energies. The supported analytic and numerical derivatives also connect to the gradient-driven run types described below. See CASSCF Nuclear Gradient, CASPT2 Nuclear Gradient, and SC-NEVPT2 Nuclear Gradient. CASCI and FCI remain energy-only.

The method selects which sections are read:

input.method Required controls Optional controls
fci fci —
casci cas, ci state_average
casscf, sa-casscf cas, ci, casscf state_average
caspt2, ms-caspt2, xms-caspt2 cas, ci, pt2 casscf, state_average
nevpt2, sc-nevpt2 cas, ci, pt2 casscf, state_average
mrmp2, mcqdpt2, xmcqdpt2 cas, ci, pt2 casscf, state_average

Minimal inputs

FCI uses its self-contained section:

fci/sto-3g
geom="""
H  0.0  0.0  0.0
H  0.0  0.0  0.74
"""

CASCI and CASSCF separate the active-space, CI, and orbital-optimization controls:

casscf/sto-3g cas(active_electrons=2,active_orbitals=2) ci(nroot=2,target_spin=singlet)
geom="""
H  0.0  0.0  0.0
H  0.0  0.0  0.74
"""

For equal-weight two-state SA-CASSCF, add:

rhf/6-31g* state_average(enabled=true,nstate=2,target_roots="0,1")
geom="molecule.xyz"

For CASPT2 on the converged reference, add pt2 and set input.method=caspt2:

rhf/6-31g* pt2(target_roots=0)
geom="molecule.xyz"

Runnable examples are in examples/WF_methods.

fci

fci is used only by method=fci. It combines the active-space and solver controls that CAS methods keep in separate sections.

Keyword Default Meaning
nroot 1 Number of CI roots returned.
active_electrons, active_orbitals 0, 0 Optional restricted active space; zeros mean full CI.
frozen_core 0 Number of doubly occupied orbitals folded into the core.
solver auto auto, dense, or davidson.
max_det 5000 Determinant-count safety limit.
max_memory 2048 Combined working-memory ceiling in MiB.
eig_tol 1.0e-10 Eigenpair residual tolerance.
davidson_maxiter, davidson_subspace 100, 0 Davidson iteration and subspace limits; zero subspace selects the automatic size.
target_spin any any, a multiplicity name such as singlet, or an integer multiplicity.
irrep any Return the lowest root of this spatial irrep instead of the lowest root overall. See Selecting a root by spatial symmetry.
irrep_min_purity 0.5 Fraction of a root's weight that must sit in its dominant irrep before the root is accepted as belonging to it.
print_ci_vectors, save_ci_vectors, save_rdm false Optional CI diagnostics and artifacts.

The only integral backend is integral_backend=native. Use integral_cutoff to screen small determinant-Hamiltonian contributions.

cas

cas defines the orbital partition shared by CASCI, CASSCF, and PT2.

Keyword Default Meaning
active_electrons 0 Total active electrons; required by the compact helpers.
active_orbitals 0 Number of active spatial orbitals.
frozen_core 0 Number of frozen doubly occupied orbitals.
active_orbital_indices, core_orbital_indices empty Explicit 1-based orbital selections.
orbital_source rhf rhf, json, or another supported orbital source.
orbital_file empty File used by a non-RHF orbital source.
sort_orbitals energy Ordering used before the active partition is formed.
localize none Optional orbital localization.
max_det, max_memory 5000, 2048 Determinant and combined memory safety limits.

Explicit scattered orbital selections are supported by CASCI. CASSCF and PT2 currently require a contiguous core/active partition.

ci

ci controls the active-space eigensolver for CAS methods.

Keyword Default Meaning
nroot 1 Number of reference roots to solve.
solver auto auto, dense, or davidson.
eig_tol 1.0e-10 Eigenpair residual tolerance.
davidson_maxiter, davidson_subspace 100, 0 Davidson limits.
target_spin any Requested spin multiplicity.
irrep any Return the lowest root of this spatial irrep instead of the lowest root overall. See Selecting a root by spatial symmetry.
irrep_min_purity 0.5 Fraction of a root's weight that must sit in its dominant irrep before the root is accepted as belonging to it.
root_tracking energy Root ordering/tracking policy.
print_ci_vectors, save_ci_vectors, save_rdm false Optional diagnostics and artifacts.

nroot must cover every CASSCF root, state-average target, and PT2 target.

Selecting a root by spatial symmetry

irrep asks a correlated method for a state by its spatial symmetry rather than by its position in the energy ordering. It is the only way to do so: the solvers otherwise return the lowest roots, and an excited state of a given symmetry can sit anywhere in that list.

rhf/6-31g* ci(irrep=b1)
geom="molecule.xyz"

symmetry.enabled=true is required, because the request is resolved against the per-MO irrep labels that symmetry detection produces. The name must be an irrep of the detected abelian subgroup; the run reports which subgroup was detected and lists the available names when one does not match.

Determinants are classified by the direct product of the irreps of their occupied active orbitals, which gives each root a weight per irrep. A root is then accepted on two conditions, in this order: the irrep holding the most of that weight -- the root's dominant irrep -- must be the one requested, and it must hold at least irrep_min_purity of the total. Lowering the threshold therefore never admits a root whose dominant irrep is some other one; it only relaxes how dominant the requested irrep has to be. Determinants that could not be classified stay in the total, so they lower the purity rather than quietly vanishing from it.

The default of 0.5 is the weakest threshold that still identifies a dominant irrep; raise it to demand a cleaner symmetry eigenstate. Values outside 0 < value <= 1 are rejected rather than clamped -- below zero the filter would accept anything, above one it would accept nothing, and NaN would disable the test silently.

The request is refused, rather than partly applied, in three cases:

  • CASSCF and SA-CASSCF. The orbital optimizer does not follow a symmetry-selected root across macroiterations, so the request would be honoured by the final CI and ignored by everything that produced the orbitals. Use method=casci.
  • An unclassified active orbital. Symmetry detection leaves an orbital it cannot assign -- a near-degenerate pair rotated by the SCF, for instance -- unlabelled. Such an orbital would be coded as totally symmetric, so every determinant containing it would be mislabelled rather than declined.
  • A solve the native engine declines. The Python fallback driver has no irrep classification, and the two paths disagreeing about which root a run returns is worse than not offering the feature on the fallback.

Runnable examples: H2O_CASCI_IRREP_B1 for ci.irrep, and H2_FCI_IRREP_B1U for fci.irrep combined with target_spin. Both predict their reference from the full spectrum of the same deck, so a filter that silently did nothing would be caught.

casscf

Keyword Default Meaning
max_macro_iterations 20 Orbital-optimization iteration limit.
root 0 Zero-based state-specific objective root.
converger trah trah, ah, twophase, diis, or auto.
hessian fd Finite-difference (fd) or analytic orbital Hessian.
gradient_norm_tol 1.0e-6 Orbital-gradient convergence threshold.
energy_decrease_tol 1.0e-10 Energy-change threshold.
step_norm_tol 1.0e-8 Orbital-step threshold.
max_rotation_norm 0.2 Maximum orbital-rotation norm.
canonicalize true Canonicalize the converged orbitals.
gradient_state averaged For dedicated method=sa-casscf, differentiate the weighted objective (averaged) or the named zero-based CI root.
zvector_tol 1.0e-8 Relative cutoff for the individual-state Z-vector null space, leakage, and residual tests.
zvector_degeneracy_tol 1.0e-8 Root-gap threshold in Hartree below which an individual-state derivative is refused.
grad_step 1.0e-3 Central-difference half-step in Bohr for a nuclear gradient.
grad_guess cold cold restores the same central-point SCF data before every displacement; warm follows the preceding solution serially.
grad_gap_warn 1.0e-5 Energy-gap threshold in Hartree used in the displaced-root ordering warning.
grad_ranks_per_group 0 MPI ranks assigned to one displaced energy; zero selects the automatic distribution.

The ah_*, diis_*, and diagnostic keywords provide detailed control of the selected converger. max_macro_iterations=0 runs the fixed-orbital CASCI scaffold and performs no orbital optimization.

gradient_norm_tol and hessian refer to orbital optimization. In particular, hessian=analytic selects an analytic orbital Hessian; it does not select the nuclear derivative. State-specific CASSCF has a separate analytic nuclear-gradient kernel.

root also selects which state runtype=grad differentiates. Tighten gradient_norm_tol to 1.0e-7 for gradient runs: the analytic gradient is valid at a stationary point, and its error is first order in the converged orbital-gradient norm. See CASSCF Nuclear Gradient.

The analytic state-specific result has one reported row: use [properties] grad=0 for a direct gradient and optimize.istate=0 for optimize, ts, mep, or irc. The physical CI state is selected only by casscf.root.

For dedicated method=sa-casscf, gradient_state=averaged selects the stationary weighted objective, while an integer selects the corresponding physical CI root and activates its coupled orbital and CI Z-vector response. For a direct individual-root gradient, properties.grad must equal that physical root. Gradient-driven optimization also requires optimize.istate to match the root and target_roots to be the contiguous sequence beginning at zero. The weighted objective is currently available only for runtype=grad, because it is not one of the reported state energies used by the optimizers.

The grad_* controls in the table apply only to the numerical compatibility path, method=casscf with state averaging enabled. They do not replace or tune either analytic derivative.

state_average

Keyword Default Meaning
enabled false Enable a state-averaged CAS objective.
nstate 0 Number of averaged states.
target_roots empty Zero-based CI roots included in the average.
equal_weights true Assign equal normalized weights.
weights 1.0 Explicit weights when equal_weights=false.
root_tracking overlap Accepted for compatibility; see below — roots are in fact followed by energy order.

The number of weights must equal the number of target roots. Weights are normalized internally and must contain a positive total.

Dedicated method=sa-casscf uses analytic nuclear gradients. The weighted objective is stationary with respect to the optimized orbital and CI parameters, so its derivative uses weight-averaged density matrices without a response term. An individual root is not stationary with respect to the common state-averaged orbitals; its analytic derivative therefore includes the coupled orbital and CI response through a Z-vector.

The current molecular input requires equal weights over a contiguous root block. Despite the root_tracking=overlap spelling, no overlap matching is performed between orbital macroiterations: each CI solve is consumed in energy order. Equal weights over a contiguous block are invariant when nearby roots interchange, which is why unequal weights or a noncontiguous target_roots subset — where an interchange would move weight onto different physical states — are refused at validation.

method=casscf with enabled=true remains an explicit compatibility route that uses central differences. It includes orbital relaxation at displaced geometries and retains the grad_* controls above.

pt2

Keyword Default Meaning
reference casscf casscf or fixed-orbital casci reference.
variant auto Single-state, multistate, or extended-multistate variant inferred from the method by default.
h0 fock fock for CASPT2/QDPT or dyall for NEVPT2.
contraction uncontracted uncontracted or strong (SC-NEVPT2).
target_roots empty Zero-based PT2 target root slots; target_roots=0 explicitly corrects only the first CI root. Single-state methods accept one target root.
nroot 0 Number of retained reference roots; zero inherits ci.nroot. This count does not itself select the single-state PT2 target.
ipea_shift, level_shift, imaginary_shift, edshft 0.0 Denominator regularization controls.
frozen auto PT2 frozen core: freeze the standard deep-core orbitals automatically, use 0 to correlate all inactive orbitals, or give an explicit count.
engine auto auto, dense, direct (NumPy), or fortran. auto selects the direct engine for the QDPT family and the dense engine for CASPT2/NEVPT2; an explicit direct or fortran request for a single-state CASPT2 energy is described below.
nproc 0 Worker count; zero selects the automatic value.
max_terms 30000000 Direct-engine limit on generated single/double excitation terms, before duplicate external determinants are merged.
max_memory 2048 PT2 memory ceiling in MiB, combined with the tighter cas ceiling.
semi_canonical true Semicanonicalize the reference orbitals.
gradient auto Nuclear-gradient route: auto (analytic where it applies — including the SC-NEVPT2 analytic scope — and central differences otherwise, both for an unsupported variant and for a geometry where a precondition of the derivation fails), analytic (refuse rather than fall back), or numerical. See CASPT2 Nuclear Gradient and SC-NEVPT2 Nuclear Gradient.
grad_step 1.0e-3 Central-difference half-step in Bohr for a nuclear gradient.
grad_guess cold Displaced-geometry SCF starting-data policy (cold or warm).
grad_gap_warn 1.0e-5 Energy-gap threshold in Hartree used in the root-ordering warning.
grad_ranks_per_group 0 MPI ranks assigned to one displaced energy; zero selects the automatic distribution.

For a molecular input, use input.method=nevpt2 with pt2.h0=dyall and contraction=uncontracted, or method=sc-nevpt2 with h0=dyall and contraction=strong. Specify these PT2 controls explicitly: the method name alone does not override the current input defaults. The Python job.nevpt2(...) convenience helper writes the matching method and PT2 controls; contraction="strong" selects sc-nevpt2. The older method=caspt2 with pt2.h0=dyall remains supported; add contraction=strong to that spelling for strongly contracted NEVPT2. The QDPT family (mrmp2, mcqdpt2, and xmcqdpt2) uses the diagonal-Fock direct engine and accepts edshft; edshft is mutually exclusive with real or imaginary level shifts.

Direct single-state CASPT2 energies

For an uncontracted single-state CASPT2 energy, engine=direct uses NumPy single/double-excitation summation, while engine=fortran requests the compiled streaming calculation. Both evaluate the same diagonal-Fock zeroth-order Hamiltonian as the dense single-state calculation without forming the full determinant Hamiltonian. engine=auto keeps the dense CASPT2 calculation; selecting a direct engine is an explicit choice.

caspt2/sto-3g cas(active_electrons=2,active_orbitals=2) pt2(engine=direct)
geom="h4.xyz"

The repository example examples/WF_methods/H4_CASPT2_direct.oqp runs the same request on a CASCI reference.

The default reference=casscf and reference=casci are both supported. The spelling contraction=none is equivalent to uncontracted. The request must select one PT2 target root: with the default ci.nroot=1 this is the only root, and pt2(target_roots=0) selects the first CI root even if ci.nroot=2 retains two reference roots. Root slots are zero-based; use target_roots=1 instead to correct the second retained CI root. variant=auto also selects the single-state CASPT2 variant for method=caspt2.

The direct CASPT2 energy requires h0=fock, ipea_shift=0.0, and at most 63 spatial orbitals after PT2 frozen-core reduction. Multistate and extended multistate CASPT2, contracted calculations, Dyall H0, nonzero IPEA shifts, and nuclear-gradient or geometry calculations are outside this direct scope and are rejected when an explicit direct engine is requested. Use engine=auto or dense for the existing CASPT2 gradient routes. QDPT engine selection and its gradient support are unchanged.

max_terms bounds the excitation terms generated from all reference determinants before merging duplicates. The tighter of pt2.max_memory and cas.max_memory bounds the estimated integral and streaming-array storage, including worker copies and merge buffers. The direct calculation still stores integrals and external-space arrays: omitting the full determinant Hamiltonian does not mean zero memory use or a fixed percentage reduction in process memory. These limits are allocation estimates, not a process RSS limit. An explicit direct request that exceeds a limit fails; it does not silently switch to dense. engine=fortran also fails if the installed library has no streaming entry point.

The reported external-determinant count and minimum denominator describe only the merged external determinants generated by single and double excitations from the reference determinants. Dense calculations report the complete external determinant space, including determinants that have no Hamiltonian coupling to the reference. Their counts and minimum denominators can therefore differ even when the PT2 energies agree. Compare energies and the corresponding coupled-space quantities when comparing engines.

Nuclear gradients and geometry calculations

Methods Derivative Supported run types
State-specific method=casscf Analytic derivative of casscf.root grad, optimize, ts, mep, irc
Dedicated method=sa-casscf, individual gradient_state Analytic coupled orbital and CI Z-vector derivative grad, optimize, ts, mep, irc
Dedicated method=sa-casscf, gradient_state=averaged Analytic derivative of the weighted objective grad
method=casscf with state averaging enabled Central difference grad, optimize, ts, mep, irc
CASPT2, MRMP2, MCQDPT2, XMS-CASPT2, XMCQDPT2 Analytic (pt2.gradient, auto falls back to central differences) grad, optimize, ts, mep, irc
SC-NEVPT2 (strong contraction, Dyall h0) Analytic when in scope (pt2.gradient) grad, optimize, ts, mep, irc
Multi-set MS-CASPT2, partially contracted NEVPT2 Central difference grad, optimize, ts, mep, irc

FCI and CASCI remain energy-only. meci, mecp, and neb are not connected to these wavefunction-gradient calculations.

For state-specific CASSCF, the physical CI state is selected by casscf.root, while properties.grad and optimize.istate remain zero because the result has one reported row. For analytic SA-CASSCF, gradient_state is either averaged or a physical root in state_average.target_roots. A direct individual-root gradient and its optimizer selector must name that same root. The compatibility numerical route instead indexes the state list published by state_average.target_roots.

The SC-NEVPT2 analytic route requires pt2.h0=dyall, contraction=strong, reference=casscf, and a single state-specific root on a closed-shell RHF reference. With gradient=auto, an out-of-scope input or a geometry-specific applicability failure is reported and routed to central differences. With gradient=analytic, the same condition is an error rather than a silent method change. See SC-NEVPT2 Nuclear Gradient for the full contract and diagnostics.

The central-difference calculations currently retain energy ordering without matching CI vectors between geometries. OpenQP warns when two reported roots become closer than the displacement-induced energy change, but it cannot detect a crossing with an uncomputed root.

Python helpers

The fluent API writes the same sections and validates the required active space:

from oqp.openqp import OpenQP

job = OpenQP("h4_xms")
job.molecule(geometry="h4.xyz", charge=0)
job.caspt2(
    active_electrons=2,
    active_orbitals=2,
    variant="xms-caspt2",
    nroot=2,
    basis="sto-3g",
)
mol = job.run()
print(mol.get_results()["energies"])

Available helpers include fci, casci, casscf, sa_casscf, caspt2, nevpt2, and qdpt2. A helper call resets method-owned state from an earlier call on the same builder unless that state is explicitly supplied again.

For a gradient-driven state-specific CASSCF calculation, job.casscf(root=1, runtype="optimize") selects physical root 1 and reports it in result row zero. For analytic SA-CASSCF, job.sa_casscf(nstate=2, gradient_state=1, runtype="grad") differentiates physical CI root 1 and sets properties.grad=1; omit gradient_state to differentiate the weighted objective. The older state=1 argument remains a positional alias for the second entry of target_roots. The CASSCF helpers also accept grad_step, grad_guess, grad_gap_warn, and grad_ranks_per_group for the numerical compatibility route.

Scientific references

Multiconfigurational methods.