Quickstart: your first calculation#
This chapter gets you from a blank Python prompt to a real quantum-chemistry result in a few lines. We will compute the energy of a water molecule, switch the method to DFT, and read out an atomic-charge property — enough to see the whole shape of a qc-rs calculation.
Note
Before you start
You need qc-rs installed and importable (import qc works). If not, do
Installation & the build first.
Run your first calculation#
Type this into a Python session (or a script, or a Jupyter notebook cell):
import qc
# 1. Build a checkpoint: water, in the cc-pVDZ basis, coordinates in ångström.
mychk = qc.chk.new(
atom="O 0.0000 0.0000 0.1173; H 0.0000 0.7572 -0.4692; H 0.0000 -0.7572 -0.4692",
ao="cc-pvdz",
unit="angstrom",
)
# 2. Add a restricted Hartree–Fock (RHF) step, and run it.
mychk = mychk.scf(ref="r").run()
# 3. Read the result.
print(f"energy = {mychk.scf.energy:.6f} hartree")
print(f"converged = {mychk.scf.converged}")
You should see:
energy = -76.026772 hartree
converged = True
That is a complete Hartree–Fock calculation. Congratulations — you just solved the electronic Schrödinger equation (approximately!) for water.
What just happened?#
Three ideas, one per line:
qc.chk.new(...)builds a checkpoint — the object that holds your molecule and, later, all results. Here we gave it the geometry (atom=), the basis set (ao="cc-pvdz"), and the unit of the coordinates (unit="angstrom")..scf(ref="r")adds a step — a self-consistent-field calculation.ref="r"means restricted (closed-shell) Hartree–Fock. Adding a step does no heavy computation yet; it just records what you want..run()does the work, and afterwardsmychk.scf.energyreads the result back out.
This build-then-run pattern is the heart of qc-rs. We look at it properly in Core concepts.
Tip
Watch it run: run(log=...)
By default .run() is silent — it just computes. Pass run(log="stdout") to stream a live,
quantum-chemistry-style transcript instead: the system summary, the SCF cycle-by-cycle energy table, and the
convergence check. A few options you will reach for early — log_style="modern"/"orca" picks the visual
style, and plot=True draws the SCF convergence curve inline (in a notebook with %matplotlib inline).
After a run, mychk.log() replays the transcript without recomputing. The full set is shown in
Editor setup and the Logging & output chapter.
Tip
Make it faster: nthread=
By default a calculation uses a single CPU core. Pass run(nthread=8) to spread the work across 8
cores of your machine — shared-memory thread parallelism that speeds up almost every run on a laptop or
a single node, with no extra setup. (Running across many machines with MPI process parallelism,
nmpi=, is more advanced — we introduce it later in
Parallel computing & HPC. For now, nthread= is all you need.)
The result carries much more than the energy. For instance mychk.scf.ncycle is how many SCF iterations it
took to converge, and mychk.scf.energy_components breaks the total energy into its physical pieces
(kinetic, nuclear attraction, Coulomb, exchange, …). You will meet these as you need them.
Tip
A Python note
f"...{mychk.scf.energy:.6f}..." is an f-string — Python substitutes the value of the expression in
{...} into the text, and :.6f formats it with six digits after the decimal point.
Switch to DFT#
Want density-functional theory instead of Hartree–Fock? Change one thing — add a functional with
xc=:
mydft = qc.chk.new(
atom="O 0.0000 0.0000 0.1173; H 0.0000 0.7572 -0.4692; H 0.0000 -0.7572 -0.4692",
ao="cc-pvdz", unit="angstrom",
).scf(ref="r", xc="b3lyp").run()
print(f"{mydft.scf.energy:.6f} hartree") # -76.420369
The B3LYP energy (-76.420369) is lower than the Hartree–Fock one because it includes electron
correlation — a concept we develop in Foundations.
Your first property#
An energy is only the beginning. From the same converged calculation you can ask for hundreds of properties. Here are the Mulliken atomic charges:
q = qc.prop.chrg.mulliken(mychk)
print(q["charges"]) # [-0.3060, 0.1530, 0.1530]
print(q["atom_labels"]) # ['O', 'H', 'H']
Oxygen carries a partial negative charge and each hydrogen a partial positive charge — exactly the polarity you expect for water. The whole property suite lives in Molecular properties.
Open-shell molecules (radicals)#
Not every molecule is a closed shell. For a radical — an odd number of electrons, or unpaired spins — use
unrestricted Hartree–Fock (ref="u") and set the spin. Here is the methyl radical (CH₃•), a doublet:
ch3 = qc.chk.new(
atom="C 0 0 0; H 0 1.079 0; H 0.934 -0.539 0; H -0.934 -0.539 0",
ao="cc-pvdz", unit="angstrom",
spin=2, # spin multiplicity 2S+1: 2 = doublet (one unpaired electron)
).scf(ref="u").run() # ref="u" = unrestricted
print(f"{ch3.scf.energy:.6f} hartree") # -39.563802
print(qc.prop.spin.s_squared(ch3)) # 0.7612 (ideal doublet: 0.75)
Tip
A note on spin
spin is the multiplicity 2S+1: 1 = singlet (all electrons paired), 2 = doublet (one unpaired),
3 = triplet (two unpaired). Use ref="r" for closed shells, ref="u" (unrestricted) or ref="ro"
(restricted-open) for open shells.
The ⟨S²⟩ ≈ 0.76 here is close to the ideal 0.75 of a pure doublet; small excesses measure a little
spin contamination, which the SCF chapter explains.
Where to next#
To relax a structure and then analyze it, work through the Tutorial: DFT geometry optimization → properties.
To understand why the checkpoint/step/run pattern is shaped this way, read Core concepts.
To understand what Hartree–Fock and DFT actually compute, read Foundations.