Release notes
Version v0.16.0 - 2026.08.25
Breaking
- Integrals are owned by whoever creates them (behavioral change). Density-fitted MO integrals depend on the orbitals, but a set generated implicitly by
@cc/@fci/@ciphiused to persist for the rest of the session and be silently reused — including after the orbitals had changed (a second@dfhf,@localize, an orbital-optimized method). Only one special case was patched (wf.dump=""/dump4core_onlyrestarts forced a regeneration). Now a driver that has to create the integrals itself builds them from the current correlation orbitals and deletes them when it returns, so a stale set cannot be reused; integrals created explicitly with@dfints(or read from an FCIDUMP) persist and are the user's to refresh.setup_fcidump_if_needed!and its restart special case are gone. Scripts that relied on one implicit generation serving several@cccalls now repeat that generation (cheap next to the CC iterations) — insert@dfintsto keep the previous caching. Unchanged:wf.dump=""andwf.dump4core_onlyremain reference-orbital selectors for restarts, independent of where the integrals come from. Every correlated run now prints one line saying which integrals it uses (exact AO direct / transient MO dump / per-run DF / fcidump). FDumpnow is parametric in the element type of the integrals, so thatFDump{ComplexF64,4}can be used for complex integrals.
Changed
- The CC dressing no longer re-reads the integral blocks from the dump every iteration.
calc_dressed_intsextracts each block throughdetri_int2!, which gathers it in two passes – the second over the TRANSPOSED leading pair. A gather is contiguous only along its first index, so every block the dressing needs has a pass whose runs arenocc*8bytes (240 bytes atnocc=30), far below a page and scattered across essentially every page of each selected plane; the whole traversal then repeats every iteration. Measured on a benzene-dimer/aug-cc-pVDZ dump (NORB=372,nocc=30,nvirt=342,int271.5 GB), disk read for ONE extraction:vovv185.0 GB for 8.94 GB of data (21x, and 2.6x the whole file),oovv17.2 GB for 0.78 GB,vovo5.8 GB,voov4.9 GB – ~213 GB per dressing pass, of whichvovvalone is 87%. This is what made calculations whose integrals exceed RAM thrash despite the batching elsewhere. The blocks are bare integrals (only the T1 dressing on top of them changes), sobare_ints2!now caches them on scratch once per run: ~11.5 GB read back contiguously in place of ~213 GB of scattered reads. Blocks larger than a quarter of the dump are left uncached, which keeps a pathologicalvvvv(nvirt^4, 128 GB there) off scratch. Measured end to end on that dimer, 3 DCSD iterations: disk reads 862.7 -> 454.5 GB, major faults 4.44M -> 3.58M, CC time 644 -> 420 s, with the steady-state iteration going 222 -> 103 s (2.2x; the first iteration is unchanged since it fills the cache). Energies are bit-identical, and there is no measurable cost when the dump is resident (benzene monomer/cc-pVDZ CCSD: 102.6 s vs 103.5 s). The cache is temporary, sodelete_temporary_files!drops it at the end of every driver run and a regenerated dump can never be served a stale block. Theint2/int1memory-map handles of the closed-shell density-fitted dump are also closed now instead of leaked (one open descriptor per@dfints). - The 4-index 2-electron integral transformation (
transform_int2!/transform_int2_Q!, used for RHF→UHF FCIDUMP conversion and AO→MO derivation) is now fully BLAS-3: the triangular-output transform's final fold, previously a BLAS-1/2 scalar-axpy + rank-1 outer-product loop, is now a GEMM (still exploiting ther≤spacking). The output-index block size now adapts to the available memory (see below) so the streaming scratch stays bounded for large orbital counts (previously it eagerly reserved a fixed multiple ofnin³), while using a single pass over the integrals when memory is ample. - SVD-DC methods now localize orbitals before amplitude decomposition by default (
cc.localize=true), and LLAMA now usesampsvd_pivotol_mode=:maxdimby default for more robust rank selection in difficult cases such as ghost-atom calculations. - The minimal basis used for SAD guesses and IAO construction now defaults to MINAO. It can be overridden explicitly with
scf.minaoandloc.minao, or via a"minao"entry in the basis dictionary. - Batching of 4-index integrals is implemented in
kextroutines. This should substantially reduce the memory demand of closed-shell and open-shell CCSD/DCSD. - The
kext-type contractions are implemented for unrestricted full-triples methods (UCCSDT and UDC-CCSDT). @savewfaccepts orbital coefficients as matrix or tuple of matrices.- Use LLAMA for svd decompositions.
- Some speedups in (T) and integrals calculations.
- The test suite was migrated to the TestItems framework (
@testitem), enabling per-test run/debug in the VS Code Test Explorer and parallel execution. Each test file intest/is wrapped in an@testitemtagged by category (:fcidump,:cc,:df,:complex, …, plus:quickor:long). Run quick tests withPkg.test(), or all tests withPkg.test(test_args=["all"]). SetELEMCO_TEST_NWORKERS=Nto run test items in parallel acrossNworker processes. Subsets can be selected from the REPL by passing tags and/or item names, e.g.Pkg.test(test_args=["df"])orPkg.test(test_args=["h2o","complex"]); the old group names map to tags (FCIDUMP→:fcidump,DF→:df, …). The same tag/name filtering is also available in the VS Code Test Explorer.
Added
@moints— MO integrals from the exact (non-DF) AO integrals. The non-DF counterpart of@dfints: it transforms the exact AO integrals to the MO basis of the current orbitals and keeps the resulting dump inEC.fdfor the rest of the session (generating the AO integrals first if they are not on file yet, as@intswould). Previously the exact-AO route could only produce a transient MO dump, derived and discarded inside a driver run, so@write_intshad nothing to write and repeated runs each retransformed. Like the density-fitted dump the result covers the active space (frozen core folded intoint0/int1, deleted/frozen virtuals dropped) and follows the "whoever creates them, owns them" rule — it persists and is the user's to refresh when the orbitals change. Note that AO-direct methods (MP2/CCSD/DCSD and friends) are faster without it, since they never form the MO integrals at all.- libcint
CINTOptoptimizer for the exact-AO 4-index generation. The 2-electron libcint wrappers passed a NULL optimizer, so every quartet call recomputed the shell-pair setup data. The generation sweeps (pm_integrals!viacalc_2e4idx_tri_blockwise!, incl. the Schwarz-bounds pass) now allocate a per-basisCIntOptonce, share the read-only handle across all threads, and free it deterministically after the sweep. Honest measured gain: 1.06-1.07x on the ERI kernel across cc-pVDZ/TZ/QZ water dimers – far below the ~2x sometimes quoted forCINTOpt, because for generally-contracted correlation-consistent sets the quartet arithmetic dominates the pair-data setup the optimizer caches (segmented/low-angular-momentum bases would gain more). Values shift only at the ulp level (~1e-15, libcint-internal summation paths); pinned by a unit test at 1e-13. - Exact-AO generation computes only the stored block-triangle (Hermiticity row cut). The ± supermatrix store keeps the lower block-triangle of
Vs/Va[tri(mu nu), tri(rho sigma)](the upper part is the conj-Hermitian mirror reconstructed at read time), but the generation used to compute every bra pair and let the writer discard the mirror rows. Now the ERI kernel skips the bra shell pairs that lie entirely below a block's row floor (max(p,q) >= first(sigma-block)is the exact kept-pair predicate; blocks are shell-aligned, so the shell-level skip is exact, not conservative) and the ± fold is restricted to the kept rows. The store is BIT-identical; roughly half the libcint quartets and fold flops disappear on every system, compact ones included (unlike screening). Measured (min of 3, 8 threads): water dimer cc-pVQZ (nao=230) 33.1 s -> 19.2 s (1.72x), 1 water cc-pVTZ 1.36x, 4-water chain cc-pVTZ 1.50x unscreened / 1.23x on top of screening (sub-multiplicative: screening already removes far quartets). Small systems are block-granularity-limited (few sigma-blocks -> coarse floors, kept fraction 0.60 at nao=58 vs the 0.51 ideal at nao=230).pm_integrals!(...; rowcut=false)restores the full computation (testing). - Cauchy-Schwarz prescreening of the exact AO integrals (
int.screen, default1e-12). The four-index generation previously computed every shell quartet. It now precomputes the shell-pair boundsQ[P,R] = sqrt(max|(pr|pr)|)(nshell^2/2diagonal quartets, i.e. free next to thenshell^4generation) and skips any quartet withQ[P,R]*Q[Q,S] < int.screen, storing it as an exact zero. Set@set int screen=0to compute every quartet. The gain is entirely a function of how extended the system is - a single compact molecule has no negligible quartet at this threshold and is unaffected (measured 1.02x, i.e. the screening overhead is nil), while for separated fragments it grows quickly: two waters 15 bohr apart 1.50x, a four-water chain (nao=232) 2.37x, a six-water chain 2.59x, with 50-88% of quartets skipped. This is the usualN^4 -> N^2asymptotic effect, so it matters most exactly where the integrals are expensive. @ints/@hfnow announce the exact-AO integral generation (basis-function count and the resulting +/- store size) and report the time taken, instead of appearing to hang silently on large cases.- Memory-management utilities and options.
available_memory()estimates how much memory may reasonably be used for a large scratch allocation as a fraction (default0.8) of the currently available memory — the minimum of the node's free memory (≈ MemAvailable, so reclaimable page cache counts as free), any enforced cgroup budget (cgroup_memory_available, covering SLURMConstrainRAMSpace, containers and k8s — cgroup v1 and v2), and any SLURM per-job limit (slurm_memory_limitfromSLURM_MEM_PER_NODE/SLURM_MEM_PER_CPU) — after aGC.gc(true)so Julia's own freed memory is reflected.available_memory(EC)honors a user budget. Newmemoptions:@set mem budget=<GB>sets an explicit budget (≤0= automatic, the default) and@set mem fraction=<f>tunes the fraction used in automatic mode. Currently used to size the blocked 4-index integral transformation (so fat/constrained nodes get the right number of passes over the integrals); intended for broader memory management across the package. - Non-DF (exact) AO integrals and AO-direct coupled cluster (issue #290). Exact four-index AO electron-repulsion integrals can now be generated and used without density fitting.
@intswrites the AO integrals to scratch files (the ± supermatrix store,S_AA,h_AA);@hf/@uhfbuild HF/UHF from them (the AO Fock is assembled by streaming the triangular integrals one slab at a time inO(nao²)memory, exploiting ther≤spacking — the fullnao⁴integral tensor is never formed), and closed- and open-shell MP2/CCSD/DCSD run AO-direct: the frozen core is folded into an effective one-electron Hamiltonian and both the T1-dressed integrals and thekext4-external term are contracted straight from the AO integrals each iteration (occ-early one pass, no full MO integral set is ever formed). The higher methods now run AO-direct as well, off a persisted half-transformed integral store (see below); only FCI still retransforms the AO integrals to a transient MO dump per call. TheEC.fdFCIDUMP object is now strictly MO-only. Set@set int df=falseto default new calculations to the exact-AO route;@set int ao_direct=falseforces the derived-MO-dump route. - Persisted ± (plus/minus) supermatrix store for the exact AO integrals (
PMStoremodule). The two ±-symmetrized integral combinationsVs/Va[tri(μν),tri(ρσ)] = ⟨μν|ρσ⟩ ± ⟨νμ|ρσ⟩are symmetric (real) / Hermitian (complex) matrices over the packed pair space; only their lower block-triangle is stored as dense σ-aligned column panels (ao_pm_s/ao_pm_a, ≈n⁴/4). The ± fold is fused into the ERI generation — each shell-aligned ket-column block is assembled in a bounded RAM slab, folded and written directly as panels — so no jointly packedn⁴/2array is formed at any point. This is now the only representation of the exact AO integrals: the previously alternative jointly packedao_int2file and everyif joint … else ± …branch behind it are gone, leaving exactly two integral paths — an MO FCIDUMP (EC.fd, triangular) or the AO ± store. Theint.ao_pmandcc.use_pm_kextoptions were removed with it.- The ± split is what makes both index pairs triangular at once:
⟨pq|rs⟩ ≠ ⟨qp|rs⟩, so the bra pair cannot be packed on its own — only the joint symmetry⟨pq|rs⟩ = ⟨qp|sr⟩exists, and separating it into a symmetric and an antisymmetric supermatrix turns that one joint symmetry into two independent triangular packings (which is also why the stored object can ben⁴/4rather thann⁴/2). The exact flop ratio against the MO contraction,2no/((n+1)(o+1)), is the product of three effects: the bra pair packedn² → n(n+1)/2(×1.99 atn=232), two GEMMs instead of one (÷2), and the occupied pair packedo² → o(o+1)/2(×1.90 ato=20) — the last available only because the ± form supplies both(pq)orders, so thatK2[q,p,j,i] = K2[p,q,i,j]can be used. - Measured 2.15–2.35× on the kext against the MO path at (H₂O)₄/cc-pVTZ (nao 232, 20 correlated occupied), with the same 2× on disk. The advantage is governed by the number of correlated occupied orbitals, not by the basis size: it needs a right-hand side (
ntri_oo = nocc(nocc+1)/2) wide enough for the panel GEMM to reach peak, so atnocc ≲ 8the ± kext is no faster (the GEMM then runs at ~300–370 of ~715 GFLOP/s) even for a large basis — benchmarks belownocc ≈ 12are not representative. - All AO consumers run on the store: the
kext4-external term as zero-copy panel GEMMs, the T1-dressing occ-early sweeps and the AO-HF/frozen-core Fock builders at halved integral streaming, the open-shell αβkextvia an explicit ±-fold of the αβ density, and the AO→MO transform for the derived dump (pm_transform, straight from the panels). Complex integrals are supported throughout (pair-internal swaps are conjugation-free ± signs; the block mirror conjugates). - Three per-iteration costs were removed: the store handle is kept open across CC iterations instead of being re-mapped every iteration (re-mapping re-faulted the whole store through the page table — ~0.25 s per call for a 6 GB store, 21–26 % of the kext contraction); the ± fold and the four-quadrant scatter around the panel GEMMs are fused and threaded (bit-identical output, kext contraction 1.07–1.08 × and its non-GEMM share 11.5 % → 1.7 %, per-call allocation down 21 % / 40 % for the closed- and open-shell variants); and the
rsblocking of the MO-path 4-external contraction now grows with the width of the result instead of being fixed at 128, which streamed the result arraynrs/128times (1.30–1.35× for ≥ 17 correlated occupied orbitals; narrower cases keep the previous, bit-identical blocking).
- The ± split is what makes both index pairs triangular at once:
- AO-direct higher methods via a persisted half-transformed integral store. The one-index→occupied half-transform
⟨iν|ρσ⟩ = Σ_μ ⟨μν|ρσ⟩ C_occ[μ,i]is the universal downstream intermediate for the correlated methods, and its bra-occupied transform is T1-independent — so it is built once per orbital set (per spin) from the ± store and streamed with single-threadedpread+posix_fadvise(WILLNEED)(measured ≈4.9 GB/s, at half the disk of a fulln⁴/2store), replacing per-iteration re-streaming of the whole integral set. Off this store the higher methods now run AO-direct — with no transient MO dump: standalone MP2/UMP2/RMP2; CCSD(T)/DCSD(T) and UCCSD(T)/UDCSD(T); the Lagrange (Λ) equations and correlated properties, closed-shell (Λ-CCSD/Λ-DCSD, ΛCCSD(T)/ΛDCSD(T)) and unrestricted (ΛUCCSD/ΛUDCSD, ΛUCCSD(T)/ΛUDCSD(T)), including the 1-RDM/dipole; and EOM-CCSD/EOM-UCCSD excitation energies. Each MO integral block a method needs (they all carry ≥1 occupied index) is a cheap GEMM-only transform of the stored half-transform, written mmapped in the consumer's index order — a block whose occupied index sits on a ket is reached by particle-exchange/Hermiticity relabelings, and mixed-spin blocks simply put the other spin's coefficients on the free slots (the βα-looking reads of the unrestricted (T) resolve to the same five αβ blocks). The Λ 4-external term reuses the ±kext(pm_K2!/pm_K2ab!) by folding Λ2 with the dressed virtual bra, and the Λ general-orbital singles term — the virtual-occupied block of a generalized Fock,2J−Kclosed-shell,J(D^α+D^β)−K(D^σ)unrestricted — is read straight off the half-transformed store (ht_jk_columns!) instead of building thenao×naoFock and keeping one block of it: the store's bra index is the occupied index this term carries, and its two roles supply both orderings with the virtual on the same ket-2 slot (the exchange via the conjugation-free particle symmetry⟨mq|pe⟩ = ⟨qm|ep⟩). One sequential pass reading each stored element once,2·nocc·nao³multiply-adds against the previousnao⁴, measured 9.4× (nao 114) to 61× (nao 264) per call and 11.6× on a whole unrestricted Λ iteration; nonocc·norb³general-orbital block is ever formed. All match the derived-MO-dump reference to≤1e-8…1e-14. Basis sets with linearly-dependent (deleted) orbitals are handled too: the redundant orbitals are frozen out of the correlation treatment by the usualfreeze_orbitals!machinery and the AO←MO map keeps only the active columns, so no special casing is needed (verified to machine precision against the derived dump for CCSD, CCSD(T), Λ-CCSD, EOM-CCSD, UCCSD and ΛUCCSD on a rank-deficient basis). The doubles-only methods run AO-direct as well — CCD/DCD and the quasi-variational QV-CCD/QV-DCD need only the bare blocks that the T1 dressing already yields for an empty T1 — and so do their orbital-optimized variants OQV-CCD/OQV-DCD: instead of re-transforming an MO integral dump every macro-iteration, the orbital rotation is folded into the MO coefficients and the integral blocks are rebuilt straight from the AO integrals in the rotated basis, with the general-orbital block of the orbital gradient (⟨μν|ρi⟩) kept in the AO basis — the gradient only ever contracts its three general indices with the virtual rotation, so it is indifferent to whether they are MO or AO. The half-transformed store is rebuilt for the rotated occupied orbitals each macro-iteration: its bra is the occupied space, so unlike the T1 dressing (which leaves the occupied bra invariant) it cannot be built once. The Brueckner variants BQV-CCD/BQV-DCD run AO-direct through the same machinery: they differ from the orbital-optimized ones only in what drives the rotation — the singles residual, extracted from the same H·T2 call, instead of the orbital gradient — which needs no integral block the AO path does not already build. FCI is the only remaining method that still derives a transient MO dump. Complex integrals are supported for the directly-transformed blocks; blocks that would need a bra↔ket Hermiticity swap are real-only (pending complex AO integrals). - Orbital localization support with Intrinsic Bond Orbitals (IBO), Pipek-Mezey, and Foster-Boys localization for occupied orbitals, plus optional orthogonal projected atomic orbitals (OPAOs) for virtual orbitals.
- Complex-valued calculations: Systematic support for
ComplexF64integrals and amplitudes throughout the codebase. When a complex FCIDUMP is loaded,ECInfo{ComplexF64}propagates the element type through solvers, tensor tools, CC methods, EOM, and interfaces. Key changes:TFDump/QFDumptype aliases are now parametric (FDump{T,3}/FDump{T,4})- DIIS and Davidson solvers are parametric (
Diis{T},Davidson{T}) with correct Hermitian symmetry - Tensor load/save/mmap defaults use
ec_eltype(EC)instead ofFloat64 - All CC methods (CCSD, DCSD, (T), Λ-CCSD(T), SVD-DC) propagate element type through amplitudes, residuals, and energy accumulators
- EOM-CCSD/EOM-DCSD trial vectors and Hamiltonian matrices use
ec_eltype(EC) - Biorthogonal HF (
left_from_right_rotations) usestransposeinstead ofadjoint— a correctness fix for complex orbitals (i.e, the resulting left coefficients are complex conjugate of the actual left coefficients. This might change if it turns out to be too confusing.) - FCI module:
Symmetric→Hermitianin P-space diagonalization; removed restrictiveFloat64return annotations - TREXIO interface: amplitude/determinant write functions accept
AbstractArray{<:Number}
- EOM-UCCSD/EOM-UDCSD and EOM-RCCSD/EOM-RDCSD (restricted to singlet excitations) methods have been implemented.
- FCI and CIPHI work for non-Hermitian Hamiltonians.
Fixed
scf.maxit=0crashed instead of building the Fock matrix. With no iterations the SCF loop body never ran, so the Fock matrix the loops return was never assigned and every zero-iteration run died withUndefVarError: fock(all five loops: closed-shell, open-shell, positron DF-HF, BO-HF and BO-UHF).scf.maxit=0now means "do not iterate", not "do nothing": one pass builds the Fock matrix, the energy and the residual for the given orbitals and stops before the orbitals are updated, leaving them exactly as they came in. The orbital energies stored for such a run are the Fock expectation values⟨p|F|p⟩instead of zeros — with no update there are no eigenvalues to report, and the orbitals need not be canonical. Fed a converged set of orbitals (wf.start), a zero-iteration run reproduces the converged energy and orbital energies exactly, which is what makes it useful: it is one Fock build for orbitals you already have.- Converged HF orbitals are now canonical, so post-HF methods no longer pseudo-canonicalize. An SCF iteration builds the Fock matrix, tests convergence and breaks, so the orbitals the loop left behind diagonalized the (DIIS-extrapolated) Fock matrix of the previous iteration — the final one kept occ-occ/virt-virt off-diagonal elements of the order of the remaining orbital gradient. Since
scf.thris compared against the square of that gradient's norm (sum(abs2, S·D·F − F·D·S)), the default1e-10leaves a gradient of ~1e-5and off-diagonal elements of ~1e-6— right atcc.fock_diag_thr, so(T)was tripped into a pseudo-canonicalization on ordinary converged HF orbitals (measured for water/cc-pVDZ:1.1e-6against a1e-6threshold, and the off-diagonality trackssqrt(scf.thr)exactly). The loops now canonicalize within the occupied and within the virtual space once at convergence: those rotations leave the density — and therefore the energy, and the Fock matrix itself — exactly invariant, so this costs two small diagonalizations, cannot perturb the converged solution, and drives the off-diagonal elements to machine precision (1.1e-6 → 2e-14). Diagonalizing the full Fock matrix would not work, and is not what this does: its occ-virt mixing changes the density and re-seeds off-diagonal elements of the same order it removes (measured1.1e-6 → 0.8e-6). Applied only on the converged exit, since amaxit-exhausted loop leaves the orbitals one update ahead of the Fock matrix; linearly-dependent orbitals are excluded so their sentinel energies survive. As a side effect the stored orbital energies are now the eigenvalues of the Fock matrix that is stored with them, rather than of the previous iteration's. @write_intswrites the actual electron count.wf.chargeis applied to whatever the integral source says (nelec/FCIDUMP/neutral system) at space-setup time, so an in-memory dump built by@dfints/@mointscarries the pre-chargeNELEC— and that count used to be exported verbatim. An FCIDUMP written from a charged calculation therefore described the neutral system, and reading it back gave the wrong number of electrons unless the reader happened to set the samechargeagain.@write_intsnow applieswf.chargeto theNELECit writes (andMS2to the resulting parity, following the same rulesetup_space_fd!uses), so the exported file is a self-contained description of the system; reading needs nocharge, and setting one still ionizes relative to the file, as documented.write_fcidumpgained thechargekeyword this uses (default0, i.e. the dump's ownNELEC;fditself is never modified). Deliberately not applied to theint.fcidumpoutput of@dfints: that file is parked on disk to be read back by the same session, wherewf.chargestill describes the molecule (the correlated-property path rebuilds the space from the system viarestore_system_space!), so it keeps the countsetup_space_fd!applies the charge to.@write_intsaccepts a variable as the file name. The file argument was interpolated into the macro's expression without escaping, so it was resolved in theElemComodule rather than in the caller's scope andf = "FCIDUMP"; @write_ints ffailed withUndefVarError: f not defined in ElemCo(only string literals worked).- Fix a situation when an fcidump was deleted immediately after creation if dummy atoms are present. Now the fcidump is deleted in the
@dummymacro directly and not in@setupEC. - Fix
freeze_nvirtoption (which was apparently not working at all before). - Fix redundancy detection in the orthogonal-PAO (OPAO) construction used by
@localizeand@region. The projected-PAO overlap was orthogonalized with an absolute (ALPACA) rank threshold that failed to detect the near-linear-dependencies that appear with diffuse/augmented basis sets (e.g. aug-cc-pVDZ), leaving numerically amplified junk orbitals in the (active) virtual space. The OPAOs are now built by detecting the rank from a relative eigenvalue threshold of the PAO overlap, selecting that many atom-centered PAOs by a rank-revealing column-pivoted QR of the retained eigenvectors, and orthogonalizing them with a symmetric Löwdin transformation (plus one refinement step that restores machine-precision orthonormality even for amplified low-presence directions) — removing redundancies while keeping the OPAOs local. The threshold is tied to the AO basis redundancy threshold:relthr = loc.opaofac * scf.redthr(newloc.opaofacoption, default3). This keeps the two consistent and basis-adaptive — only directions that are (near-)redundant by the same standard the basis uses are dropped, while small-but-real directions abovescf.redthr(e.g. the virtual residual of a frozen core AO, ~1e-7·λmax) are kept as genuine degrees of freedom. Because this conservative cut sits below the real (even diffuse) virtual directions, a diffuse basis with full PAO support (e.g.@regionwith all atoms supporting the virtuals) now recovers the complete virtual space instead of dropping real (diffuse) virtuals.
Version v0.15.0 - 2026.02.05
Breaking
- The fallback basis sets are not used by default anymore. Set
@set int use_fallback_basis=trueto enable them. - In
@write_ints, thetolargument is a keyword argument now (default is-1.0). wf.orbandwf.leftoptions are deprecated. The orbitals are now always written to and read from the trexio dump filewf.dump. Use@loadwfto load the orbitals from the dump file.- The
@transform_intsmacro now automatically uses biorthogonal transformations for BO orbitals. - The
@mtensor,@mviewmacros are moved fromTensorToolsto a newMTensorOperationsmodule (still reexported byTensorTools). - The function
get_spaceblockshas been moved fromTensorToolstoUtilsmodule.
Changed
- The fallback basis sets are now defined for
ao(def2-tzvppd),jkfit(aug-def2-universal-jkfit), andmpfit(def2-tzvppd-mpfit) basis sets. - Functions for
HandHeare copied from [aug]-cc-pVXZ basis sets to [aug]-p[w]CVXZ basis sets. Functions for Li and Be are copied from [aug]-cc-pCVXZ basis sets to [aug]-pwCVXZ basis sets. CCDrivermodule is renamed toDrivers.- Function
transform_fcidumphas been renamed totransform_fcidump!. - (T) methods automatically use pseudo-canonical transformation if the Fock matrix is not diagonal in the occupied and virtual subspaces.
Added
- FCI and CIPHI (selected CI) methods.
- Local options for macros: All calculation macros (
@cc,@dfcc,@dfhf,@dfuhf,@dfmcscf,@dfmp2,@fci,@ciphi,@bohf,@bouhf) now accept an optionalbegin...endblock to set options locally for that specific call. Options are automatically restored after the call completes. This is the recommended way to set options for individual calculations. - Automatic augmentation of basis sets by additional diffuse or steep functions.
- Functions to get all elements available in a given basis set (
get_available_elements4basis) and to output the basis set for a given list of elements in the molpro format (output_basis). - Augmented basis sets for jkfit vXz-jkfit and def2-universal-jkfit basis sets.
- A keyword argument
formatin@write_intsmacro to write integrals to npy files (ifformat=:npy) or to ascii file (ifformat=:ascii). - DF-HF and DF-UF orbitals are stored in trexio dump file.
- A check for changes of the molecular geometry/basis/fcidump is performed in every macro-command call. If a change is detected, the integrals are set to be recalculated or reloaded from the fcidump file. With this, the user doesn't need to worry about calling
@ECinitafter changing the geometry/basis/fcidump. - A test for dummy atoms is added. At the moment, if dummy atoms are detected, the integrals are recalculated. In the future, once we have AO-FDump support, the integrals can be reused.
- Macros
@loadwfand@savewfto load and save orbitals (etc) from/to trexio dump files.@copywfto copy trexio dump files (e.g., to make a local backup). - Wavefunction store/start functionality for coupled cluster and selected CI methods. Use
@set wf store="filename.h5"to store the wavefunction (amplitudes for CC, determinants/coefficients for CIPHI) to a TREXIO file. Use@set wf start="filename.h5"to restart a calculation from a previously stored wavefunction. Multi-state CIPHI calculations store each state in separate files (e.g.,filename_state2.h5). pt2_onlyoption for CIPHI calculations (@set ciphi pt2_only=true) to skip variational iterations and compute only the PT2 correction using stored determinants.
Fixed
- A simple sanity check of the fitting basis sets is performed (by checking whether it's an AO basis set). The error message can be turned to a warning by setting
@set int check_fit_basis=false. - Fix normalization of biorthogonal orbitals to a balanced normalization (i.e., the norms of left and right orbitals are equal).
- Integral transformation now should use much less memory and be faster.
- Fix incompatibility with julia 1.13 (replace call of an internal Base function with a simple custom implementation).
- Fix UCCSD and UDCSD for the case of no beta electrons (#272).
Version v0.14.1 - 2025.07.03
Changed
- update libcint to version 6.
- reduce allocations in the integral calculation routines.
Added
- a simple XML based interface to Molpro.
Fixed
- Fix Mac and Windows compatibility issues related to the case insensitivity of the file system. The capital letters in the file names on scratch are now converted to lower case plus a character
ß(e.g.,oVoObecomesovßoß).
Version v0.14.0 - 2025.04.16
Breaking
- the definition of
ampsvdtolthreshold for SVD methods has been changed. Now it corresponds to the threshold for the density matrix (i.e., square of the previous definition). verbosityhas been moved fromECInfotoOptions.print.time.- increase versions of dependencies: julia>1.9
- The core-entry is now required for (non-npy) FCIDUMP files in order to check whether the file is complete.
- DMRG and AtomsBase interface have been moved to extensions. In order to run DMRG, the
ITensorspackage has to be installed and loaded; and in order to useAtomsBaseinterface, theAtomsBase,UnitfulandUnitfulAtomicpackages have to be installed and loaded.
Changed
- faster closed-shell and unrestricted CCSDT and DC-CCSDT implementations.
- ANO-RCC-MB basis is now used as the minimal AO basis for the SAD orbital starting guess.
- memory buffers are now handled by functions and types in
Buffersmodule. - the precompilation is disabled for development versions.
- Buffers is moved to a separate package Buffers.jl.
- reduce memory demand in df-hf.
- remove
IterativeSolversdependency. jkfitbasis now falls back todef2-universal-jkfitif not found (e.g. for avXz basis sets).
Added
- a macro
@dummyhas been added to set some atoms to dummy atoms. - a
neuralizefunction to trickBase.mightaliasinTensorOperationsfor reshaped-buffer arrays. BufferandThreadsBuffertypes andalloc!,drop!,reset!,reshape_buf!functions.BasisBatcherstructure to calculate 3-index integrals in batches.@dfmp2to calculate df-mp2 energy without storing integrals.@freeze_orbsalso accepts now a string of indices using the +/- or :/; syntax (#186)
Fixed
- Improve parsing method names in macros. Now the parser is not confused by multiple dashes in the name and, e.g.,
@cc svd-dc-ccsdtis evaluated correctly. - SAD orbital guess for Li and Be has been fixed.
- molden export functionality has been fixed.
- thread-safe handling of buffers using ThreadsBuffer.
- if some of the npy files are not found, the integrals are read from the fcidump file (#250)
Version v0.13.1 - 2024.07.11
Added
- Store MP2 amplitudes in
cc_amplitudes_files in@cc mp2calculations.
Fixed
- Fix
maxit=0case forcccalculations.
Version v0.13.0 - 2024.07.09
Breaking
DIIS.performhas been changed toDIIS.perform!in order to allow to read the vectors and residuals asVector{}.- The signature of
newmmapfunction has changed (the type specification is now the last argument and defaults toFloat64. - The
FciDumpmodule has been renamed toFciDumps. - The
FDumptype has been changed toFDump{N}with N=3 (for triangular storage of 2-electron integrals) or 4. The logical variabletrianghas been removed (there is a functionis_triang(::FDump)now). AliasesTFDump = FDump{3}andQFDump = FDump{4}have been introduced. - The
ECInfotype now accepts onlyFDump{3}. TheFDump{4}objects have to be transformed first (the transformation functions are not implemented yet). - The triangular functions have been moved to a separate file
utensors.jl, part of theQMTensorsmodule.uppertriangularfunction has been renamed touppertriangular_index. - The driver functions and macros now return energies in an ordered descriptive dictionary
OutDict=ODDict{String,Float64}. Uselast_energyfunction to access the last energy (orlastto access the whole entry including the key and the description).
Changed
- Save the memory using in Hessian matrix calculation in dfmcscf function.
dfdumpstores the MO integrals internally in mmaped files.- The header of the
FDumpis now stored in a type-stable structureFDumpHeader.
Added
- Export of molden files (
@export_molden). At the moment the orbital energies and occupations are not exported. - Add dfmcscf part in documentation
- CCSDT and DC-CCSDT closed-shell implementations generated with Quantwo.
QMTensors.SpinMatrixstruct for one-electron matrices (e.g., MO coefficients)- An ordered descriptive dictionary for energy outputs (
ODDict) has been implemented. Each key-value entry can have a description. DIIS.perform!now accepts a tuple of functions to calculate cusomized dot-products (e.g., involving contravariants etc).
Version v0.12.0 - 2024.05.28
Breaking
- the
mp2fit(rifit) basis sets have been renamed tompfit. ERI_?e?croutines have been renamed toeri_?e?idx.
Changed
- use SVD in DIIS.
- increase number of iterations in 2D-CCSD IAS test.
- interface to
libcint_jllhas been implemented. The basis set library is added (in Molpro format), and basis sets are parsed to aBasisSetobject.GaussianBasis.jldependency is removed.
Added
- Expand README
amdmkl()function to speed up MKL on AMD machines.- CROP-DIIS option (JCTC 11, 1518 (2015)) which is less sensitive to the DIIS dimension. To activate, set
diisoptioncrop=true, the DIIS dimension can be changed usingmaxcrop(default is 3). - An option
print_initis added to the@print_inputmacro (default isfalse). If set totrue, theElemCo.jlinfo is printed again (useful if the output is redirected in julia to a file). - A simple DMRG routine is added based on
ITensors(adapted fromITensorChemistry.jl). - A Molpro interface to import matrop matrices (orbitals or overlap).
Fixed
- Get rid of error message from git if .git is not available (e.g., in the case of the released version).
- Sort orblist, which fixes issues if user occupations are not provided in a sorted list.
- Fix amplitudes before Hylleraas energy calculation for FR-CC, which will properly report the energy in a (2,2) (single iteration) calculation.
Version v0.11.1 - 2024.04.12
Changed
- Remove
ArgParsedependency and set[compat]section inProject.toml.
Version v0.11.0 - 2024.04.12
Breaking
EC.ms(previously of typeMSys) inECInfois renamed toEC.system(of typeAbstractSystem).ECdriverroutine is moved toCCDrivermodule and renamed toccdriver. Thefcidumpkeyword-argument is now empty by default. It doesn't accept list of methods anymore, only one method at a time.- The driver routines and macros return energies as
NamedTuple. - The SVD methods have to be called now as
SVD-<methodname>, e.g.,svd-dcsd. - The
@svdccmacro is renamed to@dfccmacro and calls thedfccdriverroutine, which is intended as a driver routine for all DF-based correlation methods (i.e., methods which don't use theEC.fdintegrals).
Changed
- Renamed function
active_orbitalstooss_active_orbitals. - Renamed function
calc_ccsd_residtocalc_cc_resid. ECdriverandoss_active_orbitalsnow return named tuples.- Improved documentation of occupation strings syntax.
- Switched to
AtomandFlexibleSystemfromAtomsBaseas the internal representation of the molecular system. The basis set is stored for each atom as:basisproperty (asDict{String,String}, e.g.,system[1][:basis]["ao"]). One can also set:basisproperty for the whole system. - Renamed macro
@optto@set.@optis now an alias of@set.
Added
- The automatically generated
UCCSDTandUDC-CCSDTmethods have been added to the docs. - SCS-MP2, SCS-CCSD and SCS-DCSD
Version v0.10.0 - 2024.02.21
Breaking
- Cholesky threshold
thris used for integral decomposition only. Threshold for elimination of redundancies is now calledthred. - Files for amplitudes and multipliers are now called
..._1,..._2,... for singles, doubles, etc.
Changed
- Option
ignore_erroris moved from ECInfo structure towfoptions.
Added
UCCSD(T),ΛUCCSD(T),ΛUDCSDhave been implemented.- Pseudo-canonicalization of the FCIDUMP file (instead of full SCF calculation).
- Generated
UCCSDTandUDC-CCSDTmethods. - Macro
@print_inputto print the source of the input file to the output.
Fixed
- Fix dressing of a three-internal integral (which slightly affected the energy of CCSD/DCSD with
use_kext=false).
Version v0.9.0 - 2024.01.20
Added
- Add various methods (
DF-[U]HF,BO-[U]HF,[U/R]CCSD,[U/R]DCSD,SVD-DCSD,SVD-DC-CCSDT,CCSD(T),ΛCCSD(T),ΛDCSD...). - Setup macros, options etc.
- ...