Goal: build Q3, run a self-consistent field (SCF) calculation on silicon, and understand what the log is telling you.
You need a C++17 compiler (GCC 9 or newer, or Clang), CMake, FFTW3 and LAPACK:
Then clone:
The build generates C++ from the JSON schemas in schemas/ as it goes, which needs a few Python modules, mat3ra-esse (ESSE's schemas) among them. Create the environment before configuring — a .venv at the repository root is picked up automatically:
That produces build/q3 (the engine) and build/q3_tests (the suite). A good first sanity check is to run the tests:
It finishes in about a second. Before reading the output, look at the input — it is short, and every DFT calculation you ever run is a variation on it:
Four blocks, and they answer four different questions: what you are computing (material), which physics (model), with what numerical approximations (method), and what to do with it (control). Paths inside the manifest resolve relative to the manifest's own directory, so the example works from anywhere.
**outdir is relative to your current directory, not to the manifest.** Running the command above from the repository root writes ./output/si_nc_results.json at the repository root. This trips people up; cd into the example directory first if you want the output beside it.
Read this every time. Three things here catch most input mistakes before you waste an hour:
Z=4** — the pseudopotential treats 4 electrons per silicon atom as valence. With 2 atoms, that is the number of electrons = 8.0000 printed below.Fd-3m (#227, 48 symmetry ops)** — Q3 detected diamond structure. If you expected a symmetry and see P1 (#1, 1 symmetry op), your coordinates are slightly off and the calculation will be needlessly slow.8 -> 2 k-points** — symmetry reduced the sampling to 2 inequivalent points. This is a 4× saving, done automatically.The basis Q3 built from your cutoffs. number of bands = 8 for 8 electrons means 4 doubly-occupied bands and 4 empty ones — enough for an insulator.
This is the heart of it. DFT is a fixed-point problem: the electron density determines the potential, the potential determines the orbitals, and the orbitals determine the density. Q3 iterates until the input and output densities agree.
dr2** is the density residual — how much the density still moved. It is the quantity actually compared against convergence_threshold (1e-8 here), not delta(E). Energy converges faster than density, so stopping on energy alone would give you a plausible number from an unconverged density.dr2 by roughly an order of magnitude. That steady geometric decay is what healthy convergence looks like. Oscillation or stagnation means the mixer needs help — see TROUBLESHOOTING.md.verbosity: high under control (or pass --log-level debug) to see what happens inside each one: the Davidson micro-iterations, the per-phase timing breakdowns, and the mixer's residual bookkeeping. It changes nothing but the output.Forces here are zero to machine precision (10⁻¹⁹ Ry/bohr) — silicon's atoms sit at symmetry-fixed positions, so no other answer is possible, which makes this a useful correctness check. The residual 3.71 kbar pressure is real: the PBE equilibrium lattice constant differs slightly from the experimental one in the input file.
A caution about the total energy. −16.913417932 Ry is not a physical observable. It is referenced to the pseudopotential's own zero, so it is comparable only against another calculation using the same pseudopotentials, cutoffs and functional. Energy differences between such calculations are the physics. Tutorial 03 is about making those differences trustworthy.
Silicon's ultrasoft and PAW datasets are committed too:
The total energy will be completely different (−15.717 Ry). That is expected and it is the point of the caution above: different pseudopotentials use different energy zeros. Compare differences, never absolutes across families.
02 — Reading the results: getting these numbers out of results.json programmatically.