Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

RustiQ is an experimental Rust quantum chemistry application and reusable rustiq-chem-core library. This manual serves scientific users, Rust contributors, and theoretical chemists.

Do not use RustiQ results for research conclusions without independent validation against established quantum chemistry packages.

Where should I start?

The glossary explains unfamiliar scientific and software terms. Existing workflow notes preserve useful operational guidance alongside the user guides and CLI reference.

Implemented capabilities include RHF, UHF, MP2, XYZ geometries, Gaussian basis sets, TOML and native Nickel input, sequential studies, and versioned JSON. The practical user guides now cover these capabilities, including HF/MP2 calculations, Nickel studies, JSON output, and portable calculation bundles. The command-line reference describes the shipped commands and options.

Portable .rustiq bundles can be written, reused, and inspected from the CLI as well as through Rust APIs. Start with the portable bundle guide for a runnable CLI workflow, then see the persistence specification for the archive contract. The authoritative references page links to the roadmap for plans and to the files that define existing contracts.

Installation

Compare Docker, Nix, and manual installation before choosing your setup. Each has a dedicated page with prerequisites, commands, advantages, and limitations. Docker always runs the supplied workspace under Linux, including on Windows and macOS hosts. For native host execution, use manual installation, or Nix on a supported platform. See known supported platforms for details.

The quick commands below use the manual setup. Install Git, Rust through rustup, a C/C++ build toolchain, and CMake as described in the manual setup page.

Build from source:

git clone https://github.com/mveril/RustiQ.git
cd RustiQ
rustup show
cargo build --locked

The checked-in rust-toolchain.toml selects the Rust toolchain. Run this guide’s commands from the repository root.

Alternatively, enter nix develop .#rust after cloning. The flake declares x86_64 Linux, AArch64 Linux, and Apple Silicon macOS. Windows users can use WSL2 or the VS Code Dev Container for the Linux environment. See development environments for setup and troubleshooting.

To install the executable into Cargo’s binary directory:

cargo install --locked --path .
rustiq --help

This command installs from the checked-out source. Once the current package prerelease has been published to crates.io, install it from the registry with cargo install --locked rustiq-chem --version 0.1.0-alpha.1. For later stable releases, omit --version to install the latest stable version. Tagged binary archives and verification instructions are described in Releasing RustiQ.

When a tagged binary release is available, download the archive matching your operating system and CPU from the GitHub Releases page. Unix archives are named rustiq-chem-<target>.tar.gz; Windows archives use rustiq-chem-<target>.zip. The targets are x86_64-unknown-linux-gnu (64-bit Intel/AMD Linux), aarch64-unknown-linux-gnu (64-bit ARM Linux), x86_64-apple-darwin (Intel macOS), aarch64-apple-darwin (Apple Silicon), x86_64-pc-windows-msvc (64-bit Intel/AMD Windows), and aarch64-pc-windows-msvc (Windows on ARM). Verify the archive with its .sha256 file or the release’s sha256.sum manifest as described in Releasing RustiQ, then extract it and put rustiq (or rustiq.exe on Windows) in a directory on PATH. Prebuilt binaries use the default online basis lookup; provide the basis data required by the calculation as described in the basis-set guide.

The executable is named rustiq (or rustiq.exe on Windows); use lowercase on case-sensitive systems. Ensure Cargo’s binary directory is on PATH. The tutorial still needs the checked-in samples.

Online basis downloads are enabled by default. The first calculation imports a repository fixture and requires no basis download. It also works with --no-default-features.

First H₂ calculation

Run neutral singlet H₂ with STO-3G from the repository root:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.toml

Import writes the checked-in basis fixture to the application’s local basis store, avoiding a network download. CLI tests import the same fixture into an isolated store.

The checked-in configuration is included directly:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf.guess]
type = "CoreHamiltonian"

The geometry path resolves from the runfile directory. Preserve the directory layout if copying the sample. Its XYZ source is:

2
Hydrogen molecule
1 0.0 0.0 -0.37
H 0.0 0.0  0.37

Default input units are Angstrom; resolved coordinates are Bohr. The neutral singlet defaults resolve HF Auto to RHF. The core-Hamiltonian guess makes this example deterministic.

The existing CLI regression test checks this input, RHF resolution, units, two SCF iterations, and these selected output lines. Its reproducible command is below; the test source is linked for readers who want to inspect its assertions.

CLI test source on GitHub

SCF converged after 2 iterations.
Total Energy (including nuclear repulsion): -1.116759 Hartree

Run that verification with:

cargo test --locked --test cli_samples test_cli_h2_sample_converges_and_prints_reference_energy

For independent numerical verification, the h2-sto-3g-rhf case compares full precision JSON energies against PySCF with a 2e-10 Hartree energy tolerance. The rounded terminal value above is not that tolerance. See the book’s scientific scope and reference comparisons for the coverage boundary. The comparison implementation and full reference instructions are linked below.

Comparison source on GitHub

Reference test instructions on GitHub

nix run .#pyscf-check -- -k h2-sto-3g-rhf

These checks validate this case, not arbitrary chemistry. Results remain experimental and require independent validation before research use. Continue with output interpretation. To save and reuse the calculation’s AO ERIs, continue with the portable bundle guide.

Interpreting output

The standard run report has three visible parts:

  • Requested options: a canonical TOML representation of the requested calculation and a canonical XYZ representation of its input geometry. These show the options after parsing and normalization; they do not reproduce the original source text or comments.
  • Resolved settings: a concise summary of the scientific setup used for the calculation, including atom count, charge, multiplicity, coordinate units, resolved HF method, and basis name and size.
  • Numerical results: SCF convergence information, energy values, overlap rank, energy components, and timings. The H₂ sample’s total HF energy is reported as -1.116759 Hartree.

The original TOML and XYZ source text, along with full canonical views of the resolved configuration and geometry, are retained as internal representations; the standard CLI report does not display them.

Portable bundles can retain the scientific input snapshots and AO ERIs for later inspection and compatible reuse. They do not save the energies or the HF wavefunction; see portable calculation bundles.

The first sample resolves to neutral singlet H₂, RHF, STO-3G, and two basis functions. Input coordinates are Angstrom; resolved coordinates are Bohr. Energies are in Hartree.

  • Electronic energy: electronic kinetic energy, electron–nuclear attraction, and electron–electron interaction at the HF level.
  • Nuclear repulsion energy: repulsion between the fixed nuclei.
  • Total HF energy: electronic energy plus nuclear repulsion.
  • SCF convergence: the iterative solution met its configured criterion. This does not establish basis completeness or accuracy against experiment.

Convergence and overlap diagnostics

Both RHF and UHF require delta_energy and residual_norm to be below method.hf.convergence_threshold (default 1e-8). delta_energy is the absolute change in electronic energy between successive iterations, in Hartree. residual_norm is the Frobenius norm of the AO matrix residual \(FPS - SPF\), where \(F\), \(P\), and \(S\) are the Fock, density, and overlap matrices. UHF combines the alpha and beta norms as \(\sqrt{r_\alpha^2 + r_\beta^2}\). The same numerical threshold is applied to both diagnostics; it is not an error bound on the final energy.

Final canonicalization also checks that orbitals obtained from the final Fock matrix reproduce the occupied density within that threshold. Further density updates consume the remaining SCF iteration budget; failure to obtain consistent orbitals is a numerical error. RHF additionally requires an unmixed orbital density before accepting convergence.

Overlap effective rank is the number of retained independent basis directions. With method.hf.orthogonalization.linear_dependency_threshold = t, eigenvectors of the overlap matrix are retained only when their eigenvalue exceeds \(t\lambda_{\max}\). The default is 1e-8. A report of 9/10 means one direction was discarded, reducing the orbital space used by HF and MP2. Increasing this threshold can change energies. Setting it to zero retains all directions only if the overlap matrix is strictly positive definite.

Inspect both convergence diagnostics and the retained rank when comparing calculations. See the Nickel schema for input defaults and the scientific limitations for the interpretation of a converged solution.

The first-calculation test checks the rounded total energy of -1.116759 Hartree. The independent comparison uses full precision.

MP2 adds a correlation energy to a converged HF reference. This first sample does not request MP2. The checked-in MP2 sample is included here so the manual shows the exact runnable input:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf]
method = "Rhf"

[method.hf.guess]
type = "CoreHamiltonian"

[method.mp2]
frozen_orbitals = 0

MP2 sample source on GitHub

Its h2-sto-3g-rhf-mp2 PySCF comparison provides executable evidence for the MP2 guide; see the book’s reference comparison coverage.

A successful small-basis H₂ test does not validate every molecule, basis, open-shell state, or chemical prediction. Review the book’s scientific limitations. The full reference-test instructions remain available on GitHub.

Geometry files

RustiQ reads molecular coordinates from XYZ files. Each file starts with the number of atoms, then a comment line, then one line per atom containing an element symbol or atomic number and three Cartesian coordinates. See the checked-in H₂ example:

2
Hydrogen molecule
1 0.0 0.0 -0.37
H 0.0 0.0  0.37

RustiQ treats the coordinates as Angstrom by default; TOML can specify Bohr. The coordinates in XYZ do not specify molecular charge, spin multiplicity, or units. Those are calculation settings. A charge changes the electron count; multiplicity specifies the intended spin state. RustiQ checks that the electron count and multiplicity have compatible parity, but this check does not identify the physical ground state. See the configuration guide.

geometry info reports atom and center information, including a nuclear repulsion value.

Warning

Nuclear repulsion: beware of XYZ coordinate units.

geometry info does not convert coordinates from Angstrom to Bohr. XYZ files have no unit metadata, so this command evaluates nuclear repulsion directly from the supplied numbers, effectively treating them as Bohr. For an XYZ file written in Angstrom (including the H₂ sample below), its reported nuclear-repulsion value is not a physically meaningful energy in Hartree. Do not interpret or compare it with energies from a molecular calculation.

Unlike geometry info, rustiq run converts input coordinates using [molecule].units (default: "Angstrom") before computing energies. This setting does not apply to the standalone geometry command.

From the repository root, inspect a geometry with:

cargo run --locked -- geometry info samples/h2/molecule.xyz

The geometry tools can rotate, translate, center, or orient XYZ coordinates. For example, transformations read and write XYZ and can use standard input/output:

cargo run --locked -- geometry translate samples/h2/molecule.xyz --dz 1

These are coordinate transformations. They do not change coordinates to minimize molecular energy and are not geometry optimization. Standalone XYZ tools do not convert coordinate units; they have no unit metadata. Transformations change coordinate values, and written XYZ coordinates are rounded to six decimal places. Use the runfile’s units setting to tell a calculation how to interpret its coordinates.

For a TOML calculation, the geometry path is relative to the TOML file’s directory. init can create a TOML file that refers to an XYZ file without copying it:

cargo run --locked -- init samples/h2/molecule.xyz -o calculation.toml

Run commands from the repository root. The relevant executable checks are in tests/cli_samples.rs and tests/init_cli.rs. Geometry parsing and the transformations themselves are implemented in crates/rustiq-core/src/molecules/geometry.rs and src/cli/commands/geometry_command/.

Continue with basis sets, then configuration.

Gaussian basis sets

A basis set is a finite collection of functions used to represent molecular orbitals. RustiQ’s Gaussian basis functions are built from Gaussian functions centered on atoms. The chosen basis affects the size of the orbital space and the numerical result. A small basis such as STO-3G is useful for examples but does not guarantee accurate energies or properties.

Offline workflow

Import the checked-in STO-3G basis fixture into RustiQ’s local basis store and run the H₂ example:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.toml

The import is local and does not need network access. The test suite exercises the same fixture using an isolated store in tests/cli_samples.rs and basis import/storage behavior in crates/rustiq-core/src/basis/basis_store.rs.

List, import, or remove locally stored bases with:

cargo run --locked -- basis list
cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- basis remove sto-3g

The default store is in the platform’s application data directory. Set RUSTIQ_DATA_BASIS to choose its exact path, or RUSTIQ_DATA_HOME to choose the data root. The CLI guide in existing workflows lists platform paths and migration notes.

Online workflow

The default CLI build enables the online feature. Use it to list or download bases:

cargo run --locked -- basis list --online
cargo run --locked -- basis download sto-3g

Online commands require network access. A normal run uses the local basis store; automatic downloading can be enabled with --auto-download, disabled with --no-auto-download, or set using RUSTIQ_AUTO_DOWNLOAD. Builds without the online feature can import, list local files, and remove bases but cannot download or query online listings. The commands reflect the CLI tests in tests/cli_samples.rs.

Supported input features

Basis files are imported in the Basis Set Exchange JSON form. A shell groups functions with the same center and angular momentum: \(l=0,1,2\) denote s, p, and d functions. Cartesian and spherical describe two function forms that differ in how angular dependence is represented. For elements used by a molecule, the current loader accepts Gaussian-type and Cartesian Gaussian shells through angular momentum \(l=15\), and spherical Gaussian shells through \(l=2\). It rejects Slater-type shells and effective core potentials (ECPs). Higher angular momentum or other basis-file features should not be assumed to work just because a basis is downloadable. This describes loader support, not numerical validation of all those cases. The checks are in basis.rs.

Basis choice is one part of a calculation’s accuracy. Convergence, independent agreement, basis quality, and physical validity are distinct checks; see scientific scope. See the glossary for shared basis vocabulary.

Next: TOML configuration.

TOML calculation configuration

A TOML input describes one calculation. Begin with the checked-in neutral H₂ example:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf.guess]
type = "CoreHamiltonian"

From the repository root, import the basis if needed and run the input:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.toml

The [molecule] section points to an XYZ geometry and can set charge, multiplicity, and coordinate units. [basis] names a locally available basis. [method.hf] controls Hartree–Fock, and [method.mp2] requests a correlation calculation after HF. See the HF and MP2 guides for interpreting those methods.

For example, the existing MP2 sample adds an MP2 section:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf]
method = "Rhf"

[method.hf.guess]
type = "CoreHamiltonian"

[method.mp2]
frozen_orbitals = 0

Defaults such as neutral charge, Angstrom coordinates, automatic HF selection, 100 SCF iterations, and a \(10^{-8}\) convergence threshold are filled by the embedded Nickel contracts. The same contracts reject unknown fields and validate values; TOML parsing alone does not describe the full input rules. See the authoritative Nickel input contracts.

Important HF numerical controls include convergence_threshold, max_iterations, diis.enabled, diis.max_history, and orthogonalization.linear_dependency_threshold. MP2 has frozen_orbitals and memory_limit; the latter is a workspace budget, not a process memory limit. The defaults and detailed validation rules belong to the Nickel source, not a second specification in this guide.

Optional local AO ERI cache

The directory-backed AO ERI cache is local, disposable storage. It is disabled by default; enable it in the runfile to allow reuse across runs:

[cache]
enabled = true

--cache-dir DIR selects the directory for this run but does not enable the cache. The cache can be used as a fallback when a portable bundle has no compatible AO ERI; it is not itself a portable .rustiq bundle. See the portable bundle guide for that reuse order.

The geometry path is resolved relative to the TOML file. If the input is read from standard input, its geometry path is resolved from the current working directory. Geometry file structure and coordinate units are explained in the geometry guide.

The CLI reports diagnostics for malformed TOML, unknown or invalid fields, unavailable bases, and invalid molecular states. Tests cover valid examples and grouped diagnostics in tests/cli_samples.rs and tests/nickel_cli.rs. Successful validation means the requested input is internally acceptable; it does not validate the scientific choice of state or method. See the glossary for shared configuration and scientific terms.

Hartree–Fock calculations

Hartree–Fock (HF) is RustiQ’s reference method for its calculations. It approximates each electron as moving in an average field from the others. The result is found iteratively by updating the electron density and solving the effective one-electron equations until the density and energy are consistent.

RHF (restricted HF) uses shared spatial orbitals for paired alpha- and beta-spin electrons. It is appropriate for a closed-shell state. UHF (unrestricted HF) allows alpha and beta electrons to use different spatial orbitals, which supports open-shell states. UHF is more flexible but its wavefunction need not have a pure total spin.

Select a method and starting guess

With method = "Auto", RustiQ selects RHF for an even electron count and singlet multiplicity, and UHF otherwise. In Nickel/TOML values these methods are spelled "Rhf" and "Uhf". Explicit RHF requires an even-electron singlet; explicit UHF can also describe a singlet. This rule uses the requested charge and multiplicity; it is not a ground-state search. The user remains responsible for choosing the molecular state. Explicit Rhf or Uhf can also be requested when compatible with the electron count.

This checked-in open-shell OH example uses neutral charge and doublet multiplicity, so Auto resolves to UHF:

[basis]
name = "sto-3g"

[molecule]
geometry = "../oh.xyz"
charge = 0
multiplicity = 2

[method.hf]
method = "Auto"
convergence_threshold = 1e-5

[method.hf.guess]
type = "CoreHamiltonian"

[method.hf.diis]
enabled = true
max_history = 6

Run it after importing STO-3G:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/oh/sto-3g/calculation.toml

The open-shell CLI test and PySCF comparison are linked in scientific scope.

The checked-in H₂ input uses a core-Hamiltonian guess and resolves to RHF:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf.guess]
type = "CoreHamiltonian"

An initial density guess starts the self-consistent iterations. Available choices include core-Hamiltonian, one-electron, random, and zero guesses; the default is core-Hamiltonian. A guess affects the starting path, not the definition of the converged equations. Different guesses can lead to different solutions in difficult cases.

Iterations and convergence

SCF means self-consistent field, the repeated process of building a Fock matrix (the effective one-electron operator) from the current density matrix, solving for orbitals, then rebuilding the density. The atomic-orbital (AO) basis consists of functions centered on atoms; molecular orbitals are combinations of these functions. DIIS (direct inversion in the iterative subspace) can extrapolate Fock matrices from previous iterations to accelerate convergence. It is disabled by default; it changes the numerical route, not the HF model. The DIIS method is associated with Pulay’s extrapolation approach (Pulay, 1982).

The default maximum is 100 iterations. The default convergence_threshold is \(10^{-8}\). Both the absolute change in electronic energy between iterations and the Frobenius norm of the AO commutator residual must fall below this threshold. Its energy-change part is in Hartree. The residual is \(FPS-SPF\), where \(F\), \(P\), and \(S\) are the Fock, density, and overlap matrices; it measures inconsistency between the density and its Fock operator. The Frobenius norm is the square root of the sum of squared matrix entries. For UHF, alpha and beta (the two electron spin channels) residual norms are combined as \(\sqrt{r_\alpha^2+r_\beta^2}\). The threshold is applied to both diagnostics; it is not a bound on the final energy error.

The AO basis functions overlap. RustiQ diagonalizes their overlap matrix and discards directions whose eigenvalues are at or below the configured relative cutoff (default \(10^{-8}\) times the largest eigenvalue). The retained rank reports the effective dimension used by HF. Rank reduction can change results; inspect it when comparing calculations.

Read the result carefully

The electronic HF energy includes electronic kinetic, electron–nuclear, and electron–electron terms. Total HF energy adds nuclear repulsion. Energies are in Hartree; input Angstrom coordinates are converted to Bohr internally. Terminal energies are rounded for display. The H₂/STO-3G example is checked against a PySCF 2.14.0 reference in the project comparison suite with an absolute energy tolerance of \(2\times10^{-10}\) Hartree; the CLI test checks the rounded value. See reference comparison coverage and the output guide.

For UHF, the output includes \(\langle S^2\rangle\) and its deviation from the requested spin state’s ideal value. A nonzero deviation is called spin contamination. For a requested spin \(S=(M-1)/2\), where \(M\) is multiplicity, the ideal expectation is \(S(S+1)\) in units of \(\hbar^2\). For a doublet this is 0.75. Contamination is a diagnostic, not a correction and not proof that UHF found the right state. A converged SCF solution can still be a poor physical model or a local solution. HF uses one Slater determinant and omits electron correlation beyond exchange; small bases and strongly correlated systems need particular care. Read the scientific limitations before interpreting results. See the glossary for shared terms.

The SCF criteria, overlap rank, and spin diagnostics are implemented in scf.rs, orthogonalization.rs, and uhf.rs. The checked-in H₂ and OH CLI/reference cases provide reproducible examples.

Next: MP2.

MP2 calculations

Second-order Møller–Plesset perturbation theory (MP2) estimates an electron correlation correction using molecular orbitals from a converged HF reference. It does not replace HF: RustiQ first solves HF, then evaluates MP2. MP2 is available with both RHF and UHF references. An unconverged HF result cannot be used as an MP2 reference.

The checked-in H₂ input requests RHF-MP2 with no frozen orbitals:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf]
method = "Rhf"

[method.hf.guess]
type = "CoreHamiltonian"

[method.mp2]
frozen_orbitals = 0

Run it from the repository root after importing STO-3G:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/mp2_calculation.toml

The MP2 correlation energy is the correction added to HF electronic energy. Total MP2 energy is HF electronic energy plus MP2 correlation energy plus nuclear repulsion. The correlation energy is usually negative, but its sign and size depend on the system and reference.

Open-shell UHF-MP2 example

OH is an open-shell doublet (multiplicity 2). For this input, Auto selects UHF, and MP2 uses the converged UHF reference. The existing OH/STO-3G input is:

[basis]
name = "sto-3g"

[molecule]
geometry = "../oh.xyz"
charge = 0
multiplicity = 2

[method.hf]
method = "Auto"
convergence_threshold = 1e-10

[method.hf.guess]
type = "CoreHamiltonian"

[method.mp2]
frozen_orbitals = 0

[method.hf.diis]
enabled = true
max_history = 6

Run it from the repository root after making STO-3G available, as described in the basis-set guide:

cargo run --locked -- run samples/oh/sto-3g/mp2_calculation.toml

The calculation reports a UHF-MP2 correlation energy. Existing PySCF comparisons cover this specific example within the tolerances documented below; they do not establish general chemical accuracy.

Frozen occupied orbitals

Occupied orbitals contain electrons in the HF reference; virtual orbitals are unoccupied orbitals available as excitation destinations. The frozen_orbitals setting excludes the lowest occupied orbitals from the MP2 correlation treatment. Its default is zero, so all occupied orbitals are included. RHF requires at least one occupied orbital to remain correlated and at least one virtual orbital; the frozen count must be smaller than the occupied count. For UHF, the count cannot exceed either spin’s occupied-orbital count, though one spin sector may be fully frozen.

For RHF, the count refers to spatial orbitals; freezing one excludes one doubly occupied orbital. For UHF, the same count is applied separately to the alpha and beta occupied spaces. The excluded orbitals can have different spatial shapes. The setting does not choose chemically defined core orbitals automatically. Select it explicitly when comparing calculations.

Memory use

MP2 transforms integrals from the atomic-orbital basis into molecular-orbital blocks. RustiQ processes these blocks to avoid storing the full transformed four-index tensor at once. memory_limit configures the estimated additional workspace used for these transformations. "auto" selects a budget based on available memory; explicit byte sizes such as "500 MB" can also be set.

This workspace budget is not a limit on total process memory. It excludes already resident HF data and atomic-orbital integrals, allocator overhead, and other numerical-library scratch space. Even a single required block may exceed a very small budget. See the source for Mp2MemoryPlan and the authoritative Nickel defaults in the input contract.

For example, the existing Nickel default is auto. An explicit byte-size budget belongs under [method.mp2]:

[method.mp2]
memory_limit = "500 MB"

If the budget is below the minimum workspace needed for one occupied block, that sector cannot be transformed and the MP2 calculation errors. Automatic budget resolution follows the shared resource policy.

The H₂/STO-3G RHF-MP2 comparison checks the HF energy within \(2\times10^{-10}\) Hartree and MP2 correlation energy within \(10^{-10}\) Hartree against PySCF 2.14.0. The OH/STO-3G UHF-MP2 case checks HF energy within \(5\times10^{-8}\), correlation energy within \(5\times10^{-9}\) Hartree, and spin expectation within \(2\times10^{-5}\). These are agreement tolerances for those inputs, not a measure of general chemical accuracy. See the reference coverage and the reference test source. Reproduce both selected cases with:

nix run .#pyscf-check -- -k 'h2-sto-3g-rhf-mp2 or oh-sto-3g-uhf-mp2'

Small energy denominators can make MP2 corrections unreliable, especially in strongly correlated or near-degenerate systems. Numerical safeguards and agreement on a few examples do not establish physical validity. The method’s perturbative basis is described in Møller and Plesset (1934); see also this discussion of problematic MP2 denominators (Lee and Head-Gordon, 2018).

Nickel studies

Nickel is a configuration language that RustiQ embeds. A .ncl file can import other Nickel files and compute a list of related calculation records. The checked-in single-calculation .ncl input is a small starting point:

{
  molecule.geometry = "../molecule.xyz",
  basis.name = "sto-3g",
  method.hf = {},
}

Make sure STO-3G is in the local basis store, then run it with the same command as TOML:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.ncl

The checked-in H₂ study maps over two basis names to produce two inputs:

let bases = ["sto-3g", "6-31g"] in
std.array.map
  (fun basis_name => {
    molecule.geometry = "molecule.xyz",
    basis.name = basis_name,
    method.hf.diis = { enabled = true, max_history = 2 },
  })
  bases

This study is sequential. Run it from the repository root after making both bases available:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- basis import tests/data/reference/RustiQ/basis_sets/6-31g.json
cargo run --locked -- run samples/h2/study.ncl

When both calculations succeed, selected output excerpts are:

Calculation 1/2
Calculation 2/2
2 succeeded, 0 non-converged, 0 failed

The example runs two calculations sequentially, using STO-3G and 6-31G. Both must succeed for this success summary to appear. These are selected lines, not the complete terminal output.

The Nickel file uses molecule.geometry, basis.name, and an HF DIIS setting to create one calculation for each list item. Geometry paths resolve relative to the top-level .ncl file; Nickel imports resolve relative to the file that imports them. No external Nickel executable is needed.

TOML inputs describe one calculation. A .ncl file with one calculation behaves as a single calculation; an array with multiple entries produces a batch. This is useful for studies that vary inputs while keeping the remaining settings shared. Nickel is validated using the same authoritative input contracts as TOML; it does not define a second scientific configuration schema. The project integration test constructs a native import fixture and checks resolution from a different working directory; see tests/nickel_cli.rs. See configuration and the Nickel contract source.

RustiQ validates all study entries before it starts running them. Calculations then run in source order. A calculation that has a recoverable runtime error or does not converge is recorded for that entry, and later entries are still attempted. Fatal infrastructure errors stop the batch. The batch returns an unsuccessful process status if any entry fails or does not converge, while retaining per-calculation results. A configuration error prevents execution of the batch.

The integration coverage is in tests/nickel_cli.rs and tests/json_output_cli.rs. For structured outcomes, see JSON output. To save a study’s calculation entries and reusable AO ERIs in one portable bundle, see portable calculation bundles. See the glossary for Nickel and calculation terminology.

JSON output

Use JSON when another program needs calculation results. run writes only the machine-readable result to standard output:

cargo run --locked -- run samples/h2/sto-3g/calculation.toml --format json

Run commands from the repository root and make the named basis available first. To save machine-readable output, redirect standard output and disable color explicitly:

cargo run --locked -- run samples/h2/sto-3g/calculation.toml --format json --color never > result.json

For readable terminal inspection, add --pretty:

cargo run --locked -- run samples/h2/sto-3g/calculation.toml --format json --pretty

--pretty requires --format json. Compact JSON is unstyled; when saving pretty output for another tool, use --color never to disable syntax colors.

A TOML input produces one calculation result. A one-entry Nickel array also uses the single-result schema. A multi-entry Nickel study produces a batch document with one outcome per input, in source order. Each entry can be success, non_converged, or error. Later calculations continue after a recoverable per-calculation error, but fatal infrastructure errors stop the batch. Any recorded error or nonconvergence makes the overall command exit unsuccessfully. A valid JSON document can therefore accompany a failing exit status. For a batch, any entry error or non-convergence makes the command exit unsuccessfully while retaining the batch document. A single HF-only calculation that does not converge still produces the single result document with converged: false; its energy and diagnostics describe the final iterate, and the command exits successfully. If MP2 was requested, non-converged HF prevents MP2 execution and the run is reported as an error instead. Input, preparation, or runtime errors for a single calculation are reported as CLI diagnostics, so there is no single-result JSON document for that failed run. See the Nickel studies guide for batch outcomes.

Results include schema_version, which lets consuming software select the matching contract. The single-calculation contract is calculation-output-v1.schema.json; batch output uses batch-output-v1.schema.json. These versioned schemas are authoritative; this guide does not repeat their field definitions. See also the reference index.

When run uses --reuse or --artifact, calculation results add an optional artifacts field describing AO ERI selection and its origin. For example, a bundle hit appears as:

{
  "artifacts": [
    { "name": "ao_eri", "decision": "reused", "origin": "archive", "source_index": 0 }
  ]
}

decision describes whether the archive supplied a compatible AO ERI; origin identifies the archive, enabled local cache, or fresh computation that supplied the ERIs actually used. A bundle hit also includes its zero-based source_index. The field is omitted when neither option is used, and batch results report it on each calculation entry. See the portable bundle guide for the full workflow and the CLI reference for details.

Nickel batch JSON

The checked-in Nickel study runs two calculations. Follow that guide’s basis-set setup first, especially when running offline, then produce pretty JSON with colors disabled:

cargo run --locked -- run samples/h2/study.ncl --format json --pretty --color never

The output follows the versioned batch schema. Each successful calculation contains a result following the single-calculation schema linked above. Inspect the status of every calculation; a batch can include non-converged or failed entries even when it produces valid JSON. --color never prevents ANSI escape sequences in redirected output.

Energies are in Hartree. JSON preserves full floating-point values for comparison and downstream processing, while terminal tables round energies for readability. Do not compare a rounded terminal value against a tight numerical tolerance. Existing JSON CLI tests validate both schemas and full-precision H₂ output in tests/json_output_cli.rs. The checked-in reference tests compare JSON values against PySCF 2.14.0 for selected systems; see scientific scope. For terminology used in result fields, see the glossary.

Portable calculation bundles

A .rustiq bundle is a portable snapshot of RustiQ calculation inputs and optional reusable atomic-orbital electron-repulsion integrals (AO ERIs). It lets users rerun saved calculations or reuse compatible AO ERIs in new ones without carrying a machine-local cache. The bundle does not save a Hartree–Fock wavefunction or skip a new SCF run.

Create and inspect a bundle

Run the examples from the repository root. First make the checked-in STO-3G basis available, then run the H₂ sample and write a bundle to the current directory:

cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.toml --artifact h2.rustiq

Choose a destination that does not already exist. --artifact writes the current calculation collection as a new bundle, independently of text or JSON result output. For a Nickel study, the bundle contains one entry for each requested calculation.

Inspect a bundle without the original runfile, geometry file, or basis store:

cargo run --locked -- artifact inspect h2.rustiq
cargo run --locked -- artifact inspect h2.rustiq --format json

Inspection displays canonical requested and resolved calculation snapshots, producer information, artifact representations, and captured source names and sizes. Requested values may differ from resolved values: for example, an Auto HF method can resolve to RHF, and requested Angstrom coordinates appear as resolved Bohr coordinates. Text output syntax-highlights the canonical TOML and XYZ when color is enabled by --color or RUSTIQ_COLOR; use --color never for plain text. The optional JSON payloads_verified field is false: inspection validates the archive index, provenance, scientific snapshots and declared artifact sizes, but does not hash or decode numerical payloads. Use artifact verify to check supported payloads eagerly; otherwise, execution checks a payload when its scientific stage selects and reads it. Inspection is structural, not a calculation or an independent scientific validation.

Use artifact verify to eagerly read and validate every supported numerical payload in the bundle:

cargo run --locked -- artifact verify h2.rustiq

The command checks compact AO ERI payload hashes, NPY encoding, array dimensions, and consistency with the declared AO basis. It reports the number of verified payloads and calculations on standard output, and exits unsuccessfully if a payload is invalid or has an unsupported representation. A bundle with no numerical payloads can successfully report zero verified payloads. Verification does not execute the calculation or establish that the scientific method or result is valid. For the H₂ bundle created above, the output is:

Verified 1 payload(s) across 1 calculation(s).

Rerun a saved calculation

Run a .rustiq bundle directly to reconstruct and execute its archived calculation settings, without the original runfile, geometry file, or basis store:

cargo run --locked -- run h2.rustiq
cargo run --locked -- run h2.rustiq --format json --pretty --color never

For a multi-calculation bundle, RustiQ reruns every entry in manifest order and reports a batch, like a multi-entry Nickel study. This is a fresh calculation: RustiQ restores the resolved scientific inputs and reuses compatible AO ERIs when present; otherwise it recomputes them. A corrupt compatible AO ERI payload causes an execution error. It then runs HF again and MP2 again when requested. It does not restore orbitals, density matrices, DIIS history, or prior results, so this command does not resume an SCF trajectory. A saved random seed is restored as an input; it does not guarantee bitwise-identical results across software versions or platforms.

To use different settings, supply a TOML or Nickel input and use --reuse instead. A direct archive rerun cannot be combined with --reuse, --artifact, --cache-dir, --auto-download, or --no-auto-download. With --format json, the rerun uses the normal single-calculation or batch result schema and omits the artifacts reuse-decision array because the bundle is the implicit artifact source. The source bundle remains unchanged; direct reruns do not use the local AO ERI cache or download basis sets.

Reuse AO ERIs in a new calculation

This workflow needs a TOML or Nickel input, its geometry, and an available basis. --reuse does not run the calculation saved in the bundle or restore its captured source files. Instead, RustiQ prepares the supplied input, checks the bundle for compatible AO ERIs, and runs HF again; it also runs MP2 again if the new input requests MP2. The archive itself supplies reusable artifacts and remains read-only.

cargo run --locked -- run samples/h2/sto-3g/calculation.toml \
  --reuse h2.rustiq --format json --pretty --color never

When a runfile is executed with --reuse or --artifact, its JSON result includes an artifacts entry. A reused AO ERI is reported like this:

{
  "artifacts": [
    {
      "name": "ao_eri",
      "decision": "reused",
      "origin": "archive",
      "source_index": 0
    }
  ]
}

decision says whether the bundle supplied a compatible artifact; the CLI reports reused, missing, or incompatible. origin says where the ERIs actually came from: archive, an enabled local cache, or fresh computation. For example, decision: incompatible with origin: cache means no bundle entry matched but an enabled local cache supplied the ERIs. When an archive entry is selected, source_index is its zero-based position in that bundle. In a batch, each result reports its own selection.

The reuse order is:

  1. First compatible AO ERI in the archive’s manifest order.
  2. Matching entry in the enabled local AO ERI cache.
  3. Recompute the AO ERIs.

The local-cache step is used only when [cache].enabled = true in the runfile. --cache-dir selects the cache location but does not enable caching; see the configuration guide for the input setting.

The archive remains read-only during reuse. To publish a new snapshot from the calculation, provide a new destination:

cargo run --locked -- run samples/h2/sto-3g/calculation.toml \
  --reuse h2.rustiq --artifact h2-updated.rustiq

What can be reused?

AO ERIs are reusable when the effective integral inputs match. RustiQ checks the ordered atomic numbers and nuclear coordinates in Bohr, effective AO basis functions, Schwarz screening setting, and integral representation and computation versions. A matching basis-set label or atom count alone is not enough. HF method and convergence settings, and whether MP2 is requested, do not change AO ERI compatibility. The persistence specification defines the complete identity.

Change to the new inputAO ERI compatibility
HF method, initial guess, or SCF convergence limitCan remain compatible; HF runs again with the new settings.
Add or change MP2 settingsCan remain compatible; MP2 runs again from the new HF result.
Geometry, effective AO basis, or Schwarz screeningIncompatible; RustiQ checks the local cache, then recomputes if needed.

The bundle stores scientific input snapshots and optional AO ERIs. It does not store HF energies, convergence status, orbitals, density matrices, DIIS history, or MP2 results. Save the result JSON separately when those outputs matter. Captured input and geometry bytes are provenance for inspection; they do not affect compatibility, and Nickel imports are not captured recursively. The same reconstruction is available to Rust callers; see the Rust API examples in the persistence specification.

Publication and failures

--artifact publishes the current requested collection; it does not append to the source bundle. A new destination must not exist. An existing destination is accepted only when it resolves to the explicit --reuse source, in which case RustiQ replaces that bundle after producing a complete validated snapshot. Other existing destinations are left untouched.

Run outcomeBundle behavior
Every requested calculation produces a resultPublish the current collection.
A preparation or execution error occursDo not publish; preserve any prior destination.
HF-only run reaches its iteration limitIts result can still publish the AO ERIs. A single HF run exits successfully; a batch with non-converged results and no execution errors publishes, then exits unsuccessfully.
MP2 was requested but HF did not convergeMP2 execution fails, so the collection is not published.

JSON for a completed calculation or batch may already have been written when a later publication error is reported. See the CLI reference for exact exit and publication behavior and the persistence V1 specification for the archive contract and the EZFIO comparison.

Scientific scope and limitations

RustiQ is experimental software for molecular electronic energies at a fixed geometry. A successful run or reference comparison does not establish research-grade correctness. Independently validate the method, basis, molecular state, convergence, and quantities relevant to your research against established packages before drawing chemical conclusions.

Implemented scope

Hartree–Fock (HF) is available as restricted HF (RHF) for closed shells and unrestricted HF (UHF) with separate alpha and beta orbitals for open shells. Automatic selection resolves the method from the molecular state. DIIS accelerates the iterative SCF solution; core-Hamiltonian and randomized density guesses are available. MP2 adds a correlation correction to converged RHF or UHF orbitals, with optional frozen occupied orbitals and a blocked transformation governed by a workspace budget.

Calculations use XYZ geometries with Angstrom or Bohr input, charge and spin multiplicity, Gaussian basis functions, one-electron integrals, and compact stored electron-repulsion integrals (ERIs). Schwarz screening can skip small ERIs, and overlap orthogonalization removes near-dependent directions according to a configured threshold. These thresholds can affect energies and convergence; convergence alone does not establish their suitability for a particular system. Increasing integrals.schwarz_threshold skips more small integrals at a potential accuracy cost; setting it to zero disables Schwarz screening. The authoritative default is in the Nickel schema.

Gaussian Cartesian and spherical functions are implemented, including spherical d functions. Spherical angular momentum above d and effective core potentials (ECPs) are rejected by the current basis loader. The relevant implementation is linked below for inspection.

Basis loader source on GitHub Downloading a basis file does not guarantee that its contents are supported or numerically validated. Geometry inspection and coordinate transformations are available; these operations do not optimize the geometry’s energy. See the glossary for terminology and the workflow notes for preserved usage guidance.

Reference comparisons

The book’s first H₂ calculation provides a reproducible entry point to independent PySCF comparisons with explicit tolerances. The comparison instructions and case definitions are linked below. They cover H₂ and water in STO-3G, 6-31G, and cc-pVDZ, open-shell H₂⁺ and OH, and selected RHF/UHF MP2 cases. Additional cases exercise frozen occupied orbitals and small versus larger MP2 workspace budgets. For OH/STO-3G, the UHF-only sample uses a numerical SCF threshold of 1e-5 in both RustiQ and PySCF, while the UHF-MP2 sample uses 1e-10 in both. Matching the numerical thresholds does not make the two codes’ SCF stopping criteria identical: RustiQ checks an energy change and an AO commutator residual, while PySCF uses its own convergence tests. Compare converged energies and spin diagnostics rather than assuming equivalent accuracy from a matching input number. The first H₂ calculation identifies its CLI test and full-precision independent comparison.

This is a useful, limited reference suite. Its tolerances are case-specific; the H₂/STO-3G tolerance is not a universal accuracy guarantee. It does not systematically span elements, contraction conventions, angular momenta, charges, spin states, difficult SCF solutions, or large systems. Agreement in selected energies can leave errors in untested quantities or shared assumptions undetected. It also does not prove basis completeness, adequacy of HF/MP2 for a chemical problem, or agreement with experiment. UHF spin contamination is an additional physical concern even for converged solutions.

Physical limits of HF and MP2

HF represents the state with a single Slater determinant and omits electron correlation beyond exchange. Convergence establishes a self-consistent solution within the selected orbital space; it does not establish that the solution is the lowest-energy HF state. Different initial guesses can find different solutions. UHF can lower its energy by breaking spin symmetry, so inspect \(\langle S^2\rangle\) and spin contamination as well as the energy.

Bond stretching, dissociation, and near-degenerate states can require several important electronic configurations. A converged single-determinant reference can then be physically inadequate. MP2 is a perturbative correction to that reference, not a general remedy for strong correlation. Its energy terms contain denominators \(\epsilon_i + \epsilon_j - \epsilon_a - \epsilon_b\), with occupied indices \(i,j\) and virtual indices \(a,b\). Small denominators can produce excessively large corrections. Lee and Head-Gordon discuss these denominator problems and bond-breaking examples in their study of regularized MP2.

RustiQ rejects non-finite denominators and absolute denominator values at or below 1e-12 Hartree. This numerical guard is not a physical suitability test: passing it does not establish that the perturbation expansion is reliable. Agreement with another HF/MP2 implementation tests numerical consistency under matched conventions; judging a chemical prediction also requires an appropriate method, basis, and molecular state.

Major limitations

The current calculation methods do not provide DFT, analytic gradients, geometry optimization, vibrational frequencies, or post-HF methods beyond MP2. The molecular input workflow uses XYZ rather than a broad set of chemistry formats. General research use needs broader independent numerical validation, scientific convention documentation, and performance evidence.

Memory management and screening already exist, but compact ERI storage can still grow rapidly with basis size. The MP2 workspace budget is not a bound on total process memory. Larger checked-in molecules are examples, not evidence of robust or competitive performance at scale.

The authoritative references page links to the roadmap and issues, which own future plans. Detailed method derivations and broader validation methodology belong to later scientific documentation; this page describes current boundaries.

Reference comparison instructions on GitHub

Reference case definitions on GitHub

Project roadmap on GitHub

Glossary

This short glossary connects the scientific and software vocabulary used in this manual. It is an orientation aid; method definitions and API contracts remain in their authoritative references.

TermMeaning in this manual
AO / MOAtomic orbital / molecular orbital. Basis functions centered on atoms represent the molecular orbitals used by HF and MP2.
Basis setA finite collection of functions used to represent electronic orbitals. STO-3G is a small basis suitable for the first example, not a general accuracy guarantee.
Bohr / AngstromLength units. Bohr is the atomic unit of length; Angstrom is commonly used for molecular coordinates. RustiQ converts input coordinates to Bohr for calculations.
HartreeThe atomic unit of energy used in RustiQ’s reported energies.
HF / RHF / UHFHartree–Fock / restricted HF / unrestricted HF. RHF pairs electrons in shared spatial orbitals; UHF permits different spatial orbitals for alpha and beta spins.
SCFSelf-consistent field: the iterative procedure for solving the HF equations. Meeting its convergence criterion does not prove chemical accuracy.
DIISDirect inversion in the iterative subspace: an acceleration technique for SCF iterations.
MP2Second-order Møller–Plesset perturbation theory: a correlation correction built from an HF reference.
Multiplicity2S + 1 for spin quantum number S. Singlet and doublet mean multiplicities one and two. Charge and multiplicity specify the intended molecular state.
Spin contaminationDeviation of UHF’s spin expectation value from the value for the intended pure spin state.
ERIElectron-repulsion integral: a contribution describing the Coulomb interaction between electrons in the chosen basis.
AO ERIAtomic-orbital electron-repulsion integral. RustiQ’s optional local cache stores these deterministic integrals, not HF or MP2 results.
OrthogonalizationConstruction of an orthonormal orbital space from overlapping basis functions. Near-dependent directions may be removed.
Frozen orbitalsOccupied orbitals excluded from the MP2 correlation calculation.
ECPEffective core potential: a model replacing core electrons and their nuclear interaction; currently unsupported by RustiQ’s basis loader.
Rust / CargoRust is the implementation language; Cargo builds Rust packages and runs their tests and examples. Users can run an installed CLI without writing Rust.
Crate / workspaceA Rust package’s library or executable unit / a group of packages built together. RustiQ separates its CLI and scientific library.
CLI / APICommand-line interface for terminal users / application programming interface for code using the library.
rustdoc / mdBookRust’s API documentation generator / the tool that builds this user and developer manual.
TOML / NickelCalculation input languages. TOML provides declarative settings; Nickel also supports imports and computed studies and owns input defaults and validation.
JSON / schemaA structured data format / the contract describing valid data. Existing versioned schemas define RustiQ’s machine-readable results.
Nix / flakeA tool for reproducible packages and environments / this repository’s project definition, with dependencies locked by flake.lock. Nix does not require NixOS.
Dev ContainerA prepared Linux development environment running through Docker, with editor integration.
Cache / portable artifactDisposable local data used to avoid repeated work / an intentional scientific snapshot. .rustiq bundles can be written, reused, and inspected through the CLI or Rust APIs.
Validation / toleranceComparison against independent evidence / the allowed difference in a particular numerical check. Passing selected checks does not validate every calculation.
Contracted GaussianA basis function formed by a weighted sum of primitive Gaussian functions that share a center and angular momentum.
Primitive GaussianA Gaussian function used as a component of a contracted basis function.
Occupied / virtual orbitalAn orbital assigned electrons in the reference determinant / an unoccupied orbital available as an excitation destination.
Fock matrixThe effective one-electron matrix built from the current electron density in Hartree–Fock.
Density matrixA matrix encoding which molecular orbitals are occupied and their contributions in the atomic-orbital basis.
Overlap matrixThe matrix of pairwise integrals between basis functions; its off-diagonal values reflect that these functions need not be orthogonal.
Cartesian / spherical GaussianTwo ways to represent the angular part of Gaussian basis functions. Their function counts differ for d and higher angular momentum.
Correlation energyThe energy correction beyond the chosen HF reference; RustiQ reports MP2 correlation separately from the HF and total energies.
Linear dependenceNear-redundancy among basis functions, which can make the overlap matrix numerically singular. RustiQ may discard the affected directions.

Command-line reference

Run these commands from any working directory with the installed rustiq binary. From the repository root in a source checkout, replace rustiq with cargo run --locked --. rustiq --help and rustiq <command> --help show the options supported by the installed build.

Commands

CommandPurpose
rustiq init <XYZ>Create a TOML calculation input that refers to an XYZ geometry.
rustiq run [INPUT]Run TOML or Nickel input, or rerun calculations from a .rustiq bundle. With no path, read TOML from standard input. Multi-entry inputs run as batches.
rustiq basis import <PATH>...Import basis JSON files into the local basis store.
rustiq basis list [--online] [--verbose]List locally stored bases; online listing is available in builds with the online feature.
rustiq basis download <NAME>Download a basis in builds with the online feature.
rustiq basis remove <NAME>... / --allRemove selected bases or the local basis store contents.
rustiq cache list [--cache-dir DIR]Inspect AO ERI cache entries and their validation status.
rustiq cache remove <NAME-OR-FINGERPRINT> [--cache-dir DIR] / --allRemove selected or all AO ERI cache entries.
rustiq artifact inspect <PATH> [--format FORMAT]Inspect portable .rustiq calculation snapshots and artifact metadata.
rustiq artifact verify <PATH>Check hashes and decode supported numerical payloads in a portable .rustiq bundle.
rustiq geometry info [XYZ]Print basic geometry information; read XYZ from standard input when no path is given.
rustiq geometry rotate, translate, center, oriente, isometryTransform a geometry and write the result; each subcommand has its own help.

The geometry tools and basis storage are utilities around a calculation; they do not create a .rustiq portable artifact. See the geometry guide and existing workflows for examples of geometry, init, and basis management commands.

init options include --output (calculation.toml by default), --force, --basis (sto-3g), --charge (zero), --multiplicity, --units (angstrom by default, or bohr), --hf (auto, rhf, or uhf), and --mp2. Without an explicit multiplicity, it selects singlet for an even electron count and doublet for an odd count. This is a starting convention; choose the physical state appropriate to the molecule. The existing workflows documents path and overwrite behavior.

run options and input selection

The input filename extension selects TOML, Nickel (.ncl), or a portable .rustiq bundle. TOML describes a single calculation. Nickel can describe one calculation or an ordered array; an array of one uses the single-calculation output contract, while a larger array uses the batch contract. A .rustiq input reconstructs and reruns its archived resolved calculation(s); multi-entry bundles use the batch contract. Nickel imports resolve relative to the importing file. Geometry paths resolve relative to the top-level input file; for TOML read from standard input, they resolve from the current working directory. Direct archive reruns cannot be combined with --reuse, --artifact, --cache-dir, --auto-download, or --no-auto-download; the source bundle is read-only and provides its resolved basis and inputs. Archive reruns do not use the local ERI cache or basis-download settings. Text output shows SCF progress; JSON output suppresses progress and writes only the result document.

Important options:

OptionBehavior
--format FORMAT (text or json)Select text output (default) or versioned JSON. JSON result data is written to standard output.
--prettyPretty-print single-calculation or batch JSON, optionally with syntax highlighting. Requires --format json.
--color MODE (auto, always, or never)Control ANSI colors globally; also accepts RUSTIQ_COLOR. Use --color never when redirecting pretty JSON.
--auto-download / --no-auto-downloadIn online builds, allow or disable fetching a missing basis for this run. These override RUSTIQ_AUTO_DOWNLOAD; without either flag, 1 or true (case-insensitive) enables it and other or missing values disable it. Offline builds always use local bases.
--cache-dir DIRChoose the AO ERI cache root for this run. The input must also set [cache].enabled = true; this option does not enable caching.
--reuse PATHRead a portable .rustiq bundle and reuse the first compatible AO ERI for each calculation.
--artifact PATHWrite the current calculation or batch as a portable .rustiq bundle, independently of text or JSON output.

The cache directory path is resolved from the caller’s current working directory. Pass the same --cache-dir to cache list or cache remove to manage entries from a run that used a custom cache root.

The CLI reports input, basis, preparation, and single-run calculation errors as diagnostics. A single HF calculation that reaches its iteration limit returns its final-iteration result with a successful process status and, in JSON, converged: false. MP2 requires converged HF. For a multi-calculation Nickel or .rustiq batch, recoverable per-entry errors do not prevent later entries from running; the JSON document records each outcome, but any error or non-convergence makes the overall process exit unsuccessfully. Fatal infrastructure failures stop the batch. JSON output for an unsuccessful batch is still a valid document. The exact output fields are defined by the versioned schemas; see the JSON guide for examples and interpretation. For a single calculation, an input, preparation, or runtime failure is reported as a diagnostic and does not produce result JSON. A non-converged single HF run is a result, not a runtime failure.

Feature availability

CapabilityAvailable behavior
TOMLOne calculation per input; see the checked-in H₂ input.
NickelOne calculation or an ordered study/batch; see the checked-in study example.
JSONVersioned single-calculation and batch results, selected with run --format json; schemas are linked below.
AO ERI cacheOptional local reuse through [cache].enabled and --cache-dir; entries can be listed or removed. AO ERI means atomic-orbital electron-repulsion integral.
Portable .rustiq bundleCreate with run --artifact, rerun with run FILE.rustiq, reuse artifacts with run INPUT --reuse FILE.rustiq, inspect with artifact inspect, and validate stored AO ERIs with artifact verify. Reruns start a fresh HF calculation. See the portable bundle guide.
Scientific statusExperimental; selected checks do not establish research-grade correctness. See scientific scope and limitations.

Basis downloads and online basis listing require a build with the online feature. The standard CLI enables it; offline builds provide import, local listing, and removal. Geometry transformations are CLI utilities, not calculation input transformations unless their output file is then used as an input.

From the repository root, import the checked-in STO-3G and 6-31G basis fixtures before running these examples:

cargo run --locked -- basis import tests/data/sto-3g.json tests/data/reference/RustiQ/basis_sets/6-31g.json
cargo run --locked -- run samples/h2/sto-3g/calculation.toml
cargo run --locked -- run samples/h2/study.ncl --format json --pretty --color never
cargo run --locked -- run samples/h2/sto-3g/calculation-cache.toml --cache-dir ./rustiq-cache
cargo run --locked -- cache list --cache-dir ./rustiq-cache

The Nickel study uses both STO-3G and 6-31G; importing only STO-3G is insufficient unless basis auto-download is enabled in an online build. The TOML and cache examples require only STO-3G. See the Nickel studies guide for the individual import commands. The relative ./rustiq-cache directory is resolved from the caller’s working directory on Windows, Linux, and macOS.

The H₂ TOML and Nickel examples are exercised by tests/cli_samples.rs, tests/nickel_cli.rs, and tests/json_output_cli.rs. The JSON tests also check pretty-printing of Nickel batches. The cache-enabled input is samples/h2/sto-3g/calculation-cache.toml; its store-then-hit behavior is covered by test_cli_h2_sample_uses_eri_cache_when_enabled_in_runfile in tests/cli_samples.rs, in addition to the Rust core persistence tests.

Calculation input contracts

TOML and Nickel inputs use the same calculation settings. The embedded Nickel contracts are authoritative for defaults, allowed fields, types, and validation; the CLI does not define a separate TOML-only set of defaults. Consult the TOML guide for sections and checked-in examples, then the geometry, Hartree–Fock, and MP2 guides for the corresponding scientific settings. The Nickel contracts and their validation are linked from the reference index.

The following settings are accepted by both TOML and Nickel. This is a navigation aid, not a second schema: exact defaults, value constraints, and cross-field validation remain defined by the linked Nickel contract.

SectionSupported settings
[molecule]geometry, charge, multiplicity, units (Angstrom or Bohr)
[basis]name
[method.hf]method (Auto, Rhf, Uhf), max_iterations, convergence_threshold, guess, diis.enabled, diis.max_history, orthogonalization.linear_dependency_threshold
[method.mp2]frozen_orbitals, memory_limit
[integrals]schwarz_threshold for integral screening
[cache]enabled for the disposable local AO ERI cache
[output]scf (Normal or Quiet)

The accepted density guesses and their fields are defined in the Nickel contract; see the HF guide for their use. The cache stores AO ERI data only; it does not store Hartree–Fock or MP2 results, and a cache hit does not guarantee that every calculation will run faster.

Cache and portable bundles

The local AO ERI cache (atomic-orbital electron-repulsion integrals) is a disposable optimization for deterministic two-electron integrals. It is disabled by default in the calculation input; --cache-dir only selects where enabled cache entries are stored. Use cache list and cache remove to inspect or remove entries. Missing, invalid, or incompatible entries are recomputed. The local cache is not a deliverable or a portable calculation file.

Portable .rustiq bundles use the V1 ZIP/ZIP64 format described by the authoritative persistence specification. The format is conceptually inspired by EZFIO in Quantum Package 2 (qp2), but uses an independent archive structure and APIs; see the comparison. For a guided create, inspect, and reuse workflow, see the portable bundle guide. Bundles are separate from the disposable local AO ERI cache. Reuse opens its source read-only. For each requested calculation, RustiQ selects the first compatible, supported AO ERI in bundle order; when none is available, an enabled local cache is checked before recomputation. A corrupt selected payload is an error. A source entry can supply data to multiple calculations in a Nickel batch.

cargo run --locked -- run samples/h2/sto-3g/calculation.toml --artifact h2.rustiq
cargo run --locked -- run samples/h2/sto-3g/calculation.toml --reuse h2.rustiq --artifact next.rustiq --format json
cargo run --locked -- artifact inspect h2.rustiq --format json
cargo run --locked -- artifact verify h2.rustiq
cargo run --locked -- run h2.rustiq
# Replace the source bundle after all requested calculations produce results:
cargo run --locked -- run samples/h2/sto-3g/calculation.toml --reuse h2.rustiq --artifact h2.rustiq

Publication captures the current requested calculation collection and its compatible known artifacts. It does not append history. An existing destination is accepted only when it resolves to the explicit --reuse source; otherwise the command fails without replacing it. Publication happens after every requested calculation produces a result. Preparation or execution errors prevent publication of the collection and leave the destination unchanged. An HF-only non-converged result can contribute its AO ERI. A Nickel batch containing only non-converged HF-only results can publish its bundle even though the command exits unsuccessfully. If MP2 was requested but HF does not converge, execution fails and the bundle is not published. HF orbitals, SCF restart state, DIIS history, and MP2 results are not persisted.

When --reuse or --artifact is used, JSON calculation results include an optional artifacts array. decision reports archive selection (reused, missing, or incompatible); origin reports the ERI actually used (archive, cache, or computation). A reused item includes its zero-based source_index. Without these options the existing JSON result shape is retained. run FILE.rustiq --format json uses the regular single-calculation or batch result schema but does not include this reuse-decision array: the bundle is the implicit artifact source for that mode. Publication failures are reported on stderr and return a failing exit status; JSON results for a completed calculation or batch may already have been written.

artifact inspect PATH displays requested and resolved scientific snapshots, producer details, artifact representations, and captured source names and sizes. In text mode, canonical TOML and XYZ are syntax-highlighted when color is enabled by --color or RUSTIQ_COLOR; JSON output remains structured JSON. It validates the archive index, provenance, snapshots, and declared artifact sizes, but does not hash or decode numeric payloads. Use artifact verify to check supported payloads eagerly; otherwise, execution checks a payload when its scientific stage selects and reads it. Inspection does not execute calculations or establish scientific validity. JSON output follows the artifact inspection V1 schema. artifact verify PATH eagerly reads and validates supported numerical payloads. It currently checks compact AO ERI payload hashes, NPY encoding, array dimensions, and consistency with the declared AO basis. It reports an error for an invalid payload or unsupported representation. Verification does not run a calculation or establish scientific validity. The archive captures exact bytes of the main input and geometry files as shared provenance; it does not capture Nickel’s full import graph. See the persistence specification for the archive contract and API details.

Output contracts

run --format json selects one of two versioned contracts: the single calculation schema or the batch schema. schema_version identifies the contract; schemas, rather than this manual, define the complete field sets. The JSON guide describes output selection, standard output behavior, failure cases, and the existing automated checks.

Existing calculation workflows

For a concise catalog of shipped commands, input settings, JSON behavior, and feature availability, see the command-line reference. This page keeps the longer workflow examples.

This page preserves operational details from the former README. For the progressive workflows, start with the geometry, basis set, configuration, Nickel, MP2, and JSON guides. Commands below run from the repository root; Cargo builds and launches the CLI. The Cargo package is rustiq-chem, and the installed executable is rustiq. Replace cargo run --locked -- with rustiq to use the installed binary. See the glossary for scientific and development terms.

Create input from an XYZ geometry

cargo run --locked -- init samples/h2/molecule.xyz -o calculation.toml
cargo run --locked -- init samples/h2/molecule.xyz --hf uhf --multiplicity 3 --mp2 -o triplet.toml

init references the geometry; it does not copy it. The output defaults to calculation.toml in the current directory. Its parent directory must exist. Use --force to replace an existing regular file; the source geometry, directories, and symbolic links are protected from replacement.

Defaults are STO-3G, neutral charge, Angstrom coordinates, and automatic HF selection. Without --multiplicity, the electron count (including charge) selects a singlet for an even count and a doublet for an odd count. This is a starting convention, not a prediction of the ground state. Specify the physical state yourself. --hf accepts auto, rhf, or uhf; --units accepts angstrom or bohr. Incompatible molecular states are rejected. --basis and --charge select another basis and charge. --mp2 adds MP2 with no frozen orbitals. Default-valued settings are omitted from generated TOML and restored by the authoritative Nickel configuration.

Initialization needs neither a cached basis nor network access. Running the calculation checks basis availability and numerical requirements. tests/init_cli.rs checks that generated HF and MP2 inputs run; unit tests in init_command.rs check options, paths, defaults, and overwrite protection.

Geometry paths resolve from the top-level calculation file’s directory, including geometry values supplied by Nickel imports. Nickel imports themselves resolve from the importing file. With no input filename, run reads TOML from standard input and resolves geometry from the caller’s current directory. CLI paths such as --cache-dir also resolve from the caller’s directory.

Basis management and storage

A basis set supplies the functions used to represent electronic orbitals. Import the checked-in fixture for the first calculation, or manage the local store with:

cargo run --locked -- basis list
cargo run --locked -- basis import tests/data/sto-3g.json
cargo run --locked -- basis list --online
cargo run --locked -- basis download sto-3g
cargo run --locked -- basis remove sto-3g

Online listing and download require the online Cargo feature, enabled by default for the CLI. Offline builds retain import, local listing, and removal. run --auto-download permits downloading a missing basis; --no-auto-download disables it. These flags override RUSTIQ_AUTO_DOWNLOAD, which enables downloading for 1 or true (case-insensitive); otherwise it is disabled. Import and store behavior are tested in basis_store.rs.

The CLI uses the platform’s local application data directory, then appends basis_sets:

PlatformDefault basis directory
Linux~/.local/share/rustiq/basis_sets
Windows%LOCALAPPDATA%\rustiq\data\basis_sets
macOS~/Library/Application Support/rustiq/basis_sets

An absolute XDG_DATA_HOME replaces ~/.local/share on Linux. RUSTIQ_DATA_BASIS overrides the entire basis directory and takes precedence over RUSTIQ_DATA_HOME, which selects <root>/rustiq/basis_sets. Prefer absolute paths for these overrides. If the platform directory cannot be determined, the fallback is <system temporary directory>/rustiq/basis_sets; the operating system may remove its contents.

Older alpha installations used ~/.local/share/RustiQ/basis_sets on Linux, %LOCALAPPDATA%\RustiQ\basis_sets on Windows, and ~/Library/Application Support/RustiQ/basis_sets on macOS. There is no automatic migration or lookup there. Copy existing bases to the current location or set RUSTIQ_DATA_BASIS to the old directory. The policy and override tests live in directories.rs. The basis store is separate from the disposable integral cache and portable scientific bundles described under authoritative references.

JSON results and Nickel studies

cargo run --locked -- run samples/h2/sto-3g/calculation.toml --format json
cargo run --locked -- run samples/h2/sto-3g/calculation.ncl
cargo run --locked -- run samples/h2/study.ncl --format json

The study runs STO-3G and 6-31G calculations sequentially. Import both fixtures from tests/data/reference/RustiQ/basis_sets/, or permit automatic download. The input extension selects TOML or Nickel; no external Nickel executable is needed. TOML and init describe single calculations.

JSON is suitable for automated analysis because energies retain floating-point precision rather than terminal display rounding. Use the existing single and batch schemas as the field contracts; check schema_version. UHF results include spin expectation and contamination relative to the requested spin state; RHF results omit that spin object. Unconverged results describe the final iteration, not a converged wavefunction.

One calculation, including an array of length one, produces the single-result contract. Larger arrays produce the batch contract in source order, with success, non_converged, or error outcomes. Configuration is validated before execution. Runtime calculation failures allow later entries to run; any failure or nonconvergence makes the batch exit unsuccessfully while its JSON remains a complete document. Empty arrays are rejected.

Compact JSON has no ANSI styling even with forced color. --pretty requires --format json and can add syntax highlighting when colors are enabled; use --color never when saving pretty JSON for another program. JSON tests and Nickel tests verify these contracts and study execution.

MP2 and its memory budget

MP2 estimates a correlation correction using converged HF orbitals; RustiQ supports both RHF and UHF references. It refuses MP2 on unconverged HF. The existing H₂ input is:

[basis]
name = "sto-3g"

[molecule]
geometry = "../molecule.xyz"

[method.hf]
method = "Rhf"

[method.hf.guess]
type = "CoreHamiltonian"

[method.mp2]
frozen_orbitals = 0

After importing STO-3G, run:

cargo run --locked -- run samples/h2/sto-3g/mp2_calculation.toml

frozen_orbitals excludes the lowest occupied orbitals from correlation; zero correlates all occupied orbitals. For RHF, it counts spatial orbitals: frozen_orbitals = 1 freezes one doubly occupied orbital (two electrons). For UHF, the same count applies separately to the alpha and beta occupied spaces: 1 freezes the lowest occupied alpha orbital and the lowest occupied beta orbital, also excluding two electrons. These spin orbitals can have different spatial shapes. The CLI option does not specify separate spin counts or arbitrary orbital indices.

RHF requires the count to be smaller than the occupied-orbital count. UHF requires it not to exceed either spin’s occupied count; a spin channel may have no active occupied orbitals left. Choose the frozen space explicitly when comparing packages. Defaults and input validation belong to Nickel; the core also checks the reference-specific orbital partition during MP2. The PySCF comparisons include RHF/UHF MP2, frozen orbitals, and different workspace budgets.

memory_limit = "auto" resolves once before MP2 to half the available memory. On Linux, the process’s cgroup free-memory limit caps the host value when available. If memory information is unavailable, the fallback is 512 MiB. Explicit sizes such as "500 MB" (decimal units) and "1.5 GiB" (binary units) are accepted. The budget covers additional matrix payloads for the blocked transformation from atomic to molecular orbitals, including panels and coefficient copies. HF data and compact atomic-orbital integrals are separate. It does not cap total process memory, allocator overhead, or matrix-kernel scratch storage. A budget too small for one occupied block fails before the transformation buffers are allocated. The text report shows block size and workspace estimates. See the tested resource policy and blocked implementation.

Terminal colors

--color and RUSTIQ_COLOR accept auto, always, and never, in order of precedence: CLI flag, environment setting, automatic detection. In automatic mode, NO_COLOR disables styling; otherwise terminal detection is independent for standard output (reports) and standard error (diagnostics and progress). Explicit always or never overrides NO_COLOR.

cargo run --locked -- --color never run samples/h2/sto-3g/calculation.toml

Windows output uses adaptive terminal support, including legacy consoles. The implementation and focused checks are in color.rs and the JSON integration tests. See the JSON section above for pretty output.

Authoritative references

These documents remain the sources of truth:

The directory-backed local AO ERI cache is disposable, machine-local storage. A portable .rustiq bundle is a deliberate scientific snapshot accessed by the CLI and Rust APIs. A cache directory is not a portable bundle.

Development environments

Choose an environment according to the operating system on which you want RustiQ to run, the tools you want prepared, and your compute site’s policies. Docker is an optional development convenience; it is not a universal recommendation for scientific calculations.

SetupWhere Rust and RustiQ runAdvantagesLimitations
Docker / Dev ContainerLinux inside a container on every hostPrepared workspace and VS Code integrationLinux target only; Desktop uses a VM; resource and file-sharing settings need attention
NixNative Linux or Apple Silicon macOS; Linux in WSL2 on WindowsPinned tools without requiring DockerLimited flake platforms; store and installation requirements; WSL2 uses a VM
Manual / CargoNative Linux, macOS, or WindowsDirect host execution and control over installed toolsNative dependencies and optional scientific tools must be installed separately

For native execution on Windows or Intel macOS, choose manual installation. On Linux or Apple Silicon macOS, Nix prepares tools while retaining native execution. Choose Docker when a shared Linux development workspace is useful and its host integration suits your needs.

For HPC workloads, consider the compute node’s operating system, available memory and CPUs, filesystem, and scheduler policies. A native setup avoids adding a VM on Windows or macOS; Docker Engine directly on Linux shares the host kernel. These distinctions do not establish a performance ranking: measure representative calculations with release builds on the intended execution environment. The Docker page explains resource limits and platform boundaries in more detail.

Each setup page contains its prerequisites, commands, advantages, and limits. See known supported platforms for compatibility evidence and Nix packages and shells for the pinned tool inventory.

Terms used in the setup guides

A host is the machine running your environment. A container isolates processes and their installed tools while using a Linux kernel. A virtual machine (VM) runs a guest operating system with its own kernel. WSL2 runs Linux in a VM on Windows. A terminal lets you type commands; a shell interprets them. A Nix development shell makes selected tools available in that session. Cargo builds Rust programs, and rustup installs Rust toolchains.

Docker and VS Code Dev Container

Visual Studio Code (usually called VS Code) is a free application for editing and managing software projects. You can think of it as a text editor with a project file browser, a built-in terminal, and optional extensions that add features such as Rust error highlighting, debugging, or Nickel support. For this project, it gives you one place to edit files, run commands, and see errors.

A Dev Container is a prepared Linux environment for the project. VS Code shows the files and editor on your computer, while Rust, Nix, and the other development tools run inside the container. This avoids installing and configuring those tools individually on your computer. The repository includes the container configuration, so contributors can use the same setup.

Choose this setup when you want a prepared Linux workspace with VS Code integration. Compare it with native Nix and manual installation before choosing a calculation environment.

Advantages and limitations for scientific computing

  • Advantages: the repository supplies a consistent Linux workspace, pinned tools through Nix, and editor integration. Development dependencies stay in the container; the host needs Docker, Git, and VS Code.
  • Platform: Rust, Cargo, and RustiQ run under Linux regardless of the host operating system. The resulting executable targets the container’s Linux architecture; it is not a native Windows or macOS executable.
  • Virtualization: Docker Engine directly on Linux shares the host kernel and does not require a virtual machine. Docker Desktop runs Linux containers in a Linux VM, including on Linux hosts. On Windows, its Linux backend uses WSL2 or Hyper-V. See the official Docker Desktop VM documentation.
  • Resources and files: the VM’s CPU and memory allocation can restrict a calculation independently of the physical machine’s capacity. Host file sharing can also affect I/O. Review Desktop resource settings and any container resource limits before large calculations. Images and the persistent Nix store consume disk space, and initial setup needs downloads.
  • HPC use: this is a development workspace. Cluster policy may prohibit Docker or require another runtime; the supplied Dev Container does not configure a batch scheduler. Check the site’s supported environment before choosing it for compute nodes.

There is no measured universal performance penalty documented for this setup. For performance comparisons, use release builds and record the actual CPU, available memory, architecture, filesystem, and any VM or container limits. Matching the container architecture to the processor avoids introducing cross-architecture emulation into the comparison.

Prepare your computer

  1. Install Visual Studio Code.
  2. Install and start Docker Desktop, or Docker Engine on Linux. Follow its instructions for your operating system. On Windows, its WSL2 backend requires WSL2; the official setup guide explains that requirement. Docker must be configured to run Linux containers.
  3. In VS Code, open the Extensions view from the left sidebar, search for Dev Containers, and install the extension published by Microsoft.
  4. Install Git to download the project.

Open RustiQ in its prepared environment

Open a terminal on your computer and download the project:

git clone https://github.com/mveril/RustiQ.git
cd RustiQ

In VS Code, choose File > Open Folder and select the downloaded RustiQ folder. Open View > Command Palette, search for Dev Containers: Reopen in Container, and select it. The command palette lets you find VS Code actions by name. The first creation can take several minutes while Docker builds the image and Nix downloads the toolchain pinned by flake.lock. Subsequent starts reuse the Docker image and Nix store.

The container is based on Debian Bookworm and installs only Nix and direnv at the system level. The FlakeEnv extension loads devShells.default directly and propagates its environment to terminals, tasks, debuggers, and language servers. Rust, Nix, TOML, Nickel, dependency, Python, Jupyter, and LLDB support is installed as a small explicit extension list rather than through extension packs with overlapping behavior.

The Rust toolchain, rust-analyzer, nixd, nixfmt, Nickel, its language server, Ruff, scientific Python stack, and development utilities are provided by the Nix shell. The Dev Container also installs these VS Code extensions:

The first activation can take several minutes; later starts reuse the persistent Nix store. Because .envrc execution requires explicit trust, run direnv allow once in the container if FlakeEnv reports that it is blocked, then run FlakeEnv: Reload Environment.

When the workspace is ready, choose Terminal > New Terminal in VS Code. Commands in this terminal run inside the prepared Linux environment. Verify that the tools are available:

cargo --version
rustc --version
rust-analyzer --version
cargo test

After changing .devcontainer/devcontainer.json, rebuild the container. After changing flake.nix or flake.lock, run FlakeEnv: Reload Environment; a container rebuild is only needed when the Dev Container configuration changes.

Dev Container Troubleshooting On Windows

  • If Docker reports that dockerDesktopLinuxEngine cannot be found, start Docker Desktop and wait until docker info succeeds before reopening the repository.
  • If container creation fails while mounting a path such as \\wsl.localhost\<distribution>\mnt\wslg\runtime-dir\wayland-0, disable Dev Containers: Mount Wayland Socket in the VS Code user settings. The equivalent JSON setting is "dev.containers.mountWaylandSocket": false. This only disables Linux GUI forwarding; it does not affect Docker, Rust, Nix, or terminal access.
  • Nix inside the container is installed by the Dev Container feature. It is independent of any Nix or NixOS installation in WSL.
  • If a flake change is not visible in the editor, run FlakeEnv: Reload Environment and restart the affected language server if necessary.

Nix setup

Nix supplies the project’s pinned toolchain without requiring Docker or VS Code. A development shell makes tools available to processes on the current operating system; it is not a virtual machine. See Nix packages and shells for the individual tools provided by the flake.

Advantages and limitations

  • Advantages: flake.lock pins the environment dependencies. Linux and Apple Silicon macOS users compile and run RustiQ natively with prepared Rust and optional PySCF tools. Any editor or terminal can be used.
  • Platforms: this flake supports Linux x86_64 and AArch64 and Apple Silicon macOS. It does not declare native Windows or Intel macOS support.
  • Windows: WSL2 adds a Linux VM and produces Linux executables. Nix inside WSL2 does not remove that virtualization layer.
  • Maintenance: Nix installation, flakes, and the store introduce concepts to learn. Initial downloads or local dependency builds can take time; the store requires disk space. direnv is optional.
  • HPC use: native Nix avoids a container runtime on supported hosts, but installation and access to /nix/store depend on cluster policy. Build on a suitable build node and follow the site’s scheduler and resource rules. Copying a Nix executable alone does not carry its store dependencies to another machine.

If Nix is new to you, start with the official introduction to Nix and learning resources. Nix is a package manager and development-environment tool; NixOS is a complete Linux distribution built around it. You do not need to replace your operating system with NixOS to use this repository’s flake.

Useful references include the official Nix flakes guide, nix develop reference, NixOS-WSL documentation, direnv installation guide, and nix-direnv. For tools used outside the flake, see Rustup and the uv documentation.

The flake supports the following platforms:

  • Linux on x86_64 and AArch64;
  • macOS on Apple Silicon.

The pinned nixpkgs revision no longer supports Intel macOS (x86_64-darwin). Use the native Cargo workflow on that platform.

On Windows, use the Linux flake through WSL2, with either NixOS-WSL or another Linux distribution with Nix installed. This builds and runs Linux executables. For a native Windows executable, use manual installation.

Getting Nix

Choose the case that matches your machine:

  • On NixOS, including NixOS-WSL: Nix is already installed as part of the operating system. NixOS-WSL installation instructions are available for users who want to run NixOS directly under WSL2. Make sure the modern Nix command and flakes are enabled in your NixOS configuration:

    nix.settings.experimental-features = [ "nix-command" "flakes" ];
    

    Apply the configuration with sudo nixos-rebuild switch, then continue with nix develop or the direnv workflow below.

  • On another Linux distribution, macOS, or a non-NixOS WSL2 distribution: install Nix separately as an additional package manager. It works alongside tools such as apt, dnf, pacman, or Homebrew and does not replace them. Follow the official Nix download and installation instructions for your platform, restart the shell if requested, and verify the installation with nix --version. The official page recommends a multi-user installation when the platform supports it.

In either case, Nix reads flake.nix and flake.lock from this repository to create the same project-specific toolchain without installing those development tools globally. The first invocation may take some time because Nix must download the pinned dependencies; later invocations reuse its local store.

Nix Without direnv

Install Nix with flakes enabled, clone the repository, and enter the development shell manually:

git clone https://github.com/mveril/RustiQ.git
cd RustiQ
nix develop

The default full shell provides the Rust toolchain selected by rust-toolchain.toml, the development utilities, and a Python environment built from the checked-in uv.lock. PySCF and the scientific Python dependencies are available on every platform declared by the flake. Nix places that environment directly on PATH, so no virtual environment needs to be created or activated:

python -c "import pyscf; print(pyscf.__version__)"

Platform-specific profiling and debugging tools are included where available. Run the usual Cargo commands inside the shell:

cargo build
cargo test
cargo run -- run samples/h2/sto-3g/calculation.toml

Four shells are available so that contributors only load the tools needed for their current task:

ShellContentsCommand
mini-rustRust toolchain and native build dependenciesnix develop .#mini-rust
rustComplete Rust development, debugging, and profiling tools without Pythonnix develop .#rust
mini-pyscfMinimal Rust build environment plus Python and PySCFnix develop .#mini-pyscf
fullComplete Rust and scientific Python environmentnix develop .#full

Running nix develop without a shell name selects full.

Leave the environment with exit or Ctrl-D. You can also build the default Nix package without entering the development shell:

nix build

Nix With direnv

Install both Nix and direnv, enable the direnv hook for your shell, then run:

git clone https://github.com/mveril/RustiQ.git
cd RustiQ
direnv allow

The tracked .envrc loads the full shell automatically whenever you enter the repository and unloads it when you leave. To select a lighter shell for one checkout, create an ignored .envrc.local, then allow the updated environment:

printf '%s\n' 'export RUSTIQ_DEV_SHELL=rust' > .envrc.local
direnv allow

Valid values are mini-rust, rust, mini-pyscf, and full. The tracked .envrc rejects other values before passing the selection to Nix. direnv allow is deliberately required the first time, and again after either envrc file changes, so that shell code is not executed without review. Use direnv deny to revoke permission.

Inside the Dev Container, FlakeEnv performs this integration for VS Code. The tracked .envrc remains useful for developers who use direnv in another editor or terminal.

If use flake is unknown, install or configure nix-direnv, or use nix develop directly. Some direnv/Nix installations already provide this integration.

Manual setup with Rust and Cargo

Advantages and limitations

  • Advantages: builds and calculations run directly on Linux, macOS, or Windows. No container or VM is required. This is suitable when native host execution, local profiling, or existing cluster build tools matter.
  • Maintenance: you install native build dependencies and optional tools yourself. The repository selects Rust through rust-toolchain.toml and Cargo dependencies through Cargo.lock, but does not pin the entire host environment.
  • Platforms: native Cargo supports the platforms in the compatibility table, including Windows and Intel macOS. Optional PySCF comparisons require Linux, macOS, or WSL2.
  • HPC use: this route can use the site’s existing compiler environment without Docker or Nix. Build and run according to cluster policy, using the scheduler’s assigned resources. A locally built binary still needs a compatible target OS, architecture, and runtime dependencies.

Install and build

Install a C/C++ build toolchain and CMake for native dependencies. On Linux, use your distribution’s development packages; on macOS, install the Xcode Command Line Tools and CMake. On Windows, install Visual Studio C++ Build Tools with the Windows SDK, CMake, and the Rust MSVC toolchain.

Install Git and Rust through rustup, then use Cargo directly on Linux, macOS, or Windows:

git clone https://github.com/mveril/RustiQ.git
cd RustiQ
rustup show
cargo build --locked
cargo test
cargo run -- run samples/h2/sto-3g/calculation.toml

rustup show causes rustup to notice rust-toolchain.toml and install the requested stable toolchain and components if necessary. This route is enough to build and run RustiQ, but the extra tools and the PySCF reference environment from the Nix development shell must be installed separately if you need them. The repository uses uv for that environment on Linux, macOS, and WSL2:

uv run --locked pytest tools/reference

PySCF does not support native Windows; use WSL2 for this optional comparison.

Build for calculations and install the executable

From the repository root, use an optimized build for substantial calculations or timing comparisons:

cargo build --release --locked
cargo run --release --locked -- run samples/h2/sto-3g/calculation.toml

To install into Cargo’s binary directory:

cargo install --locked --path .
rustiq --help

The executable is named rustiq (or rustiq.exe on Windows); use lowercase on case-sensitive systems. Ensure Cargo’s binary directory is on PATH. Keep the checkout for the tutorial’s sample files.

Nix packages and shells

The packages below are declared in flake.nix. The four shells are cumulative: mini-rust supplies the Rust build essentials, rust adds Rust development tools, mini-pyscf adds the Python reference-test environment to the minimal Rust shell, and full combines the complete Rust and scientific Python environments. nix develop selects full by default.

Use nix develop .#<shell> to enter a named shell. The direnv setup can select the same names with RUSTIQ_DEV_SHELL; see Development environments.

Rust build essentials

PackagePurposeShells
Rust toolchain from rust-toolchain.tomlrustc, Cargo, Clippy, rustfmt, and Rust source components pinned to the project toolchainAll
cmakeBuilds native dependencies that use CMakeAll
pkg-configHelps native builds find installed librariesAll
libiconv (macOS only)Provides character conversion support needed by native builds on macOSAll on macOS

Rust development tools

PackagePurposeShells
rust-analyzerRust language server for editor completion, diagnostics, and navigationrust, full
cargo-nextestRuns Rust tests with improved reporting and test isolationrust, full
cargo-denyChecks dependency licenses, advisories, sources, and duplicate cratesrust, full
cargo-llvm-covMeasures Rust test code coverage using LLVM instrumentationrust, full
cargo-criterionRuns Criterion benchmarks through Cargorust, full
cargo-expandDisplays macro-expanded Rust coderust, full
cargo-editAdds, removes, and upgrades dependencies from the command linerust, full
baconWatches files and reruns selected Cargo checksrust, full
cargo-watchRuns Cargo commands when files changerust, full
gitSource control commandsrust, full
hyperfineRepeats and compares command-line benchmarksrust, full
jqReads and transforms JSON from the command linerust, full
mdbookBuilds and previews this manualrust, full
nixdNix language server for editor supportrust, full
nixfmtFormats Nix expressionsrust, full
nickelParses and evaluates Nickel configuration filesrust, full
nlsNickel language server for editor diagnostics and completionrust, full
ripgrep (rg)Fast recursive text searchrust, full
timeReports elapsed time and resource usage for commandsrust, full
clang (Linux only)C/C++ compiler used by profiling and native development toolsrust, full on Linux
cargo-flamegraph (Linux only)Profiles Rust programs and creates flamegraphsrust, full on Linux
gdb (Linux only)Command-line debuggerrust, full on Linux
inferno (Linux only)Converts profiler output into flamegraphsrust, full on Linux
perf (Linux only)Linux performance-counter profilerrust, full on Linux
samply (macOS only)Sampling profiler for macOSrust, full on macOS

Python and scientific packages

Python dependencies are described by pyproject.toml and pinned in uv.lock. Nix builds the Python environments from those files. Python is 3.14 in this flake.

Package or groupPurposeShells
uvPython project and dependency manager for workflows outside the prebuilt shell environmentfull
pyscfIndependent quantum-chemistry implementation used for reference calculationsmini-pyscf, full
numpyArray and numerical operations used in tests and scientific Python toolsmini-pyscf, full
pytestRuns the PySCF reference test suitemini-pyscf, full
scipyScientific algorithms used by optional analysis and development toolsfull
matplotlibCreates plots for scientific analysisfull
ipykernelConnects Python environments to Jupyter kernelsfull
jupyterlabInteractive notebook environmentfull
ruffLints and formats Python codefull

mini-pyscf uses the Python test dependency group; full includes the default group, which combines dev, test, and linting. The helper nix run .#pyscf-check -- ... runs the reference tests against the packaged RustiQ binary. For example:

nix run .#pyscf-check -- -q

Other flake outputs

The flake also exposes nix build .#book to build this manual, nix build .#cargo-artifacts for cached Cargo dependency artifacts, and nix build .#pyscf-environment for the base PySCF environment. These are build outputs rather than development shells. The default package is the RustiQ CLI binary, available through nix build.

Useful references

Known supported platforms

RustiQ is written almost entirely in Rust, which makes it portable across a wide range of operating systems and processor architectures. The CLI and the rustiq-chem-core library are known to work on the platforms below. Automated build and test checks help maintain that compatibility as the project evolves.

Operating systemProcessor architectureAvailable setup
Linuxx86_64Cargo, Nix, or the Dev Container
LinuxAArch64 (ARM64)Cargo, Nix, or the Dev Container
Windowsx86_64Native Cargo, or a Linux environment through WSL2 or the Dev Container
WindowsAArch64 (ARM64)Native Cargo, or a Linux environment through WSL2 or the Dev Container
macOSApple Silicon (AArch64)Cargo, Nix, or the Dev Container
macOSIntel (x86_64)Cargo or the Dev Container

Other Rust targets may also work. This table describes known compatibility; it is not an exhaustive list of every platform on which RustiQ could run. Native dependencies and optional tools can impose additional requirements.

Choosing an environment

The Cargo workflow builds RustiQ directly on your operating system. It is available on all the platforms listed above. The Nix flake provides a prepared Rust and scientific Python environment for these systems:

  • x86_64-linux;
  • aarch64-linux;
  • aarch64-darwin (Apple Silicon).

The pinned nixpkgs revision no longer supports Intel macOS, so use native Cargo or the Linux Dev Container on that platform. Native Windows users can also use Cargo; Nix requires a Linux environment such as WSL2.

The optional VS Code Dev Container provides a Linux environment through Docker. It is an option on all the host platforms in the table, including Linux and Windows ARM64, provided Docker can run Linux containers on the host. Inside the container, Nix uses x86_64-linux or aarch64-linux according to the container architecture, even when the host runs Windows or macOS. See Development environments for installation instructions, Windows troubleshooting, and the configured VS Code extensions.

The optional scientific Python tools have their own platform requirements. The project configures uv for Linux and macOS, and the Nix environment provides PySCF on every declared Nix system. For PySCF comparisons on Windows, use WSL2 or the Linux Dev Container.

How compatibility is checked

The regular CI workflow provides ongoing evidence for this support:

  • Native Cargo checks cover Linux x86_64, Windows x86_64 and ARM64, and macOS Apple Silicon and Intel. They run formatting, Clippy, workspace tests with and without the online feature, and standalone core checks.
  • Nix checks cover Linux x86_64 and AArch64 and macOS Apple Silicon. They build RustiQ, exercise the development shells, and compare reference energies against PySCF.
  • The Dev Container is built and tested on Linux x86_64, including Cargo tests and PySCF comparisons. Separate Windows and macOS host integrations are not exercised by these checks.
  • The standalone uv environment is checked on Linux x86_64.

The scheduled full Nix workflow also runs all native flake checks on the three declared Nix systems. These checks validate known configurations; they do not limit the possible platforms for the Rust application.

Releasing RustiQ

RustiQ uses dist to build and publish binary archives to GitHub Releases. crates.io publication runs in a separate workflow, so a registry outage does not block a binary release. Neither workflow creates a release from a GitHub Release event; both are triggered directly by a version tag, and crates.io publication can also be started manually for an existing tag.

Binary releases

The repository-root dist-workspace.toml pins dist 0.33.0, selects only the rustiq-chem CLI package, and lists the six supported targets. Pull requests run dist plan; this checks the release plan without building or publishing artifacts. The generated workflow also runs on non-main pull requests because dist 0.33.0 does not expose a pull-request base-branch filter. A pull request cannot enter the publishing jobs.

All six target builds use native GitHub-hosted runners: Linux x64 on ubuntu-22.04, Linux ARM64 on ubuntu-24.04-arm, macOS Intel on macos-15-intel, Apple Silicon on macos-14, Windows x64 on windows-2025, and Windows ARM64 on windows-11-arm. The configuration explicitly selects the ARM runners and preserves the native Windows runners.

The rustiq-chem-core library remains a build dependency and is not packaged as an application. The generated workflow is .github/workflows/release.yml; do not edit it by hand.

Each release includes a rustiq executable (named rustiq.exe on Windows), the README, and the MIT and Apache license files. Unix archives use .tar.gz and Windows archives use .zip. Dist adds a .sha256 file for each archive and a sha256.sum manifest. Installers are disabled. Archives do not include calculation samples or basis data.

To verify all release assets on Linux, download sha256.sum and all listed assets into one directory, then run:

sha256sum --check sha256.sum

On macOS, use the built-in shasum command:

shasum -a 256 --check sha256.sum

On Windows PowerShell, compare the archive’s entry in sha256.sum with:

Get-FileHash .\rustiq-chem-x86_64-pc-windows-msvc.zip -Algorithm SHA256

The archive target identifies the operating system and CPU architecture; it does not guarantee compatibility with every Linux distribution or older system library. The Linux GNU archives require a compatible glibc runtime.

Preparing a release

From the repository root, update the version in both package manifests and update the CLI’s rustiq-chem-core dependency requirement to that same version:

  • Cargo.toml (rustiq-chem)
  • crates/rustiq-core/Cargo.toml (rustiq-chem-core)
  • Cargo.toml’s rustiq-core dependency

After editing the manifests, regenerate Cargo.lock and commit it with the version changes:

cargo check --workspace
git add Cargo.toml crates/rustiq-core/Cargo.toml Cargo.lock
git commit -m "Prepare release X.Y.Z"

The publishing workflow checks both package versions and the CLI dependency requirement against the tag using Cargo metadata. After committing the version change, check package contents and build the workspace:

cargo publish --dry-run --workspace --locked
cargo check --workspace --locked

Review the dist release plan and regenerate the workflow after changing the dist configuration or updating dist. The pinned generator checks that the generated release workflow is synchronized with dist-workspace.toml:

dist plan
dist generate --mode ci
dist generate --mode ci --check

The Rust development shell includes the Nixpkgs cargo-dist package. The generated workflow installs the exact dist version recorded in dist-workspace.toml. Before regenerating locally, install that same version if the Nixpkgs package differs:

cargo install cargo-dist --version 0.33.0 --locked

Commit and push the version changes, then create and push the matching tag:

git tag vX.Y.Z
git push origin HEAD
git push origin vX.Y.Z

Release tags must match vX.Y.Z or vX.Y.Z-prerelease, such as v1.2.3 or v0.1.0-beta.1. For a prerelease, include the same suffix in both package versions and the tag. Dist recognizes the suffix and marks the GitHub Release as a prerelease. Do not reuse an existing tag or a crates.io package version.

The tag starts dist’s generated workflow, which builds the configured platform archives, creates their checksums, and publishes the assets to GitHub Releases. A dist plan-jobs reusable workflow validates the tag format and requires its commit to be an ancestor of main before artifact builds can proceed. This accepts prerelease suffixes such as -alpha.1. A failed validation blocks the build and therefore the publishing jobs.

crates.io publication

.github/workflows/publish-crates.yml publishes both workspace crates when a v* tag on main is pushed. Cargo publishes workspace members in dependency order, so rustiq-chem-core is available before rustiq-chem. Before publishing, the workflow uses the crates.io API to exclude package versions that already exist. If a run publishes the core crate and then fails while publishing the CLI, rerunning the same tag skips the existing core version and retries the CLI. For a retry, open Actions → Publish crates.io packages → Run workflow, enter the existing v… tag, and start the workflow. This workflow remains separate from the dist binary release workflow and can also be run manually for an existing tag.

The workflow currently authenticates with the Actions secret CARGO_REGISTRY_TOKEN. Create it from a crates.io API token with only package publishing permissions, then add it under the repository’s Actions secrets before the first release. Keep the token out of repository files and do not grant permissions to yank crates.

Crates.io Trusted Publishing uses GitHub OIDC and avoids a long-lived token, but crates.io requires each crate to have an initial token-authenticated publication before a Trusted Publisher can be configured. For RustiQ’s first publication, use CARGO_REGISTRY_TOKEN to publish both packages through the tag workflow or its manual execution for an existing tag. After both crates exist, configure a Trusted Publisher for each crate in crates.io to trust this repository and the publishing workflow. A follow-up change can then replace the token authentication with OIDC; the binary release workflow does not use or depend on the crates.io token.

Cargo may time out while waiting for a published version to appear in the registry index even when the upload succeeded. Check the version on crates.io before retrying; the workflow’s existence check will skip a version already published.

Contributing and the Rust API

CONTRIBUTING.md owns branch naming, lint policy, and verification commands. See development environments for setup.

The workspace keeps CLI parsing and presentation in the root package and scientific configuration and calculations in rustiq-chem-core. The core’s calculation module orchestrates work in molecules, basis, eri, hf, and mp2.

Rustdoc remains the canonical public API reference. Generate and open it with MathJax support:

tools/generate-rustdoc.sh --open

On Windows:

.\tools\generate-rustdoc.ps1 -Open

The generated entry point is target/doc/rustiq_core/index.html. MathJax equations require browser access to the CDN. The initial Pages site publishes the manual; rustdoc is generated separately.

Runnable API examples and public API tests provide executable workflows and verification. Link to these sources instead of duplicating item-level documentation in the book.

Architecture and calculation lifecycle

The root CLI package owns terminal reports, application directories, and src/runfile/, which resolves TOML/Nickel through the embedded Nickel schema. The library owns scientific configuration and calculations without a Nickel dependency. This boundary lets a different frontend supply scientific options without embedding its input syntax or terminal behavior into numerical code.

Within the core, molecules owns geometry, units, charge and electron counts; basis constructs Gaussian functions; eri computes and stores electron repulsion integrals; hf solves RHF/UHF; and mp2 consumes HF orbitals. Rust makes ownership and mutation explicit for matrices, integral storage, and shared results. Enums model choices such as the HF method, while Cargo brings dependency locking, feature selection, and tests into one workflow. These engineering tools help make assumptions inspectable; they do not establish numerical correctness or a performance advantage over other languages.

Typed errors distinguish invalid input from numerical failures. Optional source locations let the CLI attach diagnostics to input text without making the library own that text or its presentation.

CalculationBuilder accepts geometry, basis data, and scientific options. prepare() validates the state, converts coordinates to Bohr, constructs the basis, and resolves RHF/UHF. A prepared calculation can execute repeatedly. run_hf() distinguishes converged and unconverged outcomes; only the converged solution exposes mp2(). This type boundary prevents accidental MP2 execution on unconverged orbitals. Cloned solutions share immutable scientific data; execution errors retain completed HF outcomes when available.

The normalized CalculationRequest records scientific input without geometry paths or frontend source spans. Canonical TOML/XYZ rendering belongs to CLI adapters. Core consumers supply explicit paths to BasisStore::new; application storage environment variables are CLI policy. The core has no default features; its optional online feature enables online basis support. See the runnable examples and public API tests above for complete construction and error handling.

Data preparation, execution, and reuse

The lifecycle is:

CLI TOML/Nickel adapter or another frontend
    -> geometry + basis data + scientific options
    -> CalculationBuilder::prepare()
       molecule in Bohr, Gaussian basis, resolved HF method and random seeds
    -> PreparedCalculation::run_hf()
       one-electron integrals, overlap orthogonalization, AO ERI acquisition
       -> iterative SCF and final canonicalization
       -> HfOutcome::Converged or HfOutcome::Unconverged
    -> converged HfSolution::mp2()
       blocked AO-to-MO transformation and correlation energy

prepare() constructs reusable input data; it does not compute integrals or solve HF. Each normal run_hf() call builds a new HF execution state, including one-electron integrals and the orthogonalizer. Without an explicit reuse source, AO ERIs are recomputed too. Repeated execution of a prepared calculation does not itself memoize these numerical arrays. Random seeds resolved at preparation are retained for repeated executions.

An optional EriCache can load compatible AO ERIs from a directory or store newly computed ones. It is disposable local storage. A supplied CompactEri through run_hf_with_eri() bypasses AO ERI computation and cache lookup, but the raw tensor API checks its expected element count rather than proving its scientific provenance. The caller must supply ERIs for the prepared geometry, AO ordering, and screening policy. Use the persistence APIs’ compatibility checks when reusing an archive. HF solutions retain their AO ERIs, and cloned solutions share immutable result data; these retained results are distinct from the prepared input data.

Portable .rustiq bundles can be read and written through the core persistence APIs and through the CLI’s run --reuse, run --artifact, and artifact inspect commands. CLI reuse starts from the supplied runfile and resolves its geometry and basis as usual, then uses bundle compatibility to select AO ERIs; the bundle is not an input-file substitute. The Rust API can also reconstruct a calculation from the archived scientific snapshots. Neither workflow turns a local cache directory into a portable artifact. See the portable bundle guide, the persistence contract, and the runnable API examples for details.

This distinction matters for performance: compact AO ERI storage still grows as the fourth power of basis dimension, and the MP2 workspace budget covers additional transformation buffers rather than the full HF data or process memory. See MP2 memory policy.

Build profiles and performance investigation

Cargo’s default development and test builds favor development speed. Release builds optimize execution using thin link-time optimization and one codegen unit, and strip symbols. The custom profiling profile retains release optimizations with debug information and symbols:

cargo build --locked --release
cargo build --locked --profile profiling

The profiling executable is under target/profiling/. For optimization specific to the build machine’s CPU, use RUSTFLAGS="-C target-cpu=native" cargo build --locked --release; that binary may require instructions absent on another CPU. In PowerShell, set $env:RUSTFLAGS = "-C target-cpu=native", build, then remove it with Remove-Item Env:RUSTFLAGS. There is no separate native Cargo profile.

The eri_timings and mp2_timings benchmarks use Criterion and require bench-support:

cargo bench --bench mp2_timings --features bench-support
cargo bench --bench eri_timings --features bench-support

The MP2 benchmark compares dense and memory-blocked kernels on deterministic synthetic inputs. It validates that both paths produce matching energies before timing them; input and ERI construction remain outside the measured iterations. RUSTIQ_MP2_MEMORY, RUSTIQ_MP2_SIZES (comma-separated AO dimensions), and RAYON_NUM_THREADS select the memory budget, AO dimensions, and thread count. The ERI benchmark times repeated integral construction for the checked-in molecular cases. By default it skips the larger ethanol and cholesterol cases; set RUSTIQ_BENCH_HEAVY=1 to include them. RUSTIQ_BENCH_FILTER selects cases by name or geometry path, and RUSTIQ_BENCH_BASIS_STORE selects a basis store. It reports compact ERI storage elements processed per second. This count is the size of the compact representation; Schwarz screening may skip evaluations or leave stored elements zero, so it is not a count of integrals evaluated per second.

The standard cases use 30 samples, a 2-second warm-up, and a 5-second measurement target. Heavy ERI cases and MP2 cases with 48 or more AOs use Criterion’s minimum of 10 samples, a 1-second warm-up, and a 2-second target. These are targets: Criterion may take longer to collect the requested samples, especially when each calculation is expensive. Heavy ERI cases remain disabled unless RUSTIQ_BENCH_HEAVY=1 is set. Measurements are saved under target/criterion.

Criterion baselines can be compared only between revisions that both use Criterion. The first Criterion-enabled revision establishes the starting point; legacy timing results cannot be compared directly with Criterion measurements. MP2 input construction is excluded from measured iterations. Keep CPU architecture, Rayon thread count, build flags, enabled features, MP2 memory budget, power settings, and benchmark environment variables consistent. Save a baseline on the first Criterion revision, then compare from the revision under test:

cargo bench --bench mp2_timings --features bench-support -- --save-baseline before
cargo bench --bench mp2_timings --features bench-support -- --baseline before

See the MP2 benchmark source and ERI benchmark source. Benchmarks provide performance measurements, not scientific validation.

Documentation checks

The book uses standard mdBook theme, search, and MathJax, without external preprocessors. Preview it inside nix develop .#rust:

mdbook serve docs --open

Run the documentation workflow’s checks locally:

nix build .#book

Open result/index.html for the generated manual. The derivation runs:

mdbook build docs
mdbook test docs
pytest tools/test_book_links.py
python tools/check-book-links.py docs/book --config docs/book.toml

Verification coverage is deliberately explicit:

  • Book build checks chapter structure and sample includes.
  • The link checker validates generated local links, assets, and HTML fragments. It does not fetch external URLs.
  • mdbook test validates supported Rust code blocks. This edition has no Rust snippets. It does not execute shell, TOML, XYZ, or Nickel examples.
  • Main CI validates CLI samples, configuration, batches, and PySCF comparisons. Documentation CI does not repeat that scientific suite. The first-calculation chapter identifies its sample test, numerical reference, tolerance, and reproduction command.

The Documentation workflow builds and validates pull requests and can also be run manually. A separate Publish documentation workflow runs on pushes to main, including merges, and deploys to GitHub Pages after successful validation. The publication job does not appear in pull request checks. Maintainers must select GitHub Actions as the repository’s Pages source before the first deployment. PR builds have no Pages write permission.

When extending the manual, tie executable capabilities to checked-in examples and automated verification. Numerical claims need a reference and tolerance.