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?
- Scientific users: Installation → First H₂ calculation → Interpreting output. These explain how to run the software without writing Rust. Read scientific limitations before using the results.
- Rust developers and architects: Development environments → Contributing, architecture, and the Rust API → Documentation checks. Start with the calculation lifecycle to see how input, scientific code, and reporting fit together.
- Theoretical chemists: First calculation → Reference comparisons → Scientific limitations. These identify tested evidence and current assumptions without requiring development tools.
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.
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.
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.116759Hartree.
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
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 infodoes 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 runconverts 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:
- First compatible AO ERI in the archive’s manifest order.
- Matching entry in the enabled local AO ERI cache.
- 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 input | AO ERI compatibility |
|---|---|
| HF method, initial guess, or SCF convergence limit | Can remain compatible; HF runs again with the new settings. |
| Add or change MP2 settings | Can remain compatible; MP2 runs again from the new HF result. |
| Geometry, effective AO basis, or Schwarz screening | Incompatible; 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 outcome | Bundle behavior |
|---|---|
| Every requested calculation produces a result | Publish the current collection. |
| A preparation or execution error occurs | Do not publish; preserve any prior destination. |
| HF-only run reaches its iteration limit | Its 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 converge | MP2 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
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.
| Term | Meaning in this manual |
|---|---|
| AO / MO | Atomic orbital / molecular orbital. Basis functions centered on atoms represent the molecular orbitals used by HF and MP2. |
| Basis set | A 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 / Angstrom | Length units. Bohr is the atomic unit of length; Angstrom is commonly used for molecular coordinates. RustiQ converts input coordinates to Bohr for calculations. |
| Hartree | The atomic unit of energy used in RustiQ’s reported energies. |
| HF / RHF / UHF | Hartree–Fock / restricted HF / unrestricted HF. RHF pairs electrons in shared spatial orbitals; UHF permits different spatial orbitals for alpha and beta spins. |
| SCF | Self-consistent field: the iterative procedure for solving the HF equations. Meeting its convergence criterion does not prove chemical accuracy. |
| DIIS | Direct inversion in the iterative subspace: an acceleration technique for SCF iterations. |
| MP2 | Second-order Møller–Plesset perturbation theory: a correlation correction built from an HF reference. |
| Multiplicity | 2S + 1 for spin quantum number S. Singlet and doublet mean multiplicities one and two. Charge and multiplicity specify the intended molecular state. |
| Spin contamination | Deviation of UHF’s spin expectation value from the value for the intended pure spin state. |
| ERI | Electron-repulsion integral: a contribution describing the Coulomb interaction between electrons in the chosen basis. |
| AO ERI | Atomic-orbital electron-repulsion integral. RustiQ’s optional local cache stores these deterministic integrals, not HF or MP2 results. |
| Orthogonalization | Construction of an orthonormal orbital space from overlapping basis functions. Near-dependent directions may be removed. |
| Frozen orbitals | Occupied orbitals excluded from the MP2 correlation calculation. |
| ECP | Effective core potential: a model replacing core electrons and their nuclear interaction; currently unsupported by RustiQ’s basis loader. |
| Rust / Cargo | Rust is the implementation language; Cargo builds Rust packages and runs their tests and examples. Users can run an installed CLI without writing Rust. |
| Crate / workspace | A Rust package’s library or executable unit / a group of packages built together. RustiQ separates its CLI and scientific library. |
| CLI / API | Command-line interface for terminal users / application programming interface for code using the library. |
| rustdoc / mdBook | Rust’s API documentation generator / the tool that builds this user and developer manual. |
| TOML / Nickel | Calculation input languages. TOML provides declarative settings; Nickel also supports imports and computed studies and owns input defaults and validation. |
| JSON / schema | A structured data format / the contract describing valid data. Existing versioned schemas define RustiQ’s machine-readable results. |
| Nix / flake | A tool for reproducible packages and environments / this repository’s project definition, with dependencies locked by flake.lock. Nix does not require NixOS. |
| Dev Container | A prepared Linux development environment running through Docker, with editor integration. |
| Cache / portable artifact | Disposable 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 / tolerance | Comparison against independent evidence / the allowed difference in a particular numerical check. Passing selected checks does not validate every calculation. |
| Contracted Gaussian | A basis function formed by a weighted sum of primitive Gaussian functions that share a center and angular momentum. |
| Primitive Gaussian | A Gaussian function used as a component of a contracted basis function. |
| Occupied / virtual orbital | An orbital assigned electrons in the reference determinant / an unoccupied orbital available as an excitation destination. |
| Fock matrix | The effective one-electron matrix built from the current electron density in Hartree–Fock. |
| Density matrix | A matrix encoding which molecular orbitals are occupied and their contributions in the atomic-orbital basis. |
| Overlap matrix | The matrix of pairwise integrals between basis functions; its off-diagonal values reflect that these functions need not be orthogonal. |
| Cartesian / spherical Gaussian | Two ways to represent the angular part of Gaussian basis functions. Their function counts differ for d and higher angular momentum. |
| Correlation energy | The energy correction beyond the chosen HF reference; RustiQ reports MP2 correlation separately from the HF and total energies. |
| Linear dependence | Near-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
| Command | Purpose |
|---|---|
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>... / --all | Remove 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] / --all | Remove 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, isometry | Transform 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:
| Option | Behavior |
|---|---|
--format FORMAT (text or json) | Select text output (default) or versioned JSON. JSON result data is written to standard output. |
--pretty | Pretty-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-download | In 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 DIR | Choose the AO ERI cache root for this run. The input must also set [cache].enabled = true; this option does not enable caching. |
--reuse PATH | Read a portable .rustiq bundle and reuse the first compatible AO ERI for each calculation. |
--artifact PATH | Write 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
| Capability | Available behavior |
|---|---|
| TOML | One calculation per input; see the checked-in H₂ input. |
| Nickel | One calculation or an ordered study/batch; see the checked-in study example. |
| JSON | Versioned single-calculation and batch results, selected with run --format json; schemas are linked below. |
| AO ERI cache | Optional local reuse through [cache].enabled and --cache-dir; entries can be listed or removed. AO ERI means atomic-orbital electron-repulsion integral. |
Portable .rustiq bundle | Create 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 status | Experimental; 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.
| Section | Supported 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:
| Platform | Default 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:
-
Command-line reference: shipped commands, principal options, output behavior, and availability boundaries.
-
TOML calculation configuration and Nickel studies: runnable inputs linked to the authoritative Nickel defaults and validation below.
-
Persistence V1 specification: the portable ZIP/ZIP64
.rustiqcontract. -
Embedded Nickel schema: input defaults and validation.
-
Rustdoc: public Rust API reference.
-
CONTRIBUTING.md: contribution requirements.
-
CITATION.cff: project citation metadata.
-
ROADMAP.md and issues: future work.
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.
| Setup | Where Rust and RustiQ run | Advantages | Limitations |
|---|---|---|---|
| Docker / Dev Container | Linux inside a container on every host | Prepared workspace and VS Code integration | Linux target only; Desktop uses a VM; resource and file-sharing settings need attention |
| Nix | Native Linux or Apple Silicon macOS; Linux in WSL2 on Windows | Pinned tools without requiring Docker | Limited flake platforms; store and installation requirements; WSL2 uses a VM |
| Manual / Cargo | Native Linux, macOS, or Windows | Direct host execution and control over installed tools | Native 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
- Install Visual Studio Code.
- 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.
- In VS Code, open the Extensions view from the left sidebar, search for Dev Containers, and install the extension published by Microsoft.
- 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:
- FlakeEnv loads the flake environment into editor processes.
- rust-analyzer provides Rust language support; CodeLLDB provides debugging.
- Nix IDE and Nickel provide Nix and Nickel language support.
- Even Better TOML supports TOML, while Prettier formats JSON, YAML, and Markdown.
- Dependi helps inspect dependencies; Python, Jupyter, and Ruff support the Python reference tools.
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
dockerDesktopLinuxEnginecannot be found, start Docker Desktop and wait untildocker infosucceeds 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.lockpins 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.
direnvis optional. - HPC use: native Nix avoids a container runtime on supported hosts, but
installation and access to
/nix/storedepend 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 withnix developor 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 withnix --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:
| Shell | Contents | Command |
|---|---|---|
mini-rust | Rust toolchain and native build dependencies | nix develop .#mini-rust |
rust | Complete Rust development, debugging, and profiling tools without Python | nix develop .#rust |
mini-pyscf | Minimal Rust build environment plus Python and PySCF | nix develop .#mini-pyscf |
full | Complete Rust and scientific Python environment | nix 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.tomland Cargo dependencies throughCargo.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
| Package | Purpose | Shells |
|---|---|---|
Rust toolchain from rust-toolchain.toml | rustc, Cargo, Clippy, rustfmt, and Rust source components pinned to the project toolchain | All |
cmake | Builds native dependencies that use CMake | All |
pkg-config | Helps native builds find installed libraries | All |
libiconv (macOS only) | Provides character conversion support needed by native builds on macOS | All on macOS |
Rust development tools
| Package | Purpose | Shells |
|---|---|---|
rust-analyzer | Rust language server for editor completion, diagnostics, and navigation | rust, full |
cargo-nextest | Runs Rust tests with improved reporting and test isolation | rust, full |
cargo-deny | Checks dependency licenses, advisories, sources, and duplicate crates | rust, full |
cargo-llvm-cov | Measures Rust test code coverage using LLVM instrumentation | rust, full |
cargo-criterion | Runs Criterion benchmarks through Cargo | rust, full |
cargo-expand | Displays macro-expanded Rust code | rust, full |
cargo-edit | Adds, removes, and upgrades dependencies from the command line | rust, full |
bacon | Watches files and reruns selected Cargo checks | rust, full |
cargo-watch | Runs Cargo commands when files change | rust, full |
git | Source control commands | rust, full |
hyperfine | Repeats and compares command-line benchmarks | rust, full |
jq | Reads and transforms JSON from the command line | rust, full |
mdbook | Builds and previews this manual | rust, full |
nixd | Nix language server for editor support | rust, full |
nixfmt | Formats Nix expressions | rust, full |
nickel | Parses and evaluates Nickel configuration files | rust, full |
nls | Nickel language server for editor diagnostics and completion | rust, full |
ripgrep (rg) | Fast recursive text search | rust, full |
time | Reports elapsed time and resource usage for commands | rust, full |
clang (Linux only) | C/C++ compiler used by profiling and native development tools | rust, full on Linux |
cargo-flamegraph (Linux only) | Profiles Rust programs and creates flamegraphs | rust, full on Linux |
gdb (Linux only) | Command-line debugger | rust, full on Linux |
inferno (Linux only) | Converts profiler output into flamegraphs | rust, full on Linux |
perf (Linux only) | Linux performance-counter profiler | rust, full on Linux |
samply (macOS only) | Sampling profiler for macOS | rust, 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 group | Purpose | Shells |
|---|---|---|
uv | Python project and dependency manager for workflows outside the prebuilt shell environment | full |
pyscf | Independent quantum-chemistry implementation used for reference calculations | mini-pyscf, full |
numpy | Array and numerical operations used in tests and scientific Python tools | mini-pyscf, full |
pytest | Runs the PySCF reference test suite | mini-pyscf, full |
scipy | Scientific algorithms used by optional analysis and development tools | full |
matplotlib | Creates plots for scientific analysis | full |
ipykernel | Connects Python environments to Jupyter kernels | full |
jupyterlab | Interactive notebook environment | full |
ruff | Lints and formats Python code | full |
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
- Nix flakes and
nix develop. - Rustup toolchain file and Cargo commands.
- PySCF documentation, uv documentation, and JupyterLab documentation.
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 system | Processor architecture | Available setup |
|---|---|---|
| Linux | x86_64 | Cargo, Nix, or the Dev Container |
| Linux | AArch64 (ARM64) | Cargo, Nix, or the Dev Container |
| Windows | x86_64 | Native Cargo, or a Linux environment through WSL2 or the Dev Container |
| Windows | AArch64 (ARM64) | Native Cargo, or a Linux environment through WSL2 or the Dev Container |
| macOS | Apple Silicon (AArch64) | Cargo, Nix, or the Dev Container |
| macOS | Intel (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
uvenvironment 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’srustiq-coredependency
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 testvalidates 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.