CC2, CC3, CCSD, CCSDT, QCISD, and perturbative triples¶
Canonical coupled cluster is the small-molecule accuracy reference in
vibe-qc. method="ccsd" runs DF-CCSD; method="ccsd(t)" adds the
standard perturbative triples correction. The same choice can be made
explicitly with triples="none" or triples="(t)". Density fitting is
the default integral route; pass CCSDOptions(density_fit=False) for
the conventional route with exact four-index integrals (see
Conventional (non-DF) integrals).
Closed-shell QCISD and QCISD(T) are available through method="qcisd"
and method="qcisd(t)". Ground-state closed-shell CC2 is available through
method="cc2" or method="ci", citype="cc2". Full iterative CCSDT is
available through method="ccsdt" or method="ci", citype="ccsdt" for
benchmark-scale molecular calculations. Ground-state CC3 is available through
method="cc3" or method="ci", citype="cc3" for closed-shell benchmark
calculations.
Both closed- and open-shell references are handled automatically: a
closed-shell (singlet) molecule runs on an RHF reference through the
spin-adapted kernel, and an open-shell molecule (multiplicity > 1)
runs on a UHF reference through the spin-orbital UCCSD(T) kernel by
default. For a spin-pure restricted-open-shell reference, pass
ccsd_reference="rohf": the same spin-orbital kernel is used,
with ROHF supplying identical alpha/beta spatial orbitals and
per-spin Fock matrices.
See the canonical CCSD(T) tutorial for a worked, paste-and-run walkthrough of every reference type below.
At a glance¶
High-level entry point |
|
Low-level entry point |
|
Reference |
CCSD: RHF, UHF, or ROHF; CC3: RHF; CCSDT: RHF or common-orbital ROHF |
Integral form |
CCSD: density-fitted or exact four-index; CC3/CCSDT: exact four-index MO Hamiltonian |
Scope |
CCSD: dense O(N^6) small-molecule pilot; CC3/CCSDT: dense determinant-space benchmark routes |
Validation |
in-repo spin-orbital/FCI anchors and out-of-process PySCF/ORCA comparisons |
Quick start¶
import vibeqc as vq
mol = vq.Molecule(
[
vq.Atom(8, [0.000, 0.000, 0.000]),
vq.Atom(1, [0.000, 1.499, -1.160]),
vq.Atom(1, [0.000, -1.499, -1.160]),
],
)
result = vq.run_job(mol, basis="cc-pvdz", method="ccsd(t)", output="h2o_ccsd_t")
print(result.ccsd.e_ccsd_correlation)
print(result.ccsd.e_t)
print(result.energy_total)
run_job writes the usual .out / citation sidecars and attaches the
post-SCF result as result.ccsd.
CC2¶
method="cc2" implements the ground-state second-order approximate coupled
cluster model of Christiansen, Koch, and Jorgensen. It solves the complete
singles projection together with the first-order doubles equation built from
the T1-transformed Hamiltonian and the diagonal [F,T2] commutator:
result = vq.run_job(mol, basis="cc-pvdz", method="cc2", output="h2o_cc2")
print(result.ccsd.e_ccsd_correlation) # CC2 correlation energy
print(result.energy_total)
CC2 currently supports closed-shell RHF references, frozen occupied cores,
density fitting, and the conventional exact-integral route selected by
CCSDOptions(density_fit=False). It is an energy-only route and does not
accept triples=. The dense implementation shares CCSD’s integral tensors and
small-molecule memory envelope.
CC3¶
method="cc3" implements the iterative CC3 model of Koch and coworkers.
Singles and doubles are optimized to convergence while connected triples are
regenerated from the CC3 triples equation on every iteration and coupled back
into the singles and doubles residuals:
result = vq.run_job(
mol,
basis="sto-3g",
method="cc3",
cc3_options=vq.CC3Options(
conv_tol_energy=1.0e-10,
conv_tol_residual=1.0e-8,
),
output="h2o_cc3",
)
print(result.e_correlation)
print(result.e_total)
print(result.t3_norm)
The high-level route uses canonical RHF orbitals and requires a closed-shell
singlet. It freezes chemical-core orbitals by default; use
CC3Options(n_frozen_core=0) for an all-electron calculation. The low-level
vq.cc3(hamiltonian, options) entry point accepts an orthonormal
spatial-orbital Hamiltonian and leaves frozen-core selection explicit.
CC3 is an energy-only, exact-integral benchmark route. The current
determinant-space implementation evaluates the defining commutators directly,
so its memory and runtime grow combinatorially and it is intended for compact
orbital spaces. Iteration details are written at the verbose output level;
the standard .out contains the converged summary and amplitude norms.
Full CCSDT¶
method="ccsdt" solves the full coupled-cluster singles, doubles, and triples
equations. The implementation evaluates the defining projected similarity
transform directly in determinant space, including all connected and
disconnected terms generated by T1 + T2 + T3:
result = vq.run_job(
mol,
basis="sto-3g",
method="ccsdt",
ccsdt_options=vq.CCSDTOptions(
conv_tol_energy=1.0e-10,
conv_tol_residual=1.0e-8,
),
output="h2o_ccsdt",
)
print(result.e_correlation)
print(result.e_total)
print(result.t3_norm)
The high-level route uses RHF orbitals for closed shells and common-orbital
ROHF orbitals for open shells. It freezes chemical-core orbitals by default;
set CCSDTOptions(n_frozen_core=0) for an all-electron calculation. The
low-level vq.ccsdt(hamiltonian, options) function accepts an orthonormal
spatial-orbital Hamiltonian and leaves frozen-core selection explicit.
CCSDT is an energy-only, exact-integral benchmark route. Its determinant-space
algorithm grows combinatorially, so it is intended for compact orbital spaces
and method validation rather than large production molecules. It does not
accept the perturbative triples= selector or CCSDOptions. Iteration details
are written at the verbose output level; the normal .out contains the
converged summary and amplitude norms.
Triples selector¶
The high-level driver accepts a triples= selector for the perturbative
triples mode:
vq.run_job(mol, basis="cc-pvdz", method="ccsd", triples="none")
vq.run_job(mol, basis="cc-pvdz", method="ccsd", triples="(t)")
vq.run_job(mol, basis="cc-pvdz", method="ccsd", triples="[t]")
vq.run_job(mol, basis="cc-pvdz", method="ccsd", triples="A-CCSD(T)")
method="ccsd(t)" is equivalent to method="ccsd", triples="(t)".
Passing triples="none" disables the perturbative correction even when
the method keyword is ccsd(t), and the output / citation method label
follows the effective choice.
triples="[t]" selects the fourth-order bracket correction CCSD[T],
which is identically the original CCSD+T(CCSD) of Urban and coworkers
(1985); the spelling triples="+T(CCSD)" is accepted as a synonym.
The standard (T) is [T] plus the fifth-order singles-triples
coupling; the result reports both pieces separately as
result.ccsd.e_t4 and result.ccsd.e_t5_st, and the .out block
prints the decomposition. CCSD[T] is closed-shell only; the open-shell
kernel implements the standard (T).
triples="A-CCSD(T)" selects the closed-shell asymmetric/Lambda triples
correction. The output and citation route record the effective method as
a-ccsd(t) and the result exposes the Lambda residual as
result.ccsd.lambda_residual_norm.
AutoCI-style selector¶
run_job also accepts the shared citype= spelling planned for the
single-reference CI/CC ladder:
vq.run_job(mol, basis="sto-3g", method="ci", citype="cisd")
vq.run_job(mol, basis="cc-pvdz", method="ci", citype="ccsd(t)")
vq.run_job(mol, basis="sto-3g", method="ci", citype="cc3")
vq.run_job(mol, basis="sto-3g", method="ci", citype="ccsdt")
Supported values are cisd, cc2, ccsd, ccsd(t), cc3, ccsdt, ccd,
lccd, lccsd, cepa(0)..cepa(3), qcisd, and qcisd(t).
For CISD, pass cisd_options=vq.CISDOptions(nroots=..., max_det=...)
to request multiple roots or raise the determinant-space guard.
Coupled-pair variants: CCD, LCCD, LCCSD, CEPA(n)¶
The classic coupled-pair ladder between MP2 and CCSD is available as
variants of the same closed-shell DF kernel, either directly as
method= strings or through citype=:
vq.run_job(mol, basis="cc-pvdz", method="ccd") # CCSD without singles
vq.run_job(mol, basis="cc-pvdz", method="lccd") # linearized CCD
vq.run_job(mol, basis="cc-pvdz", method="lccsd") # linearized CCSD == cepa(0)
vq.run_job(mol, basis="cc-pvdz", method="cepa(1)") # Meyer's CEPA
What each variant does:
Variant |
Definition |
|---|---|
|
CCSD with the singles amplitudes frozen at zero (Čížek 1966). |
|
Linearized CCD: the doubles residual truncated to terms linear in T2. |
|
Linearized CCSD (singles + doubles, all nonlinear terms dropped). |
|
The linearized residual plus Meyer’s pair-specific EPV shifts (coupled-electron-pair approximation). |
All variants require a closed-shell (RHF) reference; an open-shell
molecule raises NotImplementedError (use ccsd / ccsd(t) with the
UHF or ROHF reference instead). None of them defines a (T)
correction, so triples= is rejected. On the low-level API the same
selection is vq.CCSDOptions(cc_variant="cepa(1)", compute_triples=False)
with vq.run_ccsd.
Two implementation properties are worth knowing. First, there is no
second equation set: the linearized variants extract the linear part of
the canonical CCSD residual algebraically exactly (a polynomial-stencil
construction, machine-precision-validated against the in-repo
spin-orbital anchor). Second, the CEPA shift convention is the
closed-shell table of Wennmohs and Neese (Chem. Phys. 343, 217 (2008))
as implemented by ORCA’s MDCI module, validated to sub-microhartree
agreement against out-of-process ORCA 6.1 RI-CEPA/n with the same
auxiliary basis. Note that CEPA(1..3) energies depend on the choice of
occupied orbitals: vibe-qc uses canonical MOs, which corresponds to
ORCA’s %mdci Localize false (ORCA localizes internal orbitals by
default and will differ by a few tenths of a millihartree on that
account).
QCISD and QCISD(T)¶
QCISD is available as method="qcisd" or
run_job(method="ci", citype="qcisd"). QCISD(T) is available as
method="qcisd(t)", method="qcisd", triples="(t)", or
citype="qcisd(t)".
Like the coupled-pair variants, QCISD currently uses the closed-shell
RHF kernel only. Open-shell molecules raise NotImplementedError; use
ccsd / ccsd(t) with the UHF or ROHF reference for radicals.
Implementation detail: QCISD is built by exact two-parameter monomial
selection from the validated CCSD residual. It keeps the published
QCISD operator set, including the T2-quadratic disconnected quadruple
term, and uses the CI-like energy expression without the quadratic
T1*T1 contribution. QCISD(T) follows the original
Pople-Head-Gordon-Raghavachari convention: on QCISD amplitudes the
triples increment is E[T] + 2*E_ST, not the CCSD(T) E[T] + E_ST
combination. This is pinned against out-of-process ORCA 6.1
RI-QCISD(T) with canonical orbitals and the same RI auxiliary basis.
Low-level API¶
Use the low-level API when you already have a converged RHF reference or need explicit iteration controls:
import vibeqc as vq
basis = vq.BasisSet(mol, "cc-pvdz")
hf = vq.run_rhf(mol, basis, vq.RHFOptions())
opts = vq.CCSDOptions(
triples="(t)",
n_frozen_core=vq.chemical_core_orbital_count(mol),
conv_tol_energy=1e-10,
conv_tol_residual=1e-9,
)
cc = vq.run_ccsd(mol, basis, hf, opts)
print(cc.e_ccsd_t)
If opts.aux_basis is empty and density_fit=True, run_ccsd
auto-resolves the matching RI auxiliary basis for the orbital basis.
The legacy boolean compute_triples remains supported on
CCSDOptions; the triples property is the human-readable front end to
the same setting.
Conventional (non-DF) integrals¶
For strict parity against conventional CCSD(T) in other programs, run
the coupled-cluster step on exact four-index MO integrals instead of the
RI factorisation. Pass density_fit=False; no auxiliary basis is needed
(or used), so this also works for basis sets without a registered RI
auxiliary:
cc = vq.run_job(
mol,
basis="cc-pvdz",
method="ccsd(t)",
ccsd_options=vq.CCSDOptions(density_fit=False, n_frozen_core=0),
)
Everything downstream of the integral assembly (amplitude equations,
DIIS, the (T) correction) is identical to the DF path; only the source
of the (pq|rs) blocks changes. The .out block reports the route
honestly: Algorithm = CCSD(T) (no DF- prefix) and
Density fitting = off, with no RI auxiliary basis line. Both the
closed-shell (RHF) and the open-shell (UHF / ROHF) kernels support the
conventional route; all-electron conventional CCSD(T) and UCCSD(T) are
validated against PySCF’s conventional kernels to a few nanohartree on
H2O and the OH radical in cc-pVDZ (tests/test_ccsd_canonical_noDF.py).
The conventional route holds the AO ERI tensor (nbf^4 doubles) and the
correlated-window MO tensor in memory during the integral build, so it
is a small-molecule route by design. The RI error of the default DF
route is orders of magnitude below chemical accuracy (about 1e-5 to
1e-4 Ha on the correlation energy with the matched -ri auxiliary), so
DF remains the right default for everything except integral-exact
cross-code parity work. FNO-CCSD(T) and the DLPNO pilots remain DF-only.
Open-shell (UHF) references¶
For an open-shell molecule (multiplicity > 1), run_job(method="ccsd(t)")
runs UHF and then the spin-orbital UCCSD(T) kernel automatically. No extra
flags are needed; the result is attached as result.ccsd with the same
CCSDResult fields as the closed-shell path.
import vibeqc as vq
ch3 = vq.Molecule([...], charge=0, multiplicity=2) # methyl radical
result = vq.run_job(ch3, basis="cc-pvdz", method="ccsd(t)")
print(result.ccsd.e_ccsd_t)
The open-shell kernel evaluates the spin-orbital coupled-cluster equations
directly on the UHF reference, so it reproduces canonical UCCSD/UCCSD(T)
(validated against PySCF cc.UCCSD/UCCSD(T) to well under a microhartree).
Use the low-level run_uccsd(mol, basis, uhf_result, CCSDOptions(...)) when
you already have a converged UHF reference:
basis = vq.BasisSet(ch3, "cc-pvdz")
uhf = vq.run_uhf(ch3, basis, vq.UHFOptions())
cc = vq.run_uccsd(ch3, basis, uhf, vq.CCSDOptions(triples="(t)"))
Open-shell SCF is sometimes harder to converge than closed-shell: if the
UHF reference does not converge, CCSD is skipped (no coupled-cluster numbers
are produced from an unconverged reference). For difficult radicals, pass a
uhf_options=vq.UHFOptions(...) with a level shift / higher max_iter to
run_job.
Frozen natural orbitals (FNO)¶
Canonical CCSD(T) cost is dominated by the size of the virtual space. Frozen natural orbitals shrink it: the dominant virtual natural orbitals of the MP2 density are kept and the rest are discarded before CCSD(T), recovering almost all of the correlation energy at a fraction of the cost (DePrince and Sherrill, J. Chem. Theory Comput. 9, 2687 (2013)).
Turn it on with fno=True on CCSDOptions:
import vibeqc as vq
# occupation-threshold selection (default 1e-5): keep every natural orbital
# whose MP2 occupation is at or above the threshold
vq.run_job(mol, basis="cc-pvtz", method="ccsd(t)",
ccsd_options=vq.CCSDOptions(fno=True))
# or keep a fixed fraction of the virtual space
vq.run_job(mol, basis="cc-pvtz", method="ccsd(t)",
ccsd_options=vq.CCSDOptions(fno=True, fno_keep_fraction=0.6))
The retained virtuals are semicanonicalized (the virtual Fock block is
re-diagonalized) so the perturbative (T) stays exact in the truncated space.
By default a delta-MP2 correction E_MP2[full] - E_MP2[trunc] is added back
(fno_delta_mp2=True), which recovers most of the small correlation lost to
truncation. The .out file reports how many natural orbitals were kept and the
size of the delta-MP2 correction.
The result is an FNOCCSDResult with the same fields as CCSDResult plus
n_virtual_kept, n_virtual_total, and delta_mp2. The low-level entry point
is vq.cc.run_fno_ccsd(mol, basis, rhf_result, options).
FNO options:
Option |
Default |
Meaning |
|---|---|---|
|
|
enable the FNO virtual-space truncation |
|
|
keep natural orbitals with occupation |
|
|
if set, keep this fraction of virtuals (overrides the threshold) |
|
|
add the |
With no truncation (fno_keep_fraction=1.0 or fno_occ_threshold=0) FNO-CCSD(T)
reproduces canonical CCSD(T) to machine precision, since CCSD is invariant to
virtual rotation and the semicanonicalization restores the canonical (T).
Result Fields¶
CCSDResult exposes:
e_hfe_ccsd_correlatione_ccsde_te_ccsd_te_totaln_iter,convergedt1_norm,t2_normcc_trace
The per-iteration cc_trace entries are CCSDIteration records with
energy, energy change, residual norms, and the active DIIS subspace.
Limits¶
The current canonical engine is deliberately conservative:
RHF (closed-shell), UHF (open-shell default), and ROHF (
ccsd_reference="rohf") references are all supported. All three drive the same coupled-cluster equations (the closed-shell path spin-adapts them; the open-shell paths evaluate them in spin-orbital form).Dense O(N^6) pilot implementation for small molecules. Closed-shell uses the spin-adapted kernel; open-shell uses the spin-orbital kernel (same equations, validated to machine precision against the in-repo spin-orbital reference), which carries the usual spin-orbital factor in cost and memory.
Density fitting is the default production path; the conventional exact-integral route (
density_fit=False, see above) is supported for cross-code parity work on small molecules. FNO and the DLPNO pilots require density fitting.Frozen occupied cores are supported. The virtual space can be truncated with frozen natural orbitals (
fno=True, see above); explicit frozen-virtual lists are not supported.FNO is closed-shell (RHF reference) only so far; open-shell FNO is a roadmap item.
A-CCSD(T)andCCSD[T]/CCSD+T(CCSD)are implemented for closed-shell CCSD only, not for QCISD.Full CCSDT is available for RHF and common-orbital ROHF references. Its determinant-space implementation uses exact MO integrals and is intended for compact benchmark spaces; it is separate from the O(N^6) CCSD kernels.
Ground-state CC3 is available for closed-shell RHF references. Its determinant-space implementation uses exact MO integrals and is intended for compact benchmark spaces.
See also¶
AICCM A-namespace correlation APIs:
run_ccm_ccsd(method="aiccm2026dev-a")is union-and-weight Γ-CCM CCSD(T).run_ccm_uccsduses a neutral fitted-torus control and is not a Γ-CCM or χ-CCM result.χ-CCM / aiccm2026dev-b: periodic DLPNO-CCSD(T) on the finite torus (χ-CCM, 3-D).
Open-shell AICCM: union-and-weight Γ-CCM open-shell methods, A-namespace neutral-control UCCSD(T), and χ-CCM open-shell methods.