Operator interface

This page lists the dispatch points that a new format, sparsity pattern, or conversion path can hook into. The surrounding narrative for how to extend Quoll is in Defining new methods; this page is the reference.

All methods below live in the Quoll namespace. They are not exported, but they are stable and may be specialised by downstream code without touching Quoll.jl itself.

Metadata hooks (required per format)

A format is identified by its metadata type (e.g. FHIaimsCSCRealMetadata). Every format must resolve these type-level queries:

FunctionReturns
op_data_type(::Type{M})The DataContainer alias for the operator's data
op_source_type(::Type{M})The AbstractSource singleton type
op_sparsity_type(::Type{M})The AbstractSparsity subtype
op_keydata_type(::Type{M})The DataContainer alias for keyed data (needed only if your format works with KeyedOperator)

See src/operators/fhiaims.jl for a minimal example.

Loading

To load operators from disk in your format, implement:

FunctionPurpose
load_metadata_basic(::Type{M}, dir, kind)Build a BasicMetadataContainer from files on disk
load_metadata(::Type{M}, dir, basic_metadata)Wrap the basic container into the concrete metadata type (Real/Recip/SpinReal/SpinRecip)
load_data(::Type{M}, dir, kind)Read the data array from disk
get_avail_filenames(::Type{M}, kind)Return candidate on-disk filenames for this operator kind
get_avail_operatorkinds(::Type{M})Return the list of operator kinds this format supports

load_operator (the entry point used by the pipeline) is already implemented generically — it composes the methods above.

Quoll.load_operatorFunction
load_operator(::Type{OP}, ::Type{M}, dir, kind) -> OP

Load a single operator of type OP from directory dir. Loads metadata and data for the given OperatorKind, then assembles via build_operator. Format-specific loading is dispatched through load_metadata_basic, load_metadata, and load_data methods defined per format.

source
Quoll.find_operatorkindsFunction
find_operatorkinds(::Type{M}, dir) -> Vector{OperatorKind}

Scan directory dir for available operator data files matching metadata format M. Returns the list of OperatorKinds whose files are found on disk.

source

Writing

Implement write_operators(::Type{M}, dir, operators) for your metadata type. For multi-file layouts it is usually convenient to split the implementation into metadata-writing and data-writing helpers — see src/operators/deeph.jl for the shape.

Quoll.write_operatorsFunction
write_operators(::Type{M}, dir, operators)

Write a collection of operators to disk in the format determined by metadata type M. Creates the directory if it doesn't exist.

source

Building

For build_operator to produce zero-initialised operators in your format:

Quoll.build_dataFunction
build_data(metadata; value=0.0, type=Nothing, initialised=true)

Allocate a DataContainer matching the format described by metadata. Dispatches to format-specific build_data methods based on op_data_type(M).

source

build_keydata(::Type{KD}, metadata, data) is additionally required if your format should work with KeyedOperator.

Converting

To support conversion between your format and another, dispatch on the pair of metadata types (input and output):

Quoll.convert_metadataFunction
convert_metadata(::Type{Mₒᵤₜ}, in_metadata; kwargs...) -> AbstractMetadata

Convert metadata from one format to another. This is a three-stage pipeline:

  1. convert_metadata_basic — convert source, SH convention, sparsity, basis.
  2. convert_metadata_extra — convert extra fields (k-point, spins) via trait dispatch.
  3. convert_metadata_final — assemble the concrete output metadata type.

Mₒᵤₜ may be a union type (e.g. CanonicalBlockRealMetadata); the concrete subtype is chosen automatically based on which extra fields are present.

Keyword arguments

  • radii=nothing: build sparsity from neighbour list instead of converting.
  • hermitian=nothing: override hermicity (defaults to input's).
  • out_shconv=nothing: explicit output SH convention.
  • subbasis=nothing: reduce basis to this subset of orbitals.
  • inverted=false: if true, keep the complement of subbasis.
  • source_kwargs=NamedTuple(): extra arguments for constructing the output source.
  • extra_kwargs=NamedTuple(): extra arguments for trait-based conversion (e.g. kpoint).
source
Quoll.convert_metadata_basicFunction
convert_metadata_basic(::Type{Mₒᵤₜ}, in_metadata; kwargs...) -> BasicMetadataContainer

Convert the core metadata fields: derives the output source, computes the SH convention delta, converts sparsity (optionally from radii), reorders the basis set to the output SH convention, and optionally reduces it with a subbasis.

source
Quoll.convert_data!Function
convert_data!(out_operator, in_operator)

Transfer and transform data from in_operator into out_operator (mutating out_operator in place). Currently dispatches on the KeyedTrait of both operators to select the correct data types for conversion:

  • (NoKeydata, NoKeydata) → route on (Dₒᵤₜ, Dᵢₙ)
  • (HasKeydata, NoKeydata) → route on (KDₒᵤₜ, Dₒᵤₜ, Dᵢₙ)
  • (NoKeydata, HasKeydata) → route on (Dₒᵤₜ, KDᵢₙ, Dᵢₙ)
  • (HasKeydata, HasKeydata) → route on (KDₒᵤₜ, Dₒᵤₜ, KDᵢₙ, Dᵢₙ)

Concrete conversion methods are defined per format pair in src/conversions/.

source
Quoll.convert_sparsityFunction
convert_sparsity(::Type{Sₒᵤₜ}, in_sparsity, basisset; hermitian=false)

Convert a sparsity pattern to type Sₒᵤₜ, optionally changing hermicity. When input and output types match, only the hermicity is adjusted. Cross-type conversions (e.g. CSCRealSparsity → BlockRealSparsity, BlockRealSparsity → DenseRecipSparsity) are also supported.

source
convert_sparsity(::Type{Sₒᵤₜ}, in_metadata; radii=nothing, hermitian=nothing)

Metadata-level sparsity conversion wrapper. If radii is provided, builds a new sparsity pattern from a neighbour list; otherwise converts the input metadata's existing sparsity to type Sₒᵤₜ, optionally changing hermicity.

source

In practice, most conversions between your format and the rest of Quoll will go through CanonicalBlockRealMetadata, so the pair to implement is usually (YourMetadata, CanonicalBlockRealMetadata) and vice versa. Direct conversions to any other format are also supported — just add the method for that pair.

TOML parsing

If you want your format to be selectable from input_file.toml, register it with the parser's format lookup table:

Quoll.get_readformat(::Val{:myformat}) = MyFormatMetadata
Quoll.get_writeformat(::Val{:myformat}) = MyFormatMetadata

The string after Val( is matched against the format field after case/whitespace/punctuation normalisation, so "MyFormat", "my-format", and "my_format" all resolve to the same symbol.

Similarly, custom core-projection schemes register themselves via:

Quoll.Projections.get_basis_projection(::Val{:myscheme}) = MyScheme

Holy traits

Dispatch on behavioural traits rather than concrete types is used in a handful of places (real vs. reciprocal space, spin vs. no-spin, keyed vs. unkeyed operator).