vibeqc.basis_crystal

CRYSTAL-format basis-set parser and NWChem/.g94 emitter.

Targets the per-element CRYSTAL basis-set files distributed by the Bredow group (Peintinger–Vilela Oliveira–Bredow, pob-*): one file per element, named ZZ_Sym (e.g. 06_C), plain-text CRYSTAL input.

Supported today

All-electron shells (S, SP, P, D, F, G). These cover the light-element Bredow sets (pob-TZVP and pob-DZVP-rev2 for H–Br). The emitter produces NWChem/.g94 files that libint loads without modification.

Not yet supported

ECP blocks (INPUT header on Rb–I and Cs–Po pob-* archives). Parsing them is trivial; applying them in vibe-qc needs libecpint integration, which is a separate follow-on. Such files raise NotImplementedError for now.

CRYSTAL per-element format summary

Line 1::

Z NSHELL

or for ECP-using atoms::

(200 + Z) NSHELL

Each shell starts with::

ITYPE LAT NG CHE SCAL

where

  • ITYPE — 0 = user-defined (the only case the Bredow files use).

  • LAT — shell angular-momentum code:

    0=S, 1=SP, 2=P, 3=D, 4=F, 5=G.

  • NG — number of primitive Gaussians.

  • CHE — formal occupancy (electrons) assigned to this shell.

  • SCAL — scale factor applied to the exponents (1.0 = as-written).

Followed by NG lines of exponent coefficient (or exponent s_coef p_coef for SP shells).

Functions

crystal_ecp_to_libecpint_arrays(ecp)

Flatten a CrystalECP into libecpint primitive arrays.

emit_crystal(atoms)

Convert per-element basis specs into CRYSTAL inline-basis format.

emit_g94(atoms[, header_comment])

Convert a list of per-element basis specs into a single .g94 (Gaussian / NWChem format) string that libint can load.

fetch_bredow_basis_sets([dest_dir, names, ...])

Download the Bredow group all-electron basis sets and convert them to .g94 files loadable by libint.

parse_crystal_atom_basis(text[, source])

Parse a single CRYSTAL per-element basis file.

parse_crystal_atom_basis_file(path)

Convenience wrapper: parse a CRYSTAL per-element file from disk.

Classes

CrystalAtomBasis(Z, has_ecp[, shells, ecp])

Parsed per-atom basis set (one Bredow file).

CrystalECP(znuc, m_local[, m_per_ell, terms])

Parsed CRYSTAL effective-core-potential block.

CrystalECPTerm(ell, alpha, coefficient, n_pow)

One Gaussian term inside a CRYSTAL ECP angular-momentum block.

CrystalShell(shell_type, occupancy, scale_factor)

One contracted Gaussian shell in CRYSTAL format.

LibecpintInlineArrays(exponents, ...)

Flat primitive arrays in the exact shape libecpint::ECPIntegrator:: set_ecp_basis(...) expects for one ECP center.

class vibeqc.basis_crystal.CrystalShell(shell_type, occupancy, scale_factor, exponents=<factory>, coefficients=<factory>, coefficients_p=<factory>)[source]

Bases: object

One contracted Gaussian shell in CRYSTAL format.

Parameters:
shell_type: str
occupancy: float
scale_factor: float
exponents: list[float]
coefficients: list[float]
coefficients_p: list[float]
property n_primitives: int
class vibeqc.basis_crystal.CrystalECPTerm(ell, alpha, coefficient, n_pow)[source]

Bases: object

One Gaussian term inside a CRYSTAL ECP angular-momentum block.

Encodes the contribution

V_ℓ_term(r) = C · r^n · exp(−α · r²)

in the standard Stuttgart-Köln / Hay-Wadt convention. ell is the angular momentum (0=s, 1=p, …, 4=g) — or the special label "local" for the M-counted local-potential terms in CRYSTAL’s eq. 3.18.

Parameters:
ell: object
alpha: float
coefficient: float
n_pow: int
class vibeqc.basis_crystal.CrystalECP(znuc, m_local, m_per_ell=(), terms=<factory>)[source]

Bases: object

Parsed CRYSTAL effective-core-potential block.

Built from the INPUT-keyword block that follows a 200+Z atom header in CRYSTAL-format basis files. Carries everything libecpint needs to build the V_ECP operator: the effective nuclear charge (Z_eff = Z ncore), and the per-ℓ Gaussian expansion of the local + ℓ-projected potentials.

The CRYSTAL ECP convention has up to five ℓ-projected components (ℓ = 0..4) plus a “local” group counted by M in the header. terms collects them all in source order; group them by term.ell to match a specific potential expansion.

Parameters:
znuc: float
m_local: int
m_per_ell: tuple[int, ...] = ()
terms: list[CrystalECPTerm]
property total_terms: int
class vibeqc.basis_crystal.CrystalAtomBasis(Z, has_ecp, shells=<factory>, ecp=None)[source]

Bases: object

Parsed per-atom basis set (one Bredow file).

Parameters:
Z: int
has_ecp: bool
shells: list[CrystalShell]
ecp: CrystalECP | None = None
property element_symbol: str
vibeqc.basis_crystal.parse_crystal_atom_basis(text, source='<string>')[source]

Parse a single CRYSTAL per-element basis file.

source is used only in error messages.

Parameters:
Return type:

CrystalAtomBasis

vibeqc.basis_crystal.parse_crystal_atom_basis_file(path)[source]

Convenience wrapper: parse a CRYSTAL per-element file from disk.

Parameters:

path (str | Path)

Return type:

CrystalAtomBasis

class vibeqc.basis_crystal.LibecpintInlineArrays(exponents, coefficients, ams, ns, local_ell, max_proj_ell)[source]

Bases: object

Flat primitive arrays in the exact shape libecpint::ECPIntegrator:: set_ecp_basis(...) expects for one ECP center.

Mapping convention (per CRYSTAL23 §”Effective core pseudo-potentials” p. 84, eqs. 3.18 + 3.19, against libecpint’s XML convention where the local channel sits at lval = max_proj_ell + 1):

  • CRYSTAL M (ell="local" term group)

    → libecpint ams[i] = local_ell = max_proj_ell + 1. This is the U_L channel that acts on all angular momenta (no projector applied), matching the local-potential semantics in CRYSTAL eq. 3.18.

  • CRYSTAL M_ℓ (ell {0..4} term groups, with non-zero count)

    → libecpint ams[i] = . Projected channels; libecpint applies P_ℓ during integration.

Both conventions yield the same V_ECP matrix elements when summed against the basis. Verified against ecp10mdf.xml (K, Z=19) shell layout: local at lval=4 with placeholder zero, projectors at lval= 0..3 for s/p/d/f, max projector ell = 3.

Parameters:
exponents: tuple[float, ...]
coefficients: tuple[float, ...]
ams: tuple[int, ...]
ns: tuple[int, ...]
local_ell: int
max_proj_ell: int
property n_primitives: int
vibeqc.basis_crystal.crystal_ecp_to_libecpint_arrays(ecp)[source]

Flatten a CrystalECP into libecpint primitive arrays.

The conversion is bookkeeping — no algebraic rewrite of the ECP. Each CrystalECPTerm becomes one primitive with its (alpha, coefficient, n_pow) carried over verbatim; only the ell label is re-keyed onto libecpint’s per-primitive am convention (see LibecpintInlineArrays for the mapping).

Phase 14g pairs this with a C++ compute_ecp_matrix_inline that calls libecpint’s set_ecp_basis(...) (the inline- primitive form) instead of set_ecp_basis_from_library(...) (the XML form used today). That unblocks the 5th-period pob basis sets (Rb–I, Cs–Po) and any future inline-ECP archives (vDZP, mixed-row dhf-*).

Parameters:

ecp (CrystalECP) – Parsed CRYSTAL ECP block from parse_crystal_atom_basis().

Returns:

Bundle ready to feed libecpint’s inline-primitive API.

Return type:

LibecpintInlineArrays

Raises:

ValueError – If a term carries an unrecognised ell label (not "local" and not in 0..4).

vibeqc.basis_crystal.emit_g94(atoms, header_comment='')[source]

Convert a list of per-element basis specs into a single .g94 (Gaussian / NWChem format) string that libint can load.

Parameters:
Return type:

str

vibeqc.basis_crystal.emit_crystal(atoms)[source]

Convert per-element basis specs into CRYSTAL inline-basis format.

Produces text suitable for pasting into a CRYSTAL .d12 input deck after the geometry block (ENDGEOM). The format is:

Z NSHELL
0 LAT NPG OCC SCALE
  exp1  coeff1
  exp2  coeff2
...
 99 0
END

where LAT = 0(S), 1(SP), 2(P), 3(D), 4(F), 5(G). For SP shells each primitive line carries both s and p coefficients.

ECP-bearing atoms (has_ecp=True) are emitted with 200+Z as the header number; the ECP block itself is not emitted (ECP inline emission needs a separate function — libecpint integration pending). All-electron atoms emit the raw Z.

Parameters:

atoms (Sequence[CrystalAtomBasis]) – Sequence of CrystalAtomBasis objects, typically parsed from the Bredow-group per-element CRYSTAL files via parse_crystal_atom_basis() or parse_crystal_atom_basis_file().

Returns:

Multi-line CRYSTAL basis-set block ready for insertion into a .d12 deck.

Return type:

str

vibeqc.basis_crystal.fetch_bredow_basis_sets(dest_dir=None, names=None, *, verbose=True)[source]

Download the Bredow group all-electron basis sets and convert them to .g94 files loadable by libint.

Parameters:
  • dest_dir (str | Path | None) – Target directory for the .g94 output files. Defaults to basis_library/basis/ inside the vibe-qc source tree (the path already on LIBINT_DATA_PATH in editable installs).

  • names (Iterable[str] | None) – Subset of basis-set keys to fetch (from _BREDOW_ARCHIVES). None fetches all supported light-element archives.

  • verbose (bool) – Print progress + citation info.

Return type:

dict mapping basis name → path of the generated .g94 file.