atomli.calculators.qc
Generated from the public Python surface of Atomli 0.1.4.
QC(*args: 'Any', download: 'bool' = True, **kwargs: 'Any')
Section titled “QC(*args: 'Any', download: 'bool' = True, **kwargs: 'Any')”Construct the native QC calculator.
Arguments follow atomli.calculators.qc.QC, whose docstring documents the whole
surface. Device selection additionally uses Atomli’s shared resolver, so
device= or adapter= accepts atomli.gpu.Adapter objects and QC inherits
atomli.set_default_device(...) exactly like XTB/MLIP. This wrapper also
adds automatic SKALA 1.1 checkpoint delivery. With xc="SKALA-1.1"
and no skala_checkpoint, the pinned checkpoint is fetched once from
the model release and cached locally.
download: Whether a missing checkpoint may be fetched. Pass
False to require a cache hit. Ignored unless the checkpoint is
being resolved, so it never affects a non-SKALA functional or an
explicitly supplied skala_checkpoint.
Native molecular and three-dimensionally periodic DFT calculator.
QC follows the normal ASE calculator protocol and accepts both atomli
Atoms and ASE-provided Atoms objects. With settings=None it constructs
a molecular calculation. Select periodic calculation explicitly with
settings={"periodic": True}; periodic mode requires a cell and PBC enabled
on all three axes.
Parameters
Section titled “Parameters”xc : str, default “PBE”
Exchange-correlation functional. The public native matrix includes PBE
and r2SCAN for molecular and periodic calculations, plus periodic
LDA/VWN with its matched GTH-PADE pseudopotential.
basis : str, default “def2-SVP”
Molecular orbital basis. In periodic mode set settings["basis"]
instead and leave this top-level argument at its default.
density_fitting : {“none”, “default”}, optional
Molecular density-fitting selection. Molecular calculations default to
"default" (RI-J density fitting), the fast production path; pass
"none" for conventional Coulomb builds. Periodic mode requires
"none" and defaults to it.
charge : float or None
Optional total-charge override. It must be finite and integer-valued
when the native QC calculation is built.
unpaired : int or None
Number of unpaired electrons. The electron count and this number must
have the same parity, so an odd-electron system needs an odd value: a
radical such as CH3 (9 electrons) is QC(..., unpaired=1). Leaving
it at the default None on an odd-electron system raises
electron/spin parity mismatch: 9 electrons and 0 unpaired electrons;
pass unpaired=1 to fix it. Per-site moments are declared separately;
see “Magnetic structure” below.
skala_checkpoint : str or None
Path to the pinned SKALA 1.1 model file (skala-1.1.fun). Required
with, and only valid for, xc="SKALA-1.1". Both molecular and periodic
SKALA use it.
device : {“cpu”, “gpu”}, optional
Exchange-correlation compute device. "cpu" is the default. "gpu" is
available only on the QC routes implemented by the native Gpu runtime;
unsupported combinations fail closed. "wgpu" remains accepted as a
compatibility alias.
adapter : atomli.gpu.Adapter, int, str, or None
Optional physical GPU selected from the process-global atomli.gpu
inventory. PCI selectors are preferred on multi-GPU hosts. It is valid
only with device="gpu"/"wgpu"; supported periodic SKALA GPU routes
bind their qc.rs Gpu context to this adapter, while unsupported QC GPU
routes continue to raise rather than ignoring the selector.
require_convergence : bool, default True
Whether an SCF that ran out of cycles without meeting its thresholds
raises instead of returning its energy. The default refuses it: that
energy is a point on an oscillating trajectory, not an observable, and
a returned float carries no marker distinguishing it from a correct
one. Pass False to take the last iterate deliberately; the call then
warns, and calc.converged / results["converged"] report False.
The opt-out covers the energy only. Forces and stress are
differentiated from the converged state itself, so they are refused on
an unconverged SCF either way. Convergence is readable on any
calculator: calc.converged (also results["converged"]) and
calc.scf_iterations (also results["scf_iterations"]).
calc.converged is None until something has been calculated, which
is distinct from False. A converged SCF is also necessary but not
sufficient: a periodic run can converge cleanly on an under-resolved
mesh and still settle on the wrong physical state, so converged=True
is not a licence to skip convergence testing against mesh, basis
and k-point sampling.
scf : Scf, dict, str, or None
SCF numerical controls, molecular and periodic alike: an
atomli.calculators.qc.Scf, an equivalent dict, or a preset name ("default",
"robust"). Scf.fields() lists every field with its documentation,
and an unknown key raises naming them. None keeps the engine
default. The resolved block reads back from calc.parameters["scf"].
kpts : tuple, dict, KMesh, or None
ASE-conventional k-point sampling. kpts=(2, 2, 2) is a gamma-centered
mesh, kpts={"size": (2, 2, 2), "gamma": False} the shifted
Monkhorst-Pack one, and kpts=KMesh((4, 4, 4), symmetry="time_reversal")
the full mesh identity. kpts={"density": d} targets d k-points per
inverse angstrom along each reciprocal vector. Passing kpts implies
periodic mode. It is sugar for settings["kpoints"] /
settings["kpoint_density"]: exactly one spelling may declare the
sampling, and declaring both raises naming the two. Unsupported ASE
forms (even, explicit k-point lists) are rejected with an error
naming what is supported, and KMesh.fields() lists every mesh field
with its documentation.
auxiliary_basis : str or None
Explicit RI fitting basis for the molecular density-fitted Coulomb
build, e.g. "def2-universal-jfit". The default None lets the engine
choose the auxiliary set matching the functional. It is molecular-only,
and it is the fitting set itself: passing it with
density_fitting="none" or with periodic settings raises, because
neither of those runs a fitted Coulomb build. It reads back from
calc.parameters["auxiliary_basis"].
smearing : dict or None
GPAW-conventional occupation broadening,
smearing={"name": "fermi-dirac", "width": 0.1}, with the width in eV
and "gaussian" the other accepted name. It is sugar for
settings["smearing"], whose sigma is in Hartree: the width divides
by 27.211386245988 on the way in, and the resolved block reads back
from calc.parameters["settings"]["smearing"]. Exactly one spelling
may declare the broadening, and declaring both raises naming the two.
Broadening needs a periodic mode to act on, selected by
settings["periodic"] or by kpts; without one this raises. The
native key’s chemical_potential and fixed_spin have no ASE
spelling and stay in settings["smearing"].
convergence : dict or None
ASE-conventional SCF thresholds, convergence={"energy": 1e-6} with
the tolerance in eV. It is sugar for scf["energy_tolerance"], which
is in Hartree, and any other key raises naming energy as the one
this engine’s SCF converges on. Exactly one spelling may declare the
tolerance: an scf dict naming energy_tolerance, or an Scf
instance or preset name (which specifies the whole block), conflicts
with it and raises naming both.
maxiter : int or None
ASE-conventional SCF cycle limit, sugar for scf["max_cycles"], and
subject to the same one-spelling rule as convergence. It must be at
least 1; scf={"max_cycles": 0} is the spelling for evaluating the
initial density without an SCF. Disjoint scf keys compose:
maxiter=99, scf={"level_shift": 0.25} sets both.
settings : dict or None
Periodic settings schema:
periodic: required boolean selector.Trueenables periodic mode.basis: orbital basis, default"gth-dzvp-molopt-sr".pseudopotential: default"gth-pbe", or"gth-pade"for LDA/VWN.energy_cutoff: FFT-grid cutoff in Hartree, default100.0.mesh: optional positive[nx, ny, nz]FFT mesh override.kpoint_density: minimumkpt * lengthproduct in angstrom, default15.0. Each automatic dimension ismax(1, ceil(kpoint_density / lattice_length_angstrom)).kpoints: optional explicit mesh. Either positive[kx, ky, kz]dimensions (gamma-centered) or a mesh mapping /KMeshcarryingsize,centering,symmetry,wrap_aroundandao_symmetry. It is echoed as the full mesh identity either way.precision: integral and grid target, default1e-8.derivative_mode:"automatic","analytical", or"finite_difference"; default"automatic".displacement: centered force-difference step in Bohr, default1e-3.strain: dimensionless centered stress-difference step, default1e-3.smearing: optional occupation broadening, as a nested mapping. See “Occupation broadening” below.numerical_integrator: PySCF periodic integrator."knumint"(default) is the FFT grid;"multigrid"is the equivalent ofmf.multigrid_numint().dft_u: optional Hubbard+Ucorrections. See “DFT+U” below.
mesh overrides the mesh derived from energy_cutoff; kpoints overrides
the sampling derived from kpoint_density. Unknown keys, invalid dimensions,
non-positive numerical settings, non-3D PBC, and missing or degenerate cells
raise errors rather than selecting fallback values. The resolved values read
back from calc.parameters["settings"].
Atoms with pbc=True need these settings; without them the calculation
raises periodic atoms require explicit QcPeriodicSettings. The fix is to
pass settings={"periodic": True, ...}, naming at least a periodic basis
and pseudopotential.
Magnetic structure
Section titled “Magnetic structure”Per-site initial magnetic moments follow the ASE convention:
atoms.set_initial_magnetic_moments([...]) (or initial_magmoms in an
extxyz file) declares the starting magnetic state, and the calculator
reads it automatically. The declared moments seed the unrestricted SCF’s
initial density with the matching per-site alpha/beta split – the only
way to reach a ferrimagnetic or antiferromagnetic solution – and any
nonzero declaration selects spin-polarized treatment even at zero net
moment. When both unpaired and per-site moments are given, the summed
moments must equal the unpaired count or the calculation raises an error
naming both numbers; when only moments are given, the net spin is derived
from their sum, which must then be an integer.
In a k-point-sampled unrestricted cell the declared per-cell moment is
enforced at every kpoints mesh. This deliberately diverges from PySCF
through 2.14, whose KUHF.nelec leaves cell.spin unscaled and so holds
only unpaired / nkpts per cell.
Occupation broadening
Section titled “Occupation broadening”settings["smearing"] is a nested mapping broadening the occupations. A
metal has no gap for integer occupations to fill against, so its SCF
oscillates between degenerate states and never converges; broadening is
what makes such a cell solvable. It is absent by default, because integer
occupations are the correct description of an insulator.
atoms.calc = QC(xc="PBE", settings={ "periodic": True, "basis": "gth-szv-molopt-sr", "pseudopotential": "gth-pbe", "mesh": [18, 18, 18], "kpoints": [1, 1, 1], "smearing": {"sigma": 0.01, "method": "fermi"},})sigma is the width in Hartree and is required: it must be positive and
finite. method is "fermi" (default) or "gaussian".
chemical_potential fixes the Hartree chemical potential instead of
optimizing it against the electron count each cycle. fixed_spin=True
holds the alpha and beta electron counts apart, keeping the requested
moment rather than letting one common chemical potential relax it. With
smearing on, the reported energy is the Mermin free energy E - sigma*S,
the quantity the returned forces and stress differentiate. The smearing
keyword above is the ASE-conventional spelling of the same block.
settings["dft_u"] adds Hubbard +U corrections, named the way the
literature quotes them: element, then shell, then U in eV.
atoms.calc = QC(xc="PBE", settings={ "periodic": True, "basis": "gth-dzvp-molopt-sr", "pseudopotential": "gth-pbe", "dft_u": {"Fe": {"3d": 4.0}},})Every iron site in the cell gets the same 4 eV correction on its 3d shell.
Several elements and several shells per element are allowed:
{"Ni": {"3d": 6.0}, "O": {"2p": 1.0}}. The mapping echoes back from
calc.parameters["settings"]["dft_u"] exactly as written, and an
atomli.calculators.qc.DftU instance is the typed spelling of the same mapping,
accepted wherever the dict is.
The projectors are built against PySCF’s MINAO reference basis, not the
periodic basis the SCF runs in, so the shell name has to exist in MINAO for
that element. A shell that selects nothing there is refused at energy time,
naming the pattern it tried (DFT+U selection "Fe 3q" matched no AOs in the "MINAO" reference) rather than quietly running plain DFT and reporting it
as +U. Construction cannot check this: it takes the cell’s own elements to
know which AOs exist.
dft_u cannot be combined with numerical_integrator="multigrid"; PySCF’s
MultiGrid path is wired for KRKS/KUKS, not KRKSpU, so the constructor
refuses that combination.
Results and stress
Section titled “Results and stress”Energy and free energy are in eV. Forces are in eV/angstrom. Periodic stress
is in eV/angstrom**3 and defaults to ASE Voigt order
[xx, yy, zz, yz, xz, xy]; get_stress(voigt=False) returns a symmetric
3 by 3 tensor. Molecular QC does not advertise stress and raises ASE’s
PropertyNotImplementedError when stress is requested.
Caching
Section titled “Caching”The native backend and results are retained across ASE optimizer, molecular
dynamics, and repeated property calls. Exact state comparison includes
atomic numbers, positions, cell, PBC, charge, and unpaired-electron
overrides. An unchanged state reuses available results; a changed state
invalidates them. reset() also discards the retained backend.
Examples
Section titled “Examples”Molecular ASE geometry:
from ase import Atomsfrom atomli.calculators.qc import QC
atoms = Atoms("H2", positions=[[0, 0, 0], [0, 0, 0.74]])atoms.calc = QC(xc="PBE", basis="def2-SVP")energy = atoms.get_potential_energy()forces = atoms.get_forces()Periodic ASE geometry with automatic kpt * length >= 15 sampling:
from ase.build import bulkfrom atomli.calculators.qc import QC
atoms = bulk("Si", "diamond", a=5.43)atoms.calc = QC(settings={"periodic": True})stress = atoms.get_stress()stress_tensor = atoms.calc.get_stress(atoms, voigt=False)Scf(**kwargs)
Section titled “Scf(**kwargs)”SCF numerical controls, molecular and periodic alike.
Keyword arguments name the engine’s own settings fields; an unknown key
raises a message naming every valid field. Scf.fields() lists the
fields with their documentation. Scf.default() and Scf.robust() are
the named presets, also accepted wherever settings are taken as strings.
default()
Section titled “default()”The default preset.
fields()
Section titled “fields()”(name, description) for every field, in declaration order.
robust()
Section titled “robust()”The robust preset.
to_dict(self, /)
Section titled “to_dict(self, /)”The settings as a plain dict, exactly as the engine sees them.
KMesh(size, **kwargs)
Section titled “KMesh(size, **kwargs)”Explicit periodic k-point mesh, with its centering and symmetry semantics.
The mesh dimensions alone do not identify a sampling: gamma-centered and
shifted Monkhorst-Pack coordinates are different point sets for any even
dimension. KMesh carries the whole identity, so kpts= and
settings["kpoints"] state what was sampled instead of implying it.
QC(xc="PBE", kpts=KMesh((4, 4, 4), centering="monkhorst_pack"), settings=...)size is positional; every other field is a keyword naming a serde field of
the mesh struct, and an unknown one raises naming all of them.
KMesh.fields() lists them with their documentation.
fields()
Section titled “fields()”(name, description) for every field, in declaration order.
to_dict(self, /)
Section titled “to_dict(self, /)”The mesh as a plain dict, exactly as the engine sees it.
DftU(sites)
Section titled “DftU(sites)”Hubbard +U corrections, named the way the literature quotes them.
DftU({"Fe": {"3d": 4.0}}) corrects the 3d shell of every iron site by 4 eV.
Each entry becomes a PySCF AO-label pattern ("Fe 3d") resolved against the
MINAO reference cell, so the correction follows the element and shell rather
than an AO index nobody can predict from a settings dict.
QC(xc="PBE", settings={..., "dft_u": DftU({"Fe": {"3d": 4.0}})})The plain mapping is accepted anywhere this class is, so the typed spelling is for autocompletion and validation, never a requirement.
fields()
Section titled “fields()”(name, description) for the mapping’s shape.
to_dict(self, /)
Section titled “to_dict(self, /)”The selections as a plain dict, exactly as the engine sees them.