neml2.schema¶
Declarative HIT syntax for Python-native objects.
HitSchema is the native counterpart of the C++ expected_options pattern,
but intentionally smaller: it records fixed model inputs/outputs and the HIT
options needed to construct common leaf models. The Model base class
uses it to derive input_spec / output_spec and to provide a default
from_hit implementation.
- neml2.schema.BLOCK_NAME = <object object>¶
the variable name defaults to the model’s HIT block name (mirrors C++
Interpolationwhose output variable defaults to the object name). Resolved againstnode.path()at parse time.- Type:
Sentinel
defaultforvar_output()
- class neml2.schema.HitField(kind: 'str', name: 'str', value_type: 'Any' = None, doc: 'str' = '', default: 'Any' = <object object at 0x7f00bd6ec390>, attr: 'str | None' = None, reader: 'Callable[[nmhit.Node, str], Any] | None' = None, optional_reader: 'Callable[[nmhit.Node, str, Any], Any] | None' = None, factory_getter: 'str | None' = None, allow_nonlinear: 'bool' = False, suffix: 'str | None' = None, override: 'str | None' = None, priority: 'str | None' = None)[source]¶
Bases:
object- Parameters:
kind (str)
name (str)
value_type (Any)
doc (str)
default (Any)
attr (str | None)
reader (Callable[[nmhit.Node, str], Any] | None)
optional_reader (Callable[[nmhit.Node, str, Any], Any] | None)
factory_getter (str | None)
allow_nonlinear (bool)
suffix (str | None)
override (str | None)
priority (str | None)
- default: Any = <object object>¶
- override: str | None = None¶
the name of another HIT option whose non-empty value takes precedence over
name + suffixfor the resolved variable name. Used byrateoverrides — when the user supplies an explicitrate = 'my_rate_var'they bypass the<variable>_ratederivation.- Type:
For
input/outputfields
- priority: str | None = None¶
an explicit producer priority used by the
DependencyResolverwhen more than one model provides the same variable name."high"= “my output supersedes any other producer; run me last.”"low"= “my output is overwritten by any other producer; run me first.”None(default) = “I’m the sole producer — duplicate-provider error if not.”- Type:
For
outputfields
- suffix: str | None = None¶
a literal string appended to the HIT-resolved variable name, used to derive the conventional NEML2 secondary-variable names (
~1for history,_ratefor rates,_residualfor implicit residuals). Multiple input/output fields can share the samename(HIT option) with different ``suffix``es to derive several related variables from one user-supplied base name.- Type:
For
input/outputfields
- value_type: Any = None¶
- property var_type: type[TensorWrapper] | None¶
The variable
TensorWrappertype, forvar_*/input/output.
- class neml2.schema.HitSchema(*fields)[source]¶
Bases:
objectOrdered declaration of a native object’s HIT surface.
- Parameters:
fields (HitField)
- property input_spec: dict[str, type[TensorWrapper]]¶
- kwargs_from_hit(node, factory)[source]¶
Parse constructor kwargs for every schema field.
input/outputfields resolve their canonical variable name from HIT (with the option name as the default, orBLOCK_NAME/Noneperinput()/output()); the resolved name is passed underHitField.ctor_name(attror option name) soModel._store_schema_valuescan record per-instanceinput_spec/output_speckeys without going through a separate remapping pass.derived_input/derived_outputfields reference another option by name and reuse that option’s resolution (default included). A precomputedoption_valuesmap lets the derived resolver see e.g.time → "t"when the option declareddefault="t"and HIT was silent.
- property output_spec: dict[str, type[TensorWrapper]]¶
- reject_unknown_fields(node)[source]¶
Raise if node carries any HIT field not declared in the schema.
Mirrors the C++ parser’s behaviour: an unrecognised option is a hard error, not a silent skip. Silently ignored options are how stale knobs (e.g.
priorityon aComposedModelafter the resolver stopped supporting it) survive across refactors.typeis always allowed – it’s read by the factory before the schema-driven kwargs pass to dispatch the registered class. Override option names (anoption()’soverride=target) are also allowed; they substitute for the primary option’s value when non-empty.- Parameters:
node (nmhit.Node)
- Return type:
None
- neml2.schema.derived_input(referenced, type_cls, *, attr=None, suffix=None, override=None)[source]¶
Declare an input variable whose name is derived from another field’s value.
Unlike
input(), a derived field does not declare its own HIT option — it references an existinginput()/output()/option()field byreferenced(the field’sname) and computes the variable name asHIT[referenced] + suffix(orHIT[override]when that override option is set non-empty). This is the schema-driven counterpart to the time-integrator pattern of declaring one basevariableinput and deriving<variable>~1/<variable>_rate/<variable>_residualfrom it: the user sees a single option per logical knob, and the secondary variables fall out automatically. No docstring is required — derived fields don’t appear in the syntax catalog.
- neml2.schema.derived_output(referenced, type_cls, *, attr=None, suffix=None, override=None)[source]¶
Declare an output variable whose name is derived from another field’s value.
See
derived_input(). The canonical use isderived_output("variable", T, suffix="_residual")for an implicit residual output named after the basevariableoption/input.
- neml2.schema.input(name, type_cls, doc, *, default=<object object>, attr=None)[source]¶
Declare an input variable.
The canonical variable name resolves as
HIT[name]if specified, else default (which itself defaults to the option name). Passdefault=BLOCK_NAMEto fall back to the model’s HIT block name, ordefault=Noneto keep the resolved name optional (yieldingNonewhen HIT is silent — used by leaves that compute a derived default). When attr is given,Model.__init__stores the resolved name on the instance under that attribute (for leaves that reference the variable name explicitly insideforward, e.g. as a chain-rule action key).To derive a secondary variable name from another option (time-integration pattern: history
~1,_rate,_residual), usederived_input()/derived_output()instead — those declare a variable without introducing a new HIT option.
- neml2.schema.option(name, value_type, doc, *, attr=None, default=<object object>, reader=None, optional_reader=None)[source]¶
Declare a scalar/list/string HIT option.
When attr is provided and the model uses the inherited
Model.__init__, the parsed value is stored directly on the instance under that attribute name. Without attr, the parsed value is passed as a constructor kwarg and a custom__init__must consume it.
- neml2.schema.output(name, type_cls, doc, *, default=<object object>, attr=None, priority=None)[source]¶
Declare an output variable.
Same resolution rules as
input()(HIT override → default → option name); passdefault=BLOCK_NAMEfor “default to the HIT block name” (the C++Interpolationconvention) ordefault=Nonefor a derived default the leaf computes itself. For secondary names derived from another option, seederived_output().Set priority to disambiguate composition when multiple sibling models provide the same variable name:
"high"— “my output supersedes any other producer; run me last.” The composed model returns this leaf’s value."low"— “my output is overwritten by any other producer; run me first.” The composed model returns the other (default-priority) leaf’s value.None(default) — claim the name exclusively. Duplicate-provider error if any sibling also provides it.
Used by post-processors like
FixOrientationthat mutate a sibling’s output in place (input='orientation'/output='orientation').
- neml2.schema.parameter(name, type_cls, doc, *, attr=None, default=<object object>, allow_nonlinear=False)[source]¶
- neml2.schema.parameters(name, type_cls, doc, *, attr=None, default=<object object>, allow_nonlinear=False)[source]¶
Declare a list of parameters, one per token of a HIT list option.
The HIT value is a whitespace-separated list of specs; each token is declared as an independent parameter (named
<attr-or-name>_<i>) viaModel.declare_typed_parameter(), so each entry can independently resolve as a literal, a[Tensors]cross-ref, a[Models]-output promoted input (mode 3) or a bare-variable promoted input (mode 4) — same as a singleparameter(). The list of registered parameter names is stored onself.<attr>for the leaf to iterate insideforward(typically viaModel._get_param_list()).
- neml2.schema.var_inputs(option_name, type_cls, doc, *, default=<object object>, attr=None, ctor=None)[source]¶
Declare a list HIT option whose values name several inputs of one type.
The C++
LinearCombinationfrom = 'a b c'pattern: the option is a whitespace-separated list of variable names, each an input oftype_cls. Whenattris provided,Model.__init__stores the parsedlist[str]on the instance under that attribute (and extendsinput_specautomatically); otherwise the value is passed as a constructor kwarg.ctoris a deprecated alias forattr.