Input reference (TOML)

Every key the ferric CLI accepts, section by section.

Unknown keys are a hard error. The config structs in crates/ferric-cli/src/config.rs are #[serde(deny_unknown_fields)], so a misspelled key or section aborts the run before anything is computed. That includes [external_potential], its point charges, and each [[scf.ladder]] rung.

String values go through strict parsers, where an unknown value is an error at load time rather than a default. Most accept any capitalisation; the exceptions are noted per key.

This page is hand-maintained against crates/ferric-cli/src/config.rs at commit 4b64e6ce. Where a default is applied at the point of use rather than in config.rs, it was read from crates/ferric-cli/src/lib.rs at the same commit. If the code and this page disagree, the code wins. For which method.kind values exist and what each supports, see Capabilities and validation.

Units follow the code: [molecule] geometries are Å (XYZ), point charges and cutoffs named *_bohr are Bohr, keys named *_angstrom or documented as Å are Å, and energies are Hartree.

A minimal file:

[molecule]
xyz = "testdata/molecules/water.xyz"
[basis]
name = "cc-pvdz"
[method]
kind = "rimp2"
[mp2]
auxbasis = "cc-pvdz-ri"

[molecule] (required)

KeyTypeDefaultAllowed valuesNotes
xyzstringrequiredpathStandard XYZ in Å, relative to the working directory. Not read when [qmmm] is present (the PQR supplies the geometry).
chargeinteger0With [qmmm], applies to the QM region.
multiplicityinteger1≥ 1Read by uhf, rohf and ksdft (UKS) for every task, and for task = "energy" only by rimp2/oo-rimp2 (UHF + unrestricted RI-MP2 / OO-RI-MP2) and the open-shell path of pdep-rpa/gw/mp2-v: UHF, or UKS when [rpa] xc is set (pdep-rpa, gw), or ROHF/ROKS for gw with [gw] reference = "rohf"; mp2-v stays UHF. Every other kind refuses > 1. See open shells.

[basis] (required)

KeyTypeDefaultAllowed valuesNotes
namestring—a bundled name (case-insensitive)e.g. sto-3g, 6-31g*, 6-311++g**, cc-pvtz, aug-cc-pvqz, cc-pvdz-pp, def2-tzvpp, def2-qzvppd, pcseg-1; the full list of 64 sets and their aliases is in Bundled basis sets.
pathstring—path to a Gaussian-94 fileUsed only if name is absent. One of name/path is required.

Auxiliary basis names used elsewhere (auxbasis, df_*_aux) come from the same table: cc-pvdz-ri, cc-pvtz-rifit, aug-cc-pv{d,t,q}z-rifit, def2-svp-rifit, def2-tzvp-rifit, def2-tzvpp-rifit, def2-qzvp-rifit, def2-qzvpp-rifit, def2-universal-jkfit, cc-pvtz-jkfit, cc-pvqz-jkfit, cc-pvdz-f12-optri. cc-pvdz-rifit is an alias of cc-pvdz-ri; both names load the same set.

[method] (required)

KeyTypeDefaultAllowed valuesNotes
kindstringrequiredrhf uhf rohf ksdft rimp2 mp3 oo-rimp2 att-rimp2 mp2-v scs-mp2 scs-mp2-2terfc laplace-mp2 laplace-sos-mp2 pdep-rpa rs-mp2-rpa gw bse-tda tdhf-static-polarizability ccsd ccd ccsd(t) linlccd drpa wb97x-l-v b2plyp dsd-pbep86 tda tddftAny other value is an error. Smoke- and Spike-grade kinds print a [warning] grade line on stderr; Proven kinds and the ungraded laplace-sos-mp2 print none. rimp2, drpa and linlccd name the method and are computed exactly unless [local] sets a local approximation (see Capabilities and validation).
taskstring"energy"energy optimize frequenciesoptimize: rhf ksdft uhf rohf rimp2 pdep-rpa only. frequencies: rhf ksdft uhf rohf only.

[scf]

Read by every kind, because every kind runs an SCF first.

KeyTypeDefaultAllowed valuesNotes
max_iterinteger200Iteration cap; equals the library (RhfConfig) and Python default.
energy_convfloat1e-3Sanity bound, not a target. Convergence requires ΔP_rms < density_conv, ΔP_max < 10·density_conv and ΔE < energy_conv. ΔE has a noise floor that grows with system size, so a tight value is met only by chance and costs iterations; ferric prints a warning: [scf] energy_conv ... line when a value you wrote is below 0.3 times the estimated floor (see sharp bits); functionals, the LinK / COSX exchange builders, PCM / COSMO and double-hybrid kinds get no warning.
density_convfloat1e-6The convergence signal.
diis_sizeinteger8
diisstring"pulay"pulay adiis ediis (case-insensitive)An unknown value is an error when the file is loaded.
diis_switch_threshfloat1e-1Error level at which ADIIS/EDIIS hand over to Pulay. Ignored for pulay. If the density stops moving while the error is still above this level, the run is not reported converged: it restarts once on plain Pulay DIIS from a clean history, with a stderr warning (with inf, the level is 1e-2). A switch at or below the commutator floor (about 1e-6) can trigger the restart on a run that had converged, costing a few iterations.
smearing_sigmafloatnoneHartreeFermi–Dirac smearing width. Absent means integer occupations.
guessstring"minao"minao sad hcore (case-insensitive)"sad" is an alias of "minao" (the MINAO projection guess); the free-atom-SCF SAD guess is not selectable from config. Any other value is an error.
guess_basisstringunsetbundled basis nameSecondary-basis (Q-Chem BASIS2) guess: the same SCF (method, functional, charge, multiplicity and [scf] settings) is converged in this basis first and projected into the target basis as the starting point. The one exception: the secondary SCF never runs the stability check or the stability descent (check_stability, stability_descent); those apply to the target solution only. An unknown basis is an error at load time, and so is a periodic [cell] system. symmetry = true refuses it. With it set, guess selects only the secondary SCF's starting point. A secondary SCF that does not converge (iteration cap, stall or divergence) does not stop the run: the target starts from its default guess, with a warning. It also runs inside the df_guess pre-stage, and again at every geometry of an optimization or finite-difference Hessian. The rimp2 and pdep-rpa optimizers (task = "optimize") build their own RHF reference without it, so that combination is an error at load time. The guess can change which SCF state is reached. See SCF.
guess_projectionstring"fock"fock overlap (case-insensitive)How guess_basis is projected: fock (Q-Chem FOPPROJECTION, project the density and diagonalise the target Fock) or overlap (OVPROJECTION, project and re-orthonormalise the occupied MOs). Any other value, or setting it without guess_basis, is an error.
soscfboolfalseEnables the second-order (Newton) step in the SCF tail.
auroraboolfalseOpt-in AURORA auxiliary-curvature accelerator. Closed-shell RHF only (kind = "rhf", multiplicity 1). Same fixed point as DIIS; a speed-up (fewer J/K builds), not a convergence rescue.
trah_triggerfloatunset> 0Opt-in trust-region augmented-Hessian solver, engaged once the DIIS error falls below this value (rhf and uhf). A convergence rescue: fewer iterations, more wall time.
integral_threshfloat1e-12Integral screening threshold.
eri_precisionfloat1e-200 to 1e-8libint primitive-screening precision for the SCF J/K integrals. Omitted: FERRIC_ERI_PRECISION if set, else 1e-20. 1e-14 costs up to 6e-9 Ha in E_J for atoms past Ne; 0 disables primitive screening (1.8–5.7× slower per J/K build).
jk_storagestring"auto"auto memory disk direct splitWhere the raw RI-J/K three-index tensor lives. auto keeps it in memory when n_aux × n_bf² × 8 bytes fit [memory] budget_gb and the shared memory pool, keeps the packed symmetric half (n_aux × n_bf(n_bf+1)/2 × 8 bytes plus 64 unpacked aux rows of scratch) when only that fits, and otherwise, on one rank with the Coulomb operator and orbital/aux angular momenta up to 4/6, builds J by Split-RI-J (as split, below; a notice says so). For a tensor still needed beyond that (DF-K's, or J's on several ranks or for another operator) it measures this machine (an untimed warm-up block, four timed integral blocks, and a cold write and read of up to 64 MiB in the spill directory) and picks the cheaper of disk and direct for a 30-pass SCF. When J and K share one auxiliary basis, the raw tensor that DF-K needs is built as before and, when it is not held in memory, freed after DF-K's copy is made, with J from Split-RI-J. A spill directory without room for the packed tensor plus headroom rules disk out. memory is an error when even the packed half does not fit. disk always spills to $TMPDIR. direct recomputes each block per pass and writes nothing. Omitted: FERRIC_JK_STORAGE if set; an invalid value in either place is an error. J from the packed, spilled and recomputed tensors is bit-identical (all three are consumed through the same packed block stream); the unpacked in-core J differs from them in the last bits (summation order, about 1e-12 Ha in the energy). This holds for J only: K and the other consumers of the tensor (the DF-K dressing follows the tensor's own block order, and the packed tier's aux block size differs from the spill file's) can differ between tiers at the level of summation order. The tier chosen by auto depends on the budget (default 0.8 × available RAM) and on the free bytes in the shared memory pool, so the same input can pick a different tier on a busier machine or with a different budget; set memory, disk, direct or split to pin it. split stores no RI-J tensor on one rank (with J and K on one auxiliary basis too: the raw tensor DF-K needs is freed once DF-K's copy is made); on several ranks it warns and stores the RI-J tensor as auto would, with that tensor's memory. Where it applies, J comes from Split-RI-J (the density, and the fitted coefficients, contracted with the three-centre integrals' Hermite intermediates as they are computed, so no (P|μν) block is formed), recomputed every build on one rank; it is RI-J to 1e-14 relative per term (terms with a large Boys argument are evaluated as point-multipole interactions, with a proven bound on that error), uses tens of MB instead of the tensor, and costs more time than a tensor held in memory: on danuglipron PBE/def2-SVP the whole SCF took 81 s against 46 s with the tensor in memory, and 584 s with direct and 600 s with disk (all four energies identical to 1e-10 Ha; peak memory 2.5, 6.4, 3.3 and 6.5 GB). With split any tensor K still needs is stored as under auto, and the raw tensor shared with DF-K is freed once DF-K's copy is made. Applies to the RI-J tensor, and to the RI-K tensor when both use the same auxiliary basis on one rank; the RI-K dressed tensor follows [memory] budget_gb.
screeningstring"schwarz"schwarz csb csamcsb is rigorous and never looser than schwarz. csam is not a bound. It is refused for erfc (short-range) operators. See SCF: screening.
k_builderstring"direct"direct link cosxExchange builder. cosx with RI-J active (named, or the Kohn-Sham default) is RIJCOSX: J from RI-J, K from COSX, and the RI-K default is not applied; cosx next to an explicitly named df_k_aux is an error. link is ignored with a warning when DF-J/DF-K is active. Both are ignored with a warning for functionals with no exact exchange and for range-separated functionals. See SCF: choosing how exchange is built.
cosx_gridinline table{ radial = 35, angular = 194, prune = "sgx" }angular ∈ 6/14/26/50/110/194/302/434/590; prune ∈ none sgx nwchemThe COSX SCF grid. A table without prune is flat; with prune = "sgx", angular is the peak order of the pruned rows (50/110/194/302/434/590). Only with k_builder = "cosx"; otherwise it is an error. The inner table is strict.
cosx_final_passbooltrueRe-evaluate exchange once on a larger grid at the converged density and report that energy (the SCF-grid energy is printed and logged too). Without cosx_final_grid the grid is { radial = 50, angular = 302, prune = "sgx" }. Gradient tasks run without it; ROHF/ROKS skips it with a note (an explicit true there is an error). Only with cosx.
cosx_final_gridinline tablenoneas cosx_gridThe final-pass grid; setting it turns the pass on (cosx_final_pass = false with it is an error). RHF/RKS and UHF/UKS only. Only with cosx.
cosx_overlap_fitbooltrueOnly with cosx; otherwise it is an error.
cosx_grid_scheduleboolfalseRun the first SCF iterations on a coarse pruned sgx (25,110) exchange grid and switch to cosx_grid once the largest density change falls below 1e-3. Convergence is accepted only on the production grid, DIIS restarts at the switch, and the final-grid pass is unchanged. RHF/RKS and UHF/UKS; ROHF/ROKS refuse it. Only with cosx; setting it otherwise is an error.
cosx_backendstring"md3c1e"md3c1e cosx-aOnly with cosx; otherwise it is an error. cosx-a is the slower cross-check kernel.
cosx_screen_threshfloat1e-7≥ 0Only with cosx and md3c1e. 0 disables the screen.
cosx_half_transformstring"sparse"sparse denseOnly with cosx.
cosx_fp64_multiplierfloat1e5 with [precision] mode = "mixed" and cosx-kern in mixed_kernels, else 0≥ 0Precision-router threshold: tau = cosx_fp64_multiplier × cosx_screen_thresh. A kept (shell pair, sub-batch) unit whose Hölder K bound is below tau is counted as f32-eligible; the exchange matrix is unchanged (every unit is still computed in f64), so the key only changes the route_* counters. Setting it requires k_builder = "cosx", [precision] mode = "mixed" and cosx-kern in mixed_kernels, and cosx-kern is not in the shipped kernel set, so in this build setting the key is always an error; a value above 0 also needs md3c1e and cosx_screen_thresh > 0. 1e5 is the multiplier recommended by Laqua, Kussmann and Ochsenfeld, J. Chem. Phys. 154, 214116 (2021).
df_j_auxstringnone; def2-universal-jkfit for ksdft, pdep-rpa, rs-mp2-rpa, gw, bse-tda, tdhf-static-polarizability, tda, tddftaux basis name, or ""RI-J. With neither key set, rhf/uhf/rohf use exact 4-index J/K. df_j_aux = "" selects exact J for the kinds that default to RI-J (the SCF J/K log line then reads RI-JK via with a blank name). Unlike Python's run_dft, the CLI does not accept "exact", "none" or "off": any non-empty value is looked up as a basis name, and an unknown one fails the SCF.
df_k_auxstringas df_j_auxaux basis name, or ""RI-K. Use a JK-fit set. "" selects exact K.
jkstringthe kind's own: four-centre, except rs-mp2-rpa (RI-JK)exact rijk rijcosxMP2-family kinds (rimp2, oo-rimp2, att-rimp2, mp2-v, scs-mp2, scs-mp2-2terfc, laplace-mp2, laplace-sos-mp2, rs-mp2-rpa) with task = "energy" only: how the reference SCF builds J/K. rijk = RI-J + RI-K on jk_aux; rijcosx = RI-J on jk_aux + COSX K (the cosx_* keys apply); exact = four-centre. Same rule as the Python scf_jk kwarg. Cannot be combined with df_j_aux/df_k_aux; a k_builder under rijk (including rs-mp2-rpa's RI-JK default), or other than cosx under rijcosx, is an error. oo-rimp2 accepts only exact (it rebuilds exact J/K at every orbital step; RI-JK in the OO Fock builds is not implemented), and refuses df_j_aux/df_k_aux for the same reason. A fitted mode refuses df_increments and an explicit df_guess = true, and skips the default DF-guess pre-stage. The run log's scf_jk / jk_aux / k_builder record the route the SCF takes.
jk_auxstringdef2-universal-jkfitbundled JK-fit basis nameThe fitting basis for jk = "rijk"/"rijcosx". It is not the [mp2] auxbasis (an MP2-fit set for K costs mHa); a name without "jkfit" draws a warning. Setting it without jk, or with jk = "exact", is an error.
level_shiftfloat0.0HartreeVirtual-block shift. Left at 0 with a meta-GGA functional, the library applies 0.5.
mom_after_iterinteger0Maximum-overlap occupation pinning after this many iterations. 0 = aufbau throughout.
verboseboolfalseOne line per SCF iteration. The CLI's --verbose/-v flag ORs into this.
df_guessboolonTwo-stage SCF: DF first, then exact. It applies only on the closed-shell, non-laddered path (rimp2 and the other correlated kinds). rhf/ksdft use the convergence ladder, which does not compose with it, and lib.rs prints a warning there whenever it is enabled, including by default. Mutually exclusive with an explicit df_increments = true.
df_guess_auxstringdef2-universal-jkfitaux basis nameIt is an error when df_guess is off.
df_incrementsboolfalseDF-corrected incremental Fock SCF. Same scope as df_guess, and warned and ignored on rhf/ksdft.
df_increments_auxstringdef2-universal-jkfitaux basis nameIt is an error when df_increments is off.
check_stabilityboolfalseDiagnostic only: warns if the solution is a saddle point and never fails the run. On an RHF/HF run it reports two verdicts: internal (the singlet channel: is this RHF solution an RHF minimum?) and external RHF→UHF (the triplet channel: does breaking spin symmetry lower the energy?). A stretched geometry is often internally stable and externally a saddle: water / 6-31G at r(OH) = 2.0 Å gives +1.97e-2 and −3.07e-1. For an external instability, run kind = "uhf"; re-converging RHF does not help. RKS gets the internal verdict only (no triplet XC kernel, printed as a skip); UHF/UKS get the internal verdict, which already spans the independent α/β rotations. ROHF/ROKS, range-separated and meta-GGA are skipped entirely with a printed reason.
stability_descentboolfalseState selection: at a saddle of the orbital Hessian (UHF, or the RHF singlet channel), follow the downhill eigenvector and re-converge, keeping the lowest state. Turns check_stability on as well. Same as Python run_uhf(stability_descent=True). Only kind = "rhf", "uhf" or "ksdft" with task = "energy"; any other kind or task is an error. A KS functional with no stability verdict (range-separated, meta-GGA) skips the descent with a printed reason. Costs one Davidson per converged solve plus one SCF per descent. See examples/o2-uhf-stability-descent.toml.
symmetryboolfalsePoint-group-blocked closed-shell RHF or RKS: detect the Abelian subgroup, symmetrize and reorient the geometry, and diagonalize the Fock matrix per irrep. Only kind = "rhf" (Hartree-Fock, or RKS with [dft] functional) or kind = "ksdft", task = "energy", multiplicity 1, no [dft] dispersion, no [cell]/[qmmm]; anything else is an error (the result lives in a rotated frame, so gradients, optimizers and post-HF would be wrong; UHF/ROHF/UKS/ROKS blocking is not wired to the CLI). Under RKS the KS grid is built in the symmetry frame, where it is exactly symmetric, so no Fock or density symmetrisation is applied; a partially filled degenerate shell (stretched H2, singlet O2) is refused unless irrep_nelec chooses the occupation, because the grid can split such a shell. The energy is that of the SYMMETRIZED geometry; the printout and the run log give the point group, the per-irrep electron counts and the symmetrization shift (at most 1e-4 Bohr). No vector quantity is produced. The blocked SCF is one plain solve: [[scf.ladder]], df_guess, df_increments, soscf, aurora, trah_trigger, check_stability/stability_descent, smearing_sigma, mom_after_iter and k_builder = "cosx" are refused, and the default convergence-ladder escalation is not applied. Python: run_rhf(symmetry=True), run_dft/run_ksdft(symmetry=True) (return SymmetricRhfResult).
irrep_nelectableunseteven countsElectrons per irrep, irrep_nelec = { A1 = 4, B2 = 2 }: pins the occupation instead of aufbau across irreps (unlisted irreps follow aufbau). Requires symmetry = true. Python: run_rhf(irrep_nelec={...}), run_dft(irrep_nelec={...}).
ladderarray of tablesbuilt-in laddersee below[[scf.ladder]] rungs. Read only by rhf and ksdft.

[[scf.ladder]] rungs

Each rung overrides the flat [scf] settings. The rungs are walked in order, and the ladder stops at the first converged rung. Unknown keys are an error, as elsewhere.

KeyTypeDefaultAllowed valuesNotes
guessstring"minao"minao sad hcoreAs [scf] guess: "sad" is an alias of "minao", and any other value (including sad-smallbasis) is an error.
level_shiftfloatinherits
max_iterintegerinherits
df_j_aux, df_k_auxstringinherits
stall_windowintegernone
divergence_tolfloatnone
restartboolfalsetrue discards the incoming density.

[dft]

KeyTypeDefaultAllowed valuesNotes
functionalstring"LDA" (for ksdft)an XC name (LDA, PBE, B3LYP, wB97X-V, SCAN, r2SCAN, …) or a libxc nameRead by ksdft. wb97x-l-v ignores it with a warning. RPA/GW use [rpa] xc and TDDFT uses [tddft] xc instead.
grid_prunestring"nwchem-radial"none off flat; nwchem nwchem-like nwchem_like; nwchem-radial nwchem_radial; defgrid1 defgrid2 defgrid3Prunes the main grid only; the default is nwchem-radial, and none is the flat grid (with grid_weight_cut = 0, the previous default exactly). Absent, it is the default scheme at whatever grid_radial / grid_angular set (flat at grid_angular = 50, which has no region table). nwchem: NWChem-style angular pruning by radial region, about 23% fewer points at 75×110 with energies within 1e-9 Ha of the flat grid. nwchem-radial: the same angular pruning plus fewer radial shells for light atoms (H and He 50/75 of grid_radial, Li–Ne 66/75, heavier atoms all of it), 42-47% fewer points on organic molecules; live PBE/def2-SVP SCFs moved by 2e-7 to 4e-6 Ha against the flat 75×110 grid, whose own error against a 99×590 grid is 4e-4 to 3e-3 Ha on C10-C32 alkanes. defgrid1/defgrid2/defgrid3: ORCA-style grids (ORCA 6.1 DEFGRID1-3: ORCA's radial count per element row, its five-region angular tables, H and He one angular level lower) that fix their own radial and angular sizes, so grid_radial and grid_angular are an error with them; defgrid2 is as fast as nwchem-radial and much coarser (PBE/def2-SVP: -1.2e-3 Ha on n-C20H42 and +4.2e-3 Ha on danuglipron against the flat 75×110 grid, the same range as ORCA's own DefGrid2 results). Optimize and frequency runs differentiate the pruned energy. Setting it on a meta-GGA tda/tddft run replaces that run's 150 × 434 default (see grid_radial).
grid_radialinteger75 (meta-GGA TDDFT: 150)> 0Radial points per atom on the main grid. Only on a run with a Kohn–Sham grid, and not with kind = "gw". Optimize and frequency runs differentiate this grid. Same as Python grid_radial=. On tda/tddft with a meta-GGA [tddft] xc (SCAN, r2SCAN, TPSS) and no main-grid key set, the default is 150 × 434 instead (see Meta-GGA response needs a finer grid); setting any of grid_radial, grid_angular, grid_prune, grid_weight_cut replaces it.
grid_angularinteger110 (meta-GGA TDDFT: 434)6 14 26 50 110 194 302 434 590Lebedev order on the main grid. Same scope as grid_radial. An unsupported order is an error. Same as Python grid_angular=. On tda/tddft with a meta-GGA [tddft] xc (SCAN, r2SCAN, TPSS) and no main-grid key set, the default is 150 × 434 instead (see Meta-GGA response needs a finer grid); setting any of grid_radial, grid_angular, grid_prune, grid_weight_cut replaces it.
grid_weight_cutfloat1e-14finite, >= 0 (0 = no cutoff); e.g. 1e-14ORCA's WeightCut: drops every main-grid point whose final weight (radial × angular × Becke partition) is below this in absolute value. 0 turns the cutoff off (the grid is then bit-identical to the uncut one). At 1e-14, PBE/def2-SVP energies moved by under 1e-9 Ha and the XC time fell 12-15% (n-C20H42, danuglipron). A negative, NaN or infinite value is an error. Only on a run with a Kohn–Sham grid, and not with kind = "gw". Optimize and frequency runs differentiate the cut energy (the gradient drops the same points); it is discontinuous where a weight crosses the cutoff under displacement, by about cutoff × integrand. The VV10/NLC grid is not cut. Same as Python grid_weight_cut=. Setting it on a meta-GGA tda/tddft run replaces that run's 150 × 434 default (see grid_radial).
dispersionstringabsentd3bj, d3(bj), d3bj(<functional>), mbd, mbd(<functional>) (case-insensitive)Only on a Kohn–Sham SCF (kind = "ksdft", or rhf/uhf/rohf with functional). task = "optimize" and task = "frequencies" run on RKS, UKS and ROKS references; frequencies uses finite differences of the KS + dispersion gradient (also under [frequencies] hessian = "auto"), so hessian = "analytic" and "analytic-moving-grid" are errors. There is no "off" value; omit the key instead. d3bj with a functional that has no D3(BJ) row in ferric's table (listed by ferric_d3::d3bj_tabulated_functionals(), the simple-dftd3 BJ table; M06-2X has only a zero-damping fit and is refused), or mbd with a functional that has no MBD@rsSCS β, is an error.
lambdafloat0.6Only for wb97x-l-v.
omegafloat0.1Bohr⁻¹Only for wb97x-l-v. Note the unit differs from [mp2] omega.

[mp2]

This section is shared by the whole MP2 family, ccsd, ccd, ccsd(t), linlccd, drpa, the double hybrids and tda/tddft, all of which read auxbasis and frozen_core from here. drpa, linlccd and a local rimp2 read nothing else from it (plus linlccd_variant for linlccd); any other [mp2] key on them is an error.

KeyTypeDefaultAllowed valuesNotes
auxbasisstring"cc-pvdz-ri"; "cc-pvdz-rifit" for tda/tddftaux basis nameThe two defaults name the same bundled set (cc-pvdz-rifit is an alias of cc-pvdz-ri).
frozen_coreint, string or bool0integer ≥ 0, "auto", "none", true (= auto), false (= 0)"auto" gives the standard small core for this molecule after the ECP is applied, and the run prints the resolved count.
omegafloat0.420Å⁻¹att-rimp2 (erfc), rs-mp2-rpa. Ignored with a warning when attenuator = "terf". An error on att-rimp2 with att_operator = "terfc".
kappafloatnoneκ > 0, Hartree⁻¹κ-regularized MP2 for the exact rimp2; an error with [local]. Absent = plain MP2.
c_osfloat1.2 (scs-mp2), 1.27 (scs-mp2-2terfc), 1.3 (laplace-sos-mp2)
c_ssfloat1/3 (scs-mp2), 4.05 (scs-mp2-2terfc)laplace-sos-mp2 warns and ignores it.
n_quadinteger73 5 7laplace-mp2, laplace-sos-mp2. Any other value is an error.
sos_formulationstring"mo"mo ao ao-sparselaplace-sos-mp2. mo and ao are exact and agree to round-off. ao-sparse is approximate and requires domain_cutoff_bohr.
domain_cutoff_bohrfloatnone> 0, BohrRequired by ao-sparse. An error with the other formulations.
formulationstring"delta-lr"delta-lr coupled-ringsrs-mp2-rpa.
attenuatorstring"erf"erf terfrs-mp2-rpa. terf needs FERRIC_TERF_TABLE_DIR. An error on att-rimp2 (use att_operator).
r0float1.6828 (= 3.18 Bohr)Års-mp2-rpa with terf only. An error on att-rimp2 (use att_r0).
terf_omegafloatlinked, ω = 1/(r0√2)Å⁻¹, > 0rs-mp2-rpa with attenuator = "terf" only (an error elsewhere). Sets the terf/terfc sharpness independently of r0. Same as Python run_rs_mp2_rpa(terf_omega=).
att_operatorstring"erfc"erfc terfc (case-insensitive)att-rimp2 only (an error on any other kind). The short-range operator on the MP2 correlation; the SCF stays Coulomb. terfc is the Python run_terfc_rimp2 and needs FERRIC_TERF_TABLE_DIR.
att_r0float1.05Å, > 0att-rimp2 with att_operator = "terfc" only; an error with erfc.
att_omegafloatlinked, ω = 1/(r0√2)Å⁻¹, > 0att-rimp2 with att_operator = "terfc" only; an error with erfc (use omega) and on any other kind. Sets the terfc seam sharpness independently of att_r0, via Operator::terfc_with_omega; r0·ω = att_r0 × att_omega. Needs FERRIC_TERF_TABLE_DIR. With [local] integral-direct it takes the same schwarz_skip cut as the other operators.
r0_sweeparray of floatsnoneÅ, > 0rs-mp2-rpa with terf only. Reuses one SCF for several r0 values. r0 is then ignored with a warning.
r0_bondedfloat0.75Åscs-mp2-2terfc.
r0_nonbondedfloat1.05Å, > r0_bondedscs-mp2-2terfc.
linlccd_variantstring"hh"hh drivers-only fulllinlccd only (an error on any other kind), exact and local alike: it selects the method. drivers-only equals RI-MP2; full adds the pp ladder (CCD-like VVVV memory). Any other value is an error.
mp2v_r0float1.00Å, > 0mp2-v. Also sets the VV10 damping r0. It is correlated with mp2v_b in the published fit.
mp2v_bfloat11.0mp2-v.
mp2v_cfloat0.0089mp2-v. Fixed in the paper. Changing it leaves the published parameterization.
mp2v_attenuatorstring"terfc"terfc erfcmp2-v. terfc needs FERRIC_TERF_TABLE_DIR. erfc is an unparameterized control.
mp2v_omegafloatlinked, ω = 1/(r0√2)Å⁻¹, > 0mp2-v with terfc only. Setting it leaves the fitted parameterization.
mp2v_vv10_dampingstring"terfc"terfc nonemp2-v. none double-counts short-range correlation.
mp2v_nlc_n_radialinteger50> 0mp2-v VV10 grid.
mp2v_nlc_n_angularinteger50> 0mp2-v VV10 grid (unpruned).
oo_max_iterinteger100≥ 1oo-rimp2 only (closed and open shell). Orbital-optimization iterations.
oo_grad_convfloat1e-4> 0oo-rimp2 only. Convergence threshold on the orbital-gradient norm.
oo_level_shiftfloat0.1Hartree, ≥ 0oo-rimp2 only. Level shift on the approximate diagonal orbital Hessian.
oo_diis_sizeinteger6≥ 1oo-rimp2 only. DIIS subspace for the orbital rotations. The four oo_* keys match Python run_oo_rimp2(oo_max_iter=, grad_conv=, level_shift=, diis_size=); on any other kind they are an error.

[cc]

Closed-shell CCSD knobs, read by ccsd and ccsd(t) only; on any other kind the section is an error. The aux basis and frozen core stay in [mp2].

KeyTypeDefaultAllowed valuesNotes
ladderstring"auto"auto dense ri (lower case only)How the particle–particle ladder is evaluated. dense holds the nv⁴ (ab|cd) block; ri rebuilds it from the RI 3-index tensors every iteration, holding at most one nv⁴-sized panel at full width (dense holds four) and narrower panels when the budget requires (same energy to round-off, less memory, slower per iteration); auto takes dense whenever its memory plan fits the budget and ri otherwise, and says so on stderr when it falls back. The run prints the route taken (ladder = dense (auto)). Python run_ccsd(ladder=), run_ccsd_t(ladder=). See Coupled cluster.

[local]

The local approximation of a correlated method. method.kind names the method (rimp2, drpa, linlccd or, integral-direct only, att-rimp2); this section says whether and how its amplitudes are truncated. Without it (or with scheme = "none") the method is computed exactly. On any other kind the section is an error. The local runs are closed shell and task = "energy" only, and every printout and run-log result carries the model: "<method> (exact)" with "local": null, or the scheme, eps and kept fraction. See The MP2 family and Exact and local correlation.

KeyTypeDefaultAllowed valuesNotes
schemestring"none"none amplitude-thresholdamplitude-threshold: drop pair amplitudes whose localized integral is at or below eps (single threshold). Any other value is an error.
epsfloatrequired with amplitude-threshold≥ 0, finiteThe threshold is part of the model and has no default. 0 keeps every amplitude and reproduces the exact method. An error with scheme = "none".
eps_sweeparray of floatsnoneeach ≥ 0drpa only. Several ε on one SCF and one localized assembly; sorted and de-duplicated, one result block per point. Instead of eps, not with it.
referenceboolfalseAlso compute the exact method (canonical RI-MP2, canonical plasmon dRPA, exact LinLCCD) and print the local error against it. Costs the full exact calculation. An error with scheme = "none".
integral_directboolfalserimp2 only. The integral-direct local MP2: never forms the global 3-index tensor.
aux_radiusfloat10.0Bohr, > 0Integral-direct only (an error otherwise). Aux fit-domain radius.
virt_radiusfloat12.0Bohr, > 0Integral-direct only. Virtual domain radius.
ao_tailfloat1e-3≥ 0Integral-direct only. 0.0 keeps every shell.
schwarz_skipfloat1e-5≥ 0Integral-direct only. Cauchy-Schwarz cut on the batch 3-index triples: a triple is skipped when sqrt(max (P|P)) * sqrt(max (ab|ab)) < schwarz_skip, both factors from the run's own operator (Coulomb, erfc or terfc; the terfc factors carry a 1e-5 relative table-error inflation each, so the product is scaled by (1 + 1e-5)²). For terfc it is available for orbital shells up to g, r0 in [0.3, 2.5] Å and r0·ω ≤ 8.9, and errors outside that (set 0.0 to run anyway). See integral-direct local MP2. 0.0 evaluates every triple (bit-identical to a run without the cut).
batch_mergeinteger4≥ 1Integral-direct only.
gate_calfloatnone (gate off)> 0Integral-direct only. Pair-gate calibration (~0.7 Coulomb, ~0.02 erfc ω = 1).
virt_schwarz_kappafloatnone (off)> 0Integral-direct only. ε-linked Schwarz virtual-candidate screen.

[rpa]

Read by pdep-rpa, gw, bse-tda, tdhf-static-polarizability, and, for trunc_thresh only, rs-mp2-rpa.

KeyTypeDefaultAllowed valuesNotes
auxbasisstring"cc-pvdz-ri"aux basis name
frozen_coreint, string or bool0as [mp2]
xcstringnone (HF reference)XC nameSwitches the reference to RKS, or to UKS when open shell. Required by tdhf-static-polarizability. bse-tda ignores it. pdep-rpa with task = "optimize" uses an RHF reference; xc applies only to task = "energy".
n_quadinteger20 (energy runs); 16 (task = "optimize")Python run_pdep_rpa also uses 20.
quadraturestring"gauss-legendre" (CLI, Python and the Rust library QuadratureConfig::default())gauss-legendre gauss_legendre gl; minimax mini-max mm; chebyshev-tan chebyshev_tan chebyshev ct
u0float0.5Warn-and-ignore under minimax, which derives its own u₀.
trunc_threshfloat1e-4; 0.0 (full rank) for rs-mp2-rpaPDEP truncation.
eigensolver_conv_threshfloat1e-6 (energy); 1e-8 (optimize)Alias: davidson_conv_thresh.
chi0_sparsitystring"dense"dense, boys, boys:<thresh>, auto, auto:<cutoff>, auto:<cutoff>:<thresh>, each boys/auto form optionally suffixed @<radius_bohr>
run_diagnosticsboolfalse
export_eigpot_prefixstringnoneWrites <prefix>_eigpot_NNN.cube.
export_eigpot_countinteger10Capped at the number of eigenpotentials.
cube_spacingfloat0.2Bohr
cube_marginfloat4.0Bohr
export_npzstringnonepathTurns on the NPZ property bundle. The compute_* keys below default to true only when this is set.
compute_espbooltrueESP at the nuclei.
compute_esp_surfaceboolfalseESP on a vdW shell.
esp_surface_vdw_scalefloat1.4
esp_surface_n_angularinteger110Lebedev order
compute_polarizabilitybooltruealpha_tensor, the molecular static α.
compute_alpha_atomicbooltruealpha_atomic: the Krishtal–Senet–Van Alsenoy intrinsic per-atom α (JCP 125, 034312 (2006)), always Becke-partitioned; c6_partition does not affect it. Charge transfer between atoms is excluded; with compute_polarizability also on, the remainder alpha_ct = alpha_tensor − Σ_A alpha_atomic is exported.
compute_electric_fieldbooltrue
compute_density_matrixbooltrue
compute_dipolebooltrue
compute_hirshfeld_chargesbooltrueProatoms are free-atom SCF densities in the molecule's basis and SCF settings, as in Python's hirshfeld_charges.
compute_lowdin_chargesbooltrue
compute_mulliken_chargesbooltrue
compute_chelpg_chargesbooltrue
compute_resp_chargesbooltrue
compute_c6booltrueWith c6_source = "pdep", also exports alpha_ct_dynamic (nfreq, 3, 3): molecular α(iω) − Σ_A α^A(iω).
allow_partial_npzboolfalseBy default a bundle missing a requested property fails the run.
c6_sourcestring"ts"ts pdep mbd
c6_partitionstringhirshfeld for pdep, becke for ts/mbdbecke hirshfeld

[gw]

Read by gw. bse-tda and tdhf-static-polarizability read frozen_core, and tdhf-static-polarizability also reads scissor. The [rpa] section supplies the screened interaction.

KeyTypeDefaultAllowed valuesNotes
methodstring"g0w0"g0w0 cohsex evgw0 evgw (case-insensitive)
qp_mos[lo, hi]HOMO−2 … LUMO+2absolute MO indices, half-open
max_ev_iterinteger20evGW/evGW0 outer loop.
ev_conv_threshfloat1e-4Hartree
pade_nptsinteger0 (= [rpa] n_quad)
qp_newton_dampfloat1.0
frozen_coreint, string or boolfalls back to [rpa] frozen_coreas [mp2]Also overrides the PDEP frozen core, so W and Σ agree.
scissorfloat0.0Hartreetdhf-static-polarizability only. At 0.0 some molecules hit a negative α diagonal and the run errors. The remedy is about 0.3–0.4 Ha.
referencestring"uhf"uhf rohf (case-insensitive)gw on an open-shell molecule only: the reference is UHF or ROHF (UKS or ROKS with [rpa] xc). An error on a closed-shell molecule or another kind. Same as Python run_u_gw(reference=).

[tddft]

Read by tda and tddft. Also set [mp2] auxbasis (see above).

KeyTypeDefaultAllowed valuesNotes
n_rootsinteger3
xcstringnone (HF reference: CIS or TDHF)XC nameSelects the reference functional and the f_xc kernel. Meta-GGA, VV10 and range-separated functionals are refused.
c_hffloatthe functional's short-range exact-exchange fraction; 1.0 with no xc

[optimize]

Read when task = "optimize".

KeyTypeDefaultAllowed valuesNotes
max_stepsinteger100
g_max_threshfloat4.5e-4Hartree/Bohr
g_rms_threshfloat3.0e-4Hartree/Bohr
e_convfloat1e-6Hartree
trust_radiusfloat0.1Initial step size.
coordinatesstring"cartesian"cartesian cart; internal internals redundant-internal redundant_internal

[frequencies]

Read when task = "frequencies".

KeyTypeDefaultAllowed valuesNotes
hessianstring"auto"auto; analytic; analytic-moving-grid; fd finite-differenceauto uses the analytic Hessian for RHF (closed shell), UHF (aufbau occupations) and ROHF (kind = "rohf" without [dft] functional) with the Coulomb operator and exact four-centre J/K (RHF, UHF and ROHF also with density-fitted J and/or K: [scf] df_j_aux and/or df_k_aux set, ω = 0 only, no external potential (an ECP is analytic with RI), a fitting-basis metric with no eigenvalue below 1e-10 (RI-K: none below 1e-7 and cond(V) at most 1e8 for auto), and RI-K memory that fits the [memory] budget (it grows like N⁴: about 10 GB for 30 atoms with 300 basis functions, the same for the two spin channels of UHF and ROHF); no range-separated RI-K, no COSX), a basis up to f functions and a libint2 with second derivatives. For RHF and UHF, ECPs (on the default quadrature backend; FERRIC_ECP_BACKEND=libecpint is not analytic), external point charges, Gaussian-smeared external charges and a uniform external field are analytic; for ROHF an external potential is not (an ECP is). Implicit solvent, polarizable embedding, fractional occupations, MOM and constraints are not analytic for any reference. For closed-shell Kohn-Sham (kind = "ksdft", or rhf with [dft] functional) auto uses the analytic-moving-grid Hessian wherever it applies (below); UKS, ROKS, every KS case it refuses and systems whose response AO table (basis functions × grid points × 4 for a GGA, 8 bytes each) exceeds 2 GiB (on the default 75×110 grid, a GGA above about 8,100 basis functions × atoms) use finite differences, decided before the SCF; an error it raises after the SCF (a non-converged SCF included) is returned, as for the Hartree-Fock routes. Anything else uses finite differences. analytic is the Hartree-Fock analytic Hessian and an error where it does not apply (every Kohn-Sham reference included). analytic-moving-grid is the analytic closed-shell Kohn-Sham Hessian on the production (moving) grid, Becke weight response included, so it is the Hessian of the surface the KS gradient differentiates and agrees with fd to the finite-difference error. It applies to kind = "ksdft" (or rhf with [dft] functional) on a closed shell, LDA or GGA functionals, pure or global hybrid, with exact or density-fitted J and K. It is an error, before the SCF, for Hartree-Fock, open-shell (UKS/ROKS) references, meta-GGA, VV10, range-separated hybrids, ECPs, external potentials, [dft] dispersion, and what the analytic RHF Hessian refuses (COSX, implicit solvent, fractional occupations, MOM). The output prints Hessian = analytic, analytic-moving-grid or finite-difference; the JSON run log carries a frequencies record with the full-precision wavenumbers and Cartesian Hessian.
deltafloat5e-3Bohr, finite and > 0Central-difference step, finite-difference Hessians only. Check the printed Hessian asymmetry: it is zero in exact arithmetic.

[memory]

KeyTypeDefaultAllowed valuesNotes
budget_gbfloatautofinite and > 0Precedence: this key, then FERRIC_MEM_BUDGET_GB, then the legacy FERRIC_OOC_BUDGET_GB/FERRIC_ERI3_BUDGET_GB, then 0.8 × available RAM, then 2 GiB. A value of 0, a negative value or NaN is an error; omit the key for auto. It bounds the ledgered allocations, not total process memory.
three_index_budget_gbfloat—Deprecated alias. budget_gb wins if both are set.

[gpu]

Optional CUDA backend. A default build has no GPU code: there mode = "on" is an error and mode = "auto" prints a notice and runs on the CPU. A GPU run is deterministic run to run on one device but is not bit-identical to the CPU run (a different summation order, like FERRIC_BLAS_THREADS above 1).

KeyTypeDefaultConstraintMeaning
presetstring"off"off, auto, on, mixed, auto-mixedOne word that sets mode and precision together; see the presets table below. The root-level key gpu = "mixed" is the same as [gpu] preset = "mixed" (a file cannot hold both a root gpu string and a [gpu] table). A mode, precision or mixed_kernels key, or its env var, that disagrees with the preset is an error naming both; one that agrees is kept. device, memory_gb and min_flops combine with any preset. Env: FERRIC_GPU_PRESET.
modestring"off"off, auto, onauto uses a device when one is usable and otherwise prints a notice and runs on the CPU; on makes an unusable device an error. The Kohn-Sham XC grid uses the device only under on: under auto it stays on the CPU, because it was measured slower on the device (GTX 1080; see installation). Env: FERRIC_GPU.
deviceinteger0a CUDA ordinalWhich device to use. Env: FERRIC_GPU_DEVICE.
memory_gbfloat0.8 x freefinite and > 0Device-memory pool (decimal GB). A GEMM that does not fit runs on the CPU. Env: FERRIC_GPU_MEM_GB.
min_flopsinteger549755813888Smallest 2*m*n*k that an f64 einsum! matrix product sends to the device; the default is the rounded-up value of a crossover rule applied to products up to 6144³: the device does not clearly beat 6 CPU cores on a single f64 product at any shape measured (at best a 2-8% median win at 6144³ in two of three runs, a loss in the contested run, and at 4096³ and below the CPU won). Products of 2^39 FLOP or more go to the device, and that region is unmeasured. The device RI-MP2 energy does not consult it. Env: FERRIC_GPU_MIN_FLOPS.
precisionstring"f64"f64, mixedDeprecated alias of [precision] mode. It still works; given together with [precision] mode, the two must agree (a different value is an error). The run prints a deprecation note. Env: FERRIC_GPU_PRECISION.
mixed_kernelsstring arraythe kernels this build shipsas [precision] mixed_kernelsDeprecated alias of [precision] mixed_kernels. It still works; given together with [precision] mixed_kernels, the two must agree (a different list is an error). Env: FERRIC_GPU_MIXED_KERNELS (comma-separated).
gpu = "mixed"   # same as [gpu] preset = "mixed": device on, mixed precision for every shipped kernel

GPU presets

A preset fills in every knob below that is not given; the filled-in knobs print with [source: preset] in the audit lines.

Presetmodeprecisionmixed_kernels
offofff64the build default
autoautof64the build default
ononf64the build default
mixedonmixedevery kernel this build ships (rimp2-energy: the Coulomb, erfc and terfc RI-MP2 energy, closed-shell and unrestricted)
auto-mixedautomixedevery kernel this build ships (rimp2-energy: the Coulomb, erfc and terfc RI-MP2 energy, closed-shell and unrestricted)

preset = "off" is the same as no [gpu] key. A narrower mixed_kernels list is allowed under mixed and auto-mixed; naming a kernel the build does not ship is an error. Precedence for the preset itself: the command-line flag ferric --gpu <preset> input.toml (or --gpu=<preset>), then [gpu] preset or the root gpu key, then FERRIC_GPU_PRESET, then off. The flag labels its audit line [source: command line]; a mode, precision or mixed_kernels key or env var that disagrees with the flag is an error naming both, and --gpu given twice, without a value or with an unknown name is refused (exit code 2).

ferric --gpu mixed input.toml

[precision]

Which kernels may run in mixed precision, independent of the device. [gpu] chooses only device placement; its precision and mixed_kernels keys are deprecated aliases of the two keys here (either spelling works; both given with different values is an error). Every result records what ran in its precision provenance record (see Run logs). The default, no [precision] section, is f64 everywhere and bit-identical to a file without the section.

KeyTypeDefaultConstraintMeaning
modestring"f64"f64, mixedmixed runs the kernels in mixed_kernels with f32 storage and f32 panels accumulated in f64; every other contraction stays f64. A kernel that runs on a device needs [gpu] mode auto or on; with [gpu] mode = "off" (CPU-only mixed precision) only kernels with a CPU mixed path are accepted, and naming or defaulting to a device kernel is an error that lists the CPU kernels this build admits (dfj-f32, opt-in; cosx-kern is a CPU kernel but not shipped). A mixed result is not an f64 result: its error is bounded, measured and documented on the validation page, not validated against a reference code. Python: ferric.configure_precision(mode=...). Env: FERRIC_GPU_PRECISION.
mixed_kernelsstring arraythe kernels this build shipsrimp2-energy, ccsd-amplitudes, dfk-occ, cosx-kern, dfj-pack, xc-vxc, dfj-f32Which kernels may run in mixed precision; requires mode = "mixed". This build ships rimp2-energy: with mode = "mixed" the device RI-MP2 energy keeps B_ov as f32 and accumulates its panels in f64 (the default precision stays "f64", so shipping the kernel changes nothing until you ask). rimp2-energy covers the RI-MP2 energy under the Coulomb, erfc and terfc operators, closed-shell and unrestricted (open-shell, one f32 B_ov per spin); the erf operator, composite fitted operators, SR-MP2 in RS-MP2+RPA, OO-MP2 and kappa-regularised runs use the f64 device kernel. xc-vxc (the Kohn-Sham XC potential matrix of LDA and GGA functionals from f32 operands with f64 accumulation, used only in SCF iterations whose density is still changing; see the validation page) is opt-in: it is admitted when the list names it, but it is not in the default set, so mode = "mixed" or gpu = "mixed" alone leaves it out; naming it under any [gpu] mode other than "on" is an error, since the XC grid stays on the CPU under auto (measured slower on the device; see installation). dfk-occ (the device DF-K occupied path with the dressed 3-index tensor resident as f32 and f64 panel accumulation, used only in SCF iterations whose density is still changing) is opt-in on the same terms, named in the list and under mode = "on": its converged energies match the f64 device SCF to within the f64 run's own termination noise, but a mixed SCF saved only about 4% of the wall time on the one device measured, and was 3-6% slower with diffuse basis sets (see the validation page). dfj-pack (the device RI-J with the packed raw 3-index tensor resident as f32, f64 accumulation) is named in this build but not shipped. dfj-f32 (the CPU RI-J with its stored 3-index tensor kept as f32, f64 accumulation, half the memory) is opt-in: it runs when the list names it, under any [gpu] mode; every SCF RI-J build reads the rounded tensor, so the converged energy carries a first-order error of the µEh scale (PBE/def2-SVP: -0.9 µHa on n-C20H42, +5.4 µHa on danuglipron, whose peak memory fell from 8.0 to 6.1 GB and J time from 5.7 to 3.5 s) (there is no SCF ladder and no f64 exit), Hessian, response and gradient RI-J builds stay f64, and a gradient after an f32 SCF is taken at the f32 density. Naming a kernel this build does not ship yet is an error, and a build that ships no mixed kernel refuses mode = "mixed" ("no mixed-precision kernel is available in this build"). Kernels that are not names here (SCF diagonalisation, DIIS, metric inverses, GW, grid construction and Becke weights, the XC density and the functional, meta-GGA τ) never run below f64. One kernel name per list item: an empty list or a comma inside an item is an error. Python: ferric.configure_precision(mixed_kernels=[...]). Env: FERRIC_GPU_MIXED_KERNELS (comma-separated).
[gpu]
mode = "on"

[precision]
mode = "mixed"
mixed_kernels = ["rimp2-energy"]

[output]

KeyTypeDefaultAllowed valuesNotes
jsonstring or bool<input-stem>.ferric.jsonl beside the inputa path, true (the default path), false (off)On by default. See Run logs. --json <path> and --no-json override it.

[qmmm]

When present, the PQR supplies both the geometry and the MM charges. It cannot be combined with [external_potential]; doing so is an error.

KeyTypeDefaultAllowed valuesNotes
pqrstringrequiredpathGeometry in Å and charges in e. The element is read from the atom name.
qm_indicesinteger array[]zero-basedUse this, or qm_seeds + qm_radius_angstrom, but not both.
qm_seedsinteger array[]zero-based
qm_radius_angstromfloatnoneÅ, > 0Requires qm_seeds.
link_bondsarray of [qm, mm][]Required when the cut crosses a covalent bond.
boundary_schemestring"delete-host"keep delete-host rc rcdSetting a non-default value without link_bonds is an error.

See QM/MM. Smeared PQR charges, polarizable sites and MM force fields are Python only. (Smeared charges outside QM/MM are available through [external_potential] with width.)

[pcm]

IEF-PCM implicit solvent (ferric-pcm). Absent means vacuum. Honoured on task = "energy" by rhf, uhf, rohf, ksdft and pdep-rpa (for pdep-rpa the RPA correlation is evaluated on the solvated reference), and on task = "optimize" by rhf, uhf, rohf and ksdft (their gradients carry the analytic IEF-PCM term). Any other kind, any other task (frequencies: there is no PCM Hessian), [cosmo] in the same file, or pdep-rpa with [rpa] export_npz is an error. The solvent table and checks are shared with Python run_rhf(solvent=...). See examples/water-pcm.toml.

KeyTypeDefaultAllowed valuesNotes
epsilonfloat—finite and > 1Dielectric constant. Give exactly one of epsilon and solvent.
solventstring—water (78.4) dmso (46.7) methanol (32.6) ethanol (24.9) acetone (20.7) dichloromethane/dcm (8.93) thf (7.43) chloroform (4.71) toluene (2.38) hexane (1.88), case-insensitiveDielectric constants at 298 K. An unknown name is an error.
lebedev_orderinteger1106 14 26 50 110 302Tesserae per atomic sphere.

[cosmo]

Conductor-like implicit solvent, applied to every SCF variant. It cannot be combined with [pcm]. task = "energy" only: COSMO has no analytic gradient, so task = "optimize" and task = "frequencies" with [cosmo] are errors. Use [pcm] (which has a gradient) for optimization.

KeyTypeDefaultAllowed valuesNotes
epsilonfloatrequired when the section is presentfinite and > 1Default in code is 78.39, but serde has no default for this key.
radius_scalefloat1.17> 0Multiplies Bondi radii.
lebedev_orderinteger1106/14/26/50/110/302
s_matrix_kindstring"GaussianSmeared"GaussianSmeared PointChargeSerde variant names, case-sensitive.

[external_potential]

Strict, like every other section: an unknown key here or inside a point charge is an error.

KeyTypeDefaultAllowed valuesNotes
point_chargesarray of { q, x, y, z, width }[]q in e; x, y, z in Bohr; width in Bohr, finite and > 0Written as [[external_potential.point_charges]] tables. width is optional: with it the charge is Gaussian-smeared, density ∝ exp(−r²/width²) and potential q·erf(r/width)/r (the Python smeared_charges=); without it the charge is a point. See examples/water-rhf-smeared-charge.toml. The order of the list changes the one-electron potential only by summation roundoff (reordering 6458 charges: 3e-15 to 1e-14 relative) and ferric does not reorder it; a different SCF iteration count was seen only for the closed-shell direct-J/K path, on rc7 and, on main, with FERRIC_SCF_INCREMENTAL=1 below the incremental noise floor (see Sharp bits, "energy_conv is a sanity bound").
field[Ex, Ey, Ez]noneatomic unitsUniform electric field.

With both empty, the run is identical to a vacuum run.

[cell]

A 3-D periodic system. When present, the run goes to the periodic drivers instead of the molecular ones. The [molecule] XYZ supplies the atoms of the reference cell (in Å, like every XYZ). Energies are Hartree per cell.

method.kind must be rhf, uhf, rohf, ksdft, rimp2 (periodic MP2) or pdep-rpa (periodic dRPA). rhf/uhf/rohf with [dft] functional run RKS/UKS/ROKS. Any other kind is an error. At the Gamma point (no kmesh) RKS, UKS and ROKS also run range-separated (CAM) GGA hybrids with either jk: any libxc one is accepted (HSE06, or a libxc ID such as HYB_GGA_XC_CAM_B3LYP or HYB_GGA_XC_WB97X; the names CAM-B3LYP and wB97X do not resolve); HSE06 and CAM-B3LYP are pinned against PySCF, open-shell wB97X is accepted, not pinned (the attenuated exchange is the k = 0 point of the k-point range-separated exchange; PySCF Gamma pins agree to 1e-12; with jk = "rsgdf" the full-Coulomb fit is built twice, once for the Gamma J and once inside the attenuated exchange, so the build costs about 1.9× a plain Gamma run, and the exchange also contracts a J it discards every iteration; with jk = "dense" the tensors take 40 nao⁴ bytes, not 8, and max_eri_gb counts all of them); range_split with a range-separated hybrid is an error; task = "optimize" with HSE06 or CAM-B3LYP runs on the RKS, UKS and ROKS routes with either jk (the analytic forces of gamma_rsh::gamma_rks_rsh_gradient, gamma_rsh::gamma_uks_rsh_gradient and gamma_rsh::gamma_roks_rsh_gradient, the 1×1×1 k-point force on the SCF's own dense-AFT or RS-GDF exchange); other range-separated hybrids (wB97X) are energy only. The Gamma-point UKS and ROKS routes run the SCAN / r2SCAN energy with jk = "dense" (per-spin τ; jk = "rsgdf", task = "optimize" and any other meta-GGA are errors; kmesh = [1, 1, 1] is the Gamma point and runs the UKS SCAN / r2SCAN force; the k-point ROKS SCAN / r2SCAN force and stress are library-only, #498). task = "optimize" works at the Gamma point for the SCF routes (RHF, UHF, ROHF, RKS, UKS, ROKS) with either jk: it moves the atoms at a fixed lattice using the analytic periodic force, and prints the final gradient (Hartree/Bohr per cell). A Gamma-point RKS with SCAN / r2SCAN / TPSS optimizes too, with jk = "dense" only (the force is the 1×1×1 k-point force fed the Gamma SCF; it builds the 1×1×1 dense kernels, 32 nao⁴ bytes on top of the 8 nao⁴ Gamma ERI, and max_eri_gb counts all of them before the SCF); jk = "rsgdf" with a meta-GGA and task = "optimize" is an error. With kmesh it works for rhf, uhf and rohf (no functional) and for Kohn-Sham (ksdft, or rhf/uhf/rohf with [dft] functional: RKS, UKS, ROKS) using the analytic k-point force, with either jk on every route except the dense-only cases named below (SCAN / r2SCAN on the UKS route need jk = "dense"; unsplit RS-GDF: range_split with task = "optimize" is an error). The functionals are LDA, GGA and global hybrids such as PBE0 and B3LYP on every Kohn-Sham route, plus the pure meta-GGAs SCAN and r2SCAN on the closed-shell route (either jk) and the UKS route (jk = "dense"), TPSS on the closed-shell route (jk = "dense"), and the range-separated hybrids HSE06 and CAM-B3LYP (HYB_GGA_XC_CAM_B3LYP; other range-separated hybrids such as wB97X are energy only) on every Kohn-Sham route (RKS, UKS, ROKS; either jk); the force differentiates the energy's own XC grid (n_radial/n_angular/neighbour_cutoff) and, for a hybrid, its exxdiv. It is an error for range-separated hybrids other than HSE06 / CAM-B3LYP, VV10 functionals, TPSS on RS-GDF or an open-shell route, hybrid meta-GGA, meta-GGA forces on ROKS (its SCAN / r2SCAN energy runs, jk = "dense"; the library k-point ROKS SCAN / r2SCAN force and stress exist but are not wired, #498) and UKS meta-GGA forces and stress on RS-GDF, and for rimp2/pdep-rpa. Cells whose basis carries an ECP are supported by the k-point force and stress of every route above (RHF, UHF, ROHF, RKS, UKS, ROKS). The lattice is fixed in task = "optimize" (no stress relaxation). The analytic stress of a k-point SCF is printed by a task = "energy" run with stress = true (see the key below): rhf, uhf, rohf, ksdft and the [dft] functional routes (RKS, UKS, ROKS), either jk except where the stress key below says jk = "dense", the 3×3 tensor in Hartree/Bohr³ and in GPa, and the same two tensors in the run log's run_end record (extra.stress_hartree_per_bohr3, extra.stress_gpa, full precision; see run logs). It equals the Python with_stress=True tensor bit for bit (Python: run_rhf_kpts, run_uhf_kpts, run_rks_kpts, run_uks_kpts, run_roks_kpts, run_rohf_kpts), with the gate shared: every route runs with either jk, the closed-shell SCAN / r2SCAN stress and the range-separated hybrid (HSE06, CAM-B3LYP) stress of every Kohn-Sham route (RKS, UKS, ROKS) included, except the UKS SCAN / r2SCAN stress, which needs jk = "dense" (unsplit RS-GDF: range_split with stress = true is an error). The k-point force and stress use an explicit functional allowlist that is separate from the energy gate (ferric_pbc::kxcgrad::check_deriv_functional, per route and J/K, wrapped by check_kpoint_deriv_functional, which the Python bindings call too). The run_end record of an optimization carries the returned geometry and the gradient there at full precision (extra.final_geometry_bohr, extra.final_gradient_hartree_per_bohr). solve_krks (every k-point Kohn-Sham energy run, run_rks_kpts and the CLI included) clones S(k) and h(k) transiently during the SCF (2 N_k n² × 16 bytes, not charged to the budget); the periodic XC Bloch AO cache of the SCF does not follow [memory] budget_gb. Each optimizer step runs a fresh SCF from the core guess; at a k-point mesh with uhf it can land in a different spin solution between steps, which shows as a visible jump in the step energies (nothing is hidden). The force is taken through the hcore and J/K objects the SCF built, which stay in memory for the force: their bytes are charged against the same memory budget ([memory] budget_gb with jk = "rsgdf"), and with jk = "dense" the kernels count against max_eri_gb while they exist. task = "frequencies" is an error.

The periodic run reads only [cell], [scf] max_iter, [scf] density_conv (Gamma point) or energy_conv (k-point mesh), [scf] level_shift (k-point rohf / ROKS only), [dft] functional, [memory] (RS-GDF only) and [optimize]. Any other section or key is an error. A charged cell is an error.

KeyTypeDefaultAllowed valuesNotes
lattice3×3 float arrayrequiredrows are the lattice vectorsIn unit.
unitstring"angstrom"angstrom bohrApplies to lattice, omega and gdf_omega (as their inverse), neighbour_cutoff and neighbour_switch.
kmesh[n1, n2, n3]none (Gamma point)each ≥ 1Selects the k-point drivers: rhf, uhf, rohf (no functional); Kohn-Sham (ksdft, or rhf/uhf/rohf with [dft] functional): RKS with LDA, GGA, global-hybrid and SCAN / r2SCAN / TPSS functionals (and range-separated (CAM) GGA hybrids such as HSE06, HYB_GGA_XC_CAM_B3LYP and HYB_GGA_XC_WB97X, with either jk; forces and stress for HSE06 and CAM-B3LYP with either jk, wB97X energy only), UKS (ksdft with multiplicity > 1 included) with the same functionals as RKS except TPSS (SCAN / r2SCAN energy with either jk, forces and stress with jk = "dense"; the range-separated hybrids with either jk: the energy of any libxc CAM GGA hybrid, HSE06 and CAM-B3LYP pinned, open-shell wB97X accepted, not pinned, and the force and stress of HSE06 / CAM-B3LYP), and ROKS with LDA, GGA, global-hybrid and range-separated hybrid functionals (either jk; range-separated forces and stress for HSE06 / CAM-B3LYP as for UKS) and the SCAN / r2SCAN energy (jk = "dense"); rimp2 and pdep-rpa. task = "optimize" and stress = true run with HSE06 / CAM-B3LYP on RKS, UKS and ROKS (either jk) and with TPSS and UKS SCAN / r2SCAN on jk = "dense". Not yet supported with kmesh, each an error naming the gap: ROKS meta-GGA forces and stress, a ROKS meta-GGA with jk = "rsgdf", task = "optimize" or stress = true with a range-separated hybrid other than HSE06 / CAM-B3LYP, a UKS meta-GGA force or stress with jk = "rsgdf", VV10 functionals, TPSS on UKS/ROKS, task = "optimize" or stress = true with TPSS on jk = "rsgdf", meta-GGAs other than the pure SCAN / r2SCAN / TPSS, and task = "optimize" for rimp2/pdep-rpa (see task). Open-shell k-point KS and ROHF use ewald_start; [cell] n_radial/n_angular/neighbour_cutoff apply to the Kohn-Sham routes and, with a 1×1×1 mesh, the runs equal the Gamma-point ones.
centringstring"gamma"gamma mpRequires kmesh. gamma is the Gamma-centred mesh (contains Γ; PySCF make_kpts(n)); mp is the shifted Monkhorst-Pack mesh (PySCF with_gamma_point=False). Energies, task = "optimize" forces and stress = true all accept either.
exxdivstring"ewald"ewald noneExchange G = 0 treatment.
jkstring"dense"dense rsgdfdense is a toy-scale dense AFT tensor.
auxbasisstringnonebundled basis nameRequired by jk = "rsgdf"; an error with dense.
range_splitbool or floatfalsefalse, true (λ = 1), or a number > 0 (λ)Opt-in RS-GDF range split: moves the short-range blocks whose Fourier transform converges in the long-range G sphere into G space. Orbital primitives with exponent ≤ λω²/2 and aux primitives with exponent ≤ λω² count as smooth, where ω is the RS-GDF split (gdf_omega, default 1 Bohr⁻¹; not the omega key). λ ≤ 1 adds no G vectors; the energy matches the unsplit build to fitting precision. Requires jk = "rsgdf" and task = "energy" (Gamma point or kmesh). An error with task = "optimize": the optimizer is not wired to the range-split forces.
omegafloatmin(2.5 √π / V^(1/3), 0.9636 × ω_gdf), ω_gdf = gdf_omega in Bohr⁻¹> 0, in unit⁻¹Nuclear-attraction Ewald split. Any value gives the same energy to truncation (~1e-11 Ha); the default balances the real- and reciprocal-space nuclear-attraction cost, and its cap keeps the reciprocal-space sphere inside the RS-GDF one (so the cap scales with gdf_omega).
gdf_omegafloat or "auto"1 Bohr⁻¹finite, > 0, in unit⁻¹; or "auto"RS-GDF Ewald split ω. Any value gives the same energy to the fitting precision; it moves work between the short-range lattice sums (radii ∝ 1/ω) and the long-range G sphere (|G| ≤ 2ω √ln(10¹³)). The range_split thresholds and the RS-GDF forces follow it. Requires jk = "rsgdf" (an error with dense). Same as Python gdf_omega= (Å⁻¹). "auto" (opt-in; the default is unchanged) picks ω from a cost model of the cell: it prices the short-range triplet walk (the build's own screen, sampled) against the long-range G sum at ω = 0.25..2 Bohr⁻¹ and leaves 1 Bohr⁻¹ unless another value is predicted at least 10% cheaper. On the study cells (Gamma RHF, cc-pVDZ / cc-pVDZ-RI, 6 threads) sparse molecular crystals run 1.4-2.4× faster (dry ice 20.0 → 11.8 s) and dense cells keep 1 Bohr⁻¹ at a cost of ~0.2-0.5 s for the choice. Gamma-point task = "energy" only; an error with kmesh and task = "optimize". The chosen value is printed in the header and on stderr. Python: ferric.auto_gdf_omega(...) returns the value to pass as gdf_omega=.
sr_column_rotationboolon for a jk = "rsgdf" run (Gamma or kmesh), off with jk = "dense"true falseColumn rotation of generally contracted shells (the separate s/p contraction columns of cc-pVXZ-style bases) in the short-range walks: the RS-GDF short-range 3-centre sum and the hcore short-range nuclear attraction run on rotated columns and are transformed back exactly (at a kmesh the back-transform acts on the short-range residue bins and on V_SR(k) before the Bloch phase sums, the long-range and G = 0 parts stay in the parent basis). The energy matches the unrotated build to the screening precision (≤ 1.5e-11 Ha/cell at gdf_omega ≥ 0.7 on dry ice and diamond, cc-pVDZ) with fewer short-range integral calls (dry ice 25.9 → 22.4 s, diamond 7.84 → 3.08 s at 6 threads, gdf_omega = 1, range_split = true). The analytic forces and stress (task = "optimize") differentiate the same rotated walks, with the derivative blocks evaluated on the rotated columns, so optimisations keep the saving; at the Gamma point forces and stress equal the unrotated ones to ≤ 1e-12 (Ha/Bohr, Ha) on the test cells; at a kmesh the gap to the unrotated derivative is set by the screen (force 1.5e-10 Ha/Bohr, stress 6.5e-9 Ha on H2 cc-pVDZ at hcore/fit precision 1e-9/1e-10, shrinking with the precision). A basis with nothing to rotate (STO-3G, Pople, segmented) runs the unrotated build bit for bit. Absent, it is on for a jk = "rsgdf" run (Gamma point or kmesh) and off with jk = "dense"; the header line sr_column_rotation = says which and why. false turns it off everywhere. true is an error with jk = "dense". The k-point analytic forces (task = "optimize" with kmesh) and the library's k-point stress differentiate the rotated walks (the derivative blocks on the rotated columns, the residue weights transformed with Tᵀ W T). The stage table counters report how many columns were rotated: hcore SR rotated columns and rsgdf SR3 rotated columns at the Gamma point, k hcore SR rotated columns and k rsgdf SR3 rotated columns at a kmesh (0 = unrotated). Same as Python sr_column_rotation= on the Gamma bindings (None = this default).
max_eri_gbfloat0.5> 0Dense tensor cap. An error with rsgdf.
ewald_startstring"staged"staged directOpen-shell SCF with exxdiv = "ewald" only.
denominatorsstringrequired for rimp2/pdep-rpashifted unshiftedAn error on other kinds.
frozen_coreinteger0≥ 0rimp2/pdep-rpa only.
quad_pointsinteger40≥ 1pdep-rpa only. Gamma point needs jk = "rsgdf".
drpa_energystring"quadrature"quadrature plasmon second-orderpdep-rpa with kmesh only.
grad_convfloat1e-9> 0k-point SCF orbital-gradient threshold. Requires kmesh.
stressboolfalsetrue falseCompute and print the analytic stress σ = (1/Ω) dE/dε of the converged k-point SCF (Hartree/Bohr³ and GPa) and write it to the run_end record. Requires kmesh and task = "energy"; rhf, uhf, rohf, ksdft and the [dft] functional routes. An error, naming [cell] stress = true, with the Gamma point, task = "optimize", rimp2/pdep-rpa, range_split, range-separated hybrids other than HSE06 / CAM-B3LYP, TPSS and UKS SCAN/r2SCAN on jk = "rsgdf" (HSE06 / CAM-B3LYP run on RKS, UKS and ROKS with either jk; closed-shell TPSS and UKS SCAN/r2SCAN on jk = "dense"). ECP cells are supported. ROKS meta-GGA and hybrid meta-GGA are refused earlier by the k-point energy gate ([cell] kmesh with functional ...), which does not name stress. The run does one SCF through the retained hcore and J/K (the iteration printout of the plain energy run is replaced by the iteration count, energy and stress). The SCF must converge (the stress gate for restricted open shell is loose, 1e-5 in the orbital gradient: keep grad_conv well below it).
n_radialinteger75Periodic XC grid. Kohn-Sham only.
n_angularinteger3026 14 26 50 110 194 302 434 590Periodic XC grid. 434 and 590 are refinement grids; any other order is an error. Kohn-Sham only.
neighbour_cutofffloatmax(10 Bohr, covering-radius bound) (with neighbour_switch W: that value + W)> 0, in unit; ≥ bound + WPeriodic XC grid image cutoff D: image atoms within D of a grid point enter its partition weight. Kohn-Sham only. With the default neighbour_switch = 0 the cutoff is hard: the energy jumps wherever an image crosses D under a displacement or strain (measured: up to 2.2e-7 Ha on a (20, 50) grid at D = 10 on an H2 cell, and a 3.6e-5 Ha jump on an s+p triclinic cell at D = 10; the size depends on the grid and the cell) (a larger D does not remove the jumps; they get denser), and the analytic force and stress do not see the jumps, so a finite-difference step that straddles one misses by the jump / 2h. The default D also depends on the atom positions in a large sparse cell, so set it explicitly for task = "optimize" and for finite-difference checks.
neighbour_switchfloat0 (hard cutoff)≥ 0, in unitWidth W of a smooth taper on the image cutoff: an image at distance d from a grid point takes part with presence 1 for d ≤ D − W, falling to 0 at D (quintic smoothstep), and the analytic force and stress include the taper's derivative. This makes the energy continuous under displacement and strain. The taper costs the energy what lowering the cutoff toward D − W would (the automatic D adds W for that reason). Cost: the automatic D grows by W, so the image neighbours per point rise by about (1 + W/D)³; measured grid build on Li–H (75, 302): 0.29 s hard at D = 10, 0.87 s with W = 2 at the automatic D = 12. 0 is the hard cutoff, unchanged. Kohn-Sham only. Python: the neighbour_switch keyword (Å, default 0.0) of run_rks_gamma, run_uks_gamma, run_roks_gamma, run_rks_kpts, run_uks_kpts and run_roks_kpts; a negative or non-finite value is a ValueError.

Periodic [scf] defaults are max_iter = 200, density_conv = 1e-10 and energy_conv = 1e-12, not the molecular ones. k-point ROKS with a hybrid (exact exchange, global or range-separated) applies a 0.05 Ha virtual level shift by default, ramped to zero at convergence so the converged energy is unchanged; LDA/GGA ROKS and ROHF get none. [scf] level_shift (finite, ≥ 0, Hartree) overrides it on the k-point rohf / ROKS routes; 0 turns it off. Any other periodic route refuses the key.