IOP: fine-grained options#
The public signatures (chk.new, scf, ints, …) stay focused on the common controls. The rare, low-level
numerical knobs are collected into a single iop={...} dictionary — a cross-cutting channel inspired
by Gaussian’s IOp, but with readable namespaced names and typed values instead of numeric IDs.
Setting IOP keys#
Pass iop= on qc.chk.new(...), or overlay per calculation with mychk.with_iop({...}) (which returns a new
checkpoint):
import qc
m = qc.chk.new(
atom="O 0 0 0; H 0 0.76 0.59; H 0 -0.76 0.59",
ao="def2-svp",
iop={"ri.metric_cutoff": 1e-10, "integral.screen.schwarz_tol": 1e-12},
)
m2 = m.with_iop({"scf.conv_tol_grad": 1e-7}) # overlay, returns a new checkpoint
m2.scf(ref="r").run()
Keys are dotted <area>.<subsystem>.<knob> names validated against a central registry. Unknown keys
are an error (with a suggestion), not silently ignored:
m.with_iop({"not.a.real.key": 1})
# ValueError: unknown iop key "not.a.real.key"
Discovering keys: qc.iop#
The registry is introspectable — you never have to guess a key or its default:
qc.iop.list() # all 47 keys (a set of dotted names)
qc.iop.defaults() # {key: default_value} for every key
qc.iop.describe("scf.conv_tol_grad")
# {'type': 'float', 'default': 1e-06, 'min': 0.0, 'max': 1.0,
# 'consumer': 'scf', 'scientific': False,
# 'doc': 'Commutator-RMS convergence threshold (the SCF gradient tolerance).'}
describe(key) returns the value type, default, allowed range, which subsystem consumes it, and a
one-line doc.
The key registry by area#
There are 47 keys in 9 areas. The most commonly reached-for ones:
scf.* — SCF solver#
key |
meaning |
|---|---|
|
commutator-RMS gradient convergence threshold (default |
|
DIIS flavor, subspace size, first cycle |
|
incremental Fock build on/off, reset period |
|
when the 2nd-order ladder / SOSCF engages |
|
QC-family ladder controls |
|
TRAH / YQC tuning |
|
symmetry / orthogonalization |
|
adaptive integral screening in the SCF |
integral.* — integral assembly & screening#
key |
meaning |
|---|---|
|
Cauchy–Schwarz quartet screening tolerance (default |
|
density / nuclear / QQR screening |
|
integral precision target |
|
out-of-core ( |
|
disk-backend drop tolerances |
|
incore-4c tuning |
ri.* — RI / density fitting#
key |
meaning |
|---|---|
|
RI metric eigenvalue cutoff (default |
|
|
|
|
|
sparse store- |
lct.* — correlation (RI-MP2)#
key |
meaning |
|---|---|
|
freeze core orbitals in the correlation sum |
|
ROHF-MP2 convention ( |
|
single-precision RI-MP2 |
|
Laplace quadrature points (SOS-MP2) |
Other areas#
key |
meaning |
|---|---|
|
the GWH guess scaling factor |
|
PCM cavity discretization |
|
oversubscription policy ( |
|
emit timing spans |
For the exact default, type, and range of any key, call qc.iop.describe(key). The registry is the single
source of truth (crates/qc-workflow/src/iop.rs); this list mirrors it.
Which controls are IOP vs public kwargs#
Some knobs migrated from public keyword arguments to IOP keys to keep the main signatures focused — e.g.
scf.conv_tol_grad, scf.symmetrize_fock, scf.salc_cutoff, scf.orbital_ordering,
integral.screen.nuclear_tol, integral.precision are IOP keys, read from the checkpoint iop by
scf(...) / ints(...). The everyday controls (ref, xc, grid, conv_tol, algorithm, pcm, …) stay
as direct keyword arguments (the SCF chapter).