pub struct ModelVariable {
pub var_type: VariableType,
pub units: Option<String>,
pub default: Option<InlineValue>,
pub default_units: Option<String>,
pub element_type: Option<String>,
pub description: Option<String>,
pub shape: Option<Vec<String>>,
pub location: Option<String>,
pub distribution: Option<Distribution>,
pub update: Option<ParameterUpdateSpec>,
}Expand description
Variable within a model
Fields§
§var_type: VariableTypeVariable type
units: Option<String>Physical units
default: Option<InlineValue>Default/initial value: a scalar, or — for a SHAPED variable — inline
row-major nested array data (esm-spec §6.3). See InlineValue.
default_units: Option<String>The unit the default VALUE is expressed in, when it is not the
variable’s declared units (schema ModelVariable.default_units).
The schema’s contract is that default is given in the declared units,
so a default_units naming a DIFFERENT unit is a defect: units: "K"
with default: 25.0, default_units: "degC" means the stored number is 25
but the variable actually reads 298.15. Rust did not model the field at
all, so the mismatch was silently dropped on load.
element_type: Option<String>Floating-point precision of THIS variable and of the arithmetic over it,
overriding the document-wide domain.element_type (esm-spec §11.3.1).
This is NOT ModelVariable::var_type. That field is the variable’s
semantic role (unknown / parameter); this one is its element type.
It exists for the split a single document-wide precision cannot express.
A relational model may be binary32 in its floating-point quantities —
reproducing a real*4 reference — while its join keys are integers
binary32 cannot represent: a ten-digit category code is ~2.26e9, 135× above
binary32’s exact-integer limit of 2^24, so under a document-wide
Float32 two distinct codes collapse onto one and a join.on over them
merges unrelated rows. Declaring the key columns Float64 keeps them
exact while the quantities follow the document.
None means the document’s domain.element_type. See
crate::precision_infer for how the declaration propagates through an
expression and what it refuses.
description: Option<String>Brief description
shape: Option<Vec<String>>Arrayed-variable shape: ordered dimension names drawn from the
enclosing model’s domain.spatial. None means scalar.
See discretization RFC §10.2.
location: Option<String>Staggered-grid location tag (e.g., “cell_center”, “edge_normal”,
“vertex”). None means no explicit staggering.
See discretization RFC §10.2.
distribution: Option<Distribution>Parameter-only: draw the value from a distribution instead of fixing it
at default (esm-spec §6.3, schema ModelVariable.distribution).
Mutually exclusive with default. With no update the draw happens
ONCE at setup (sampled_parameters); with update.kind: "wiener" it is
redrawn every step with √dt scaling (brownian_parameters), which is
what promotes the enclosing model to an SDE. This subsumes the 0.x
brownian type’s noise_kind / correlation_group tags: correlated
noise is one vector-valued parameter carrying a cov matrix, which the
tags never actually gave.
update: Option<ParameterUpdateSpec>Parameter-only: when this parameter refreshes and what from
(esm-spec §5.4). Absent means it never changes after setup. One
mechanism replacing three 0.x constructs — the brownian type, the
discrete type’s refresh trigger, and the discrete_parameters
event lists with their functional_affect.
Implementations§
Source§impl ModelVariable
impl ModelVariable
Sourcepub fn default_scalar(&self) -> Option<f64>
pub fn default_scalar(&self) -> Option<f64>
This variable’s SCALAR default, or None when it has none or carries
inline array data instead (esm-spec §6.3).
Every consumer that seeds one f64 slot reads through here, so a shaped
variable whose whole column is authored inline never lands a bogus number
in a scalar slot — the array channel picks it up instead
(crate::simulate_array).
Sourcepub fn default_array(&self) -> Option<Result<(Vec<usize>, Vec<f64>), String>>
pub fn default_array(&self) -> Option<Result<(Vec<usize>, Vec<f64>), String>>
This variable’s default as inline ARRAY data, flattened row-major with
its per-axis extents. None when the default is absent or scalar.
§Errors
A string naming the defect when the authored array is ragged.
Sourcepub fn for_each_expression(&self, f: &mut impl FnMut(&Expr))
pub fn for_each_expression(&self, f: &mut impl FnMut(&Expr))
Visit every Expression this variable carries, in a stable order.
From esm 1.0.0 a variable has no expression field — an unknown’s
definition is an EQUATION. What is left on the variable is the
parameter’s update: each rule’s when trigger, its expression
value form, and the unit_conversion of a from binding. All three
are Expression positions and so are subject to reference integrity
(esm-spec §4.9.5), which is what this walk exists to serve.
Sourcepub fn for_each_expression_at(&self, f: &mut impl FnMut(&Expr, &str))
pub fn for_each_expression_at(&self, f: &mut impl FnMut(&Expr, &str))
As ModelVariable::for_each_expression, but also handing the callback
the JSON-pointer suffix of the SITE the expression came from, relative to
the variable’s update.
A diagnostic must name the field it is about. Reporting every one of a
parameter’s update expressions at a bare .../update is ambiguous the
moment the ordered ARRAY form is used (esm-spec §5.4) — and that form
exists precisely because parameters written by two or more events are
common — so when, expression and from/unit_conversion all have to
be distinguishable, per rule. The suffixes match the other four
bindings: "" for the single-rule object form and /i for entry i of
the array form, then the site (/when, /expression,
/from/unit_conversion).
Sourcepub fn for_each_expression_mut(&mut self, f: &mut impl FnMut(&mut Expr))
pub fn for_each_expression_mut(&mut self, f: &mut impl FnMut(&mut Expr))
Mutable counterpart of ModelVariable::for_each_expression, for the
namespacing / renaming / range-resolution passes.
Sourcepub fn try_for_each_expression_mut<E>(
&mut self,
f: &mut impl FnMut(&mut Expr) -> Result<(), E>,
) -> Result<(), E>
pub fn try_for_each_expression_mut<E>( &mut self, f: &mut impl FnMut(&mut Expr) -> Result<(), E>, ) -> Result<(), E>
Error-propagating ModelVariable::for_each_expression_mut: visits
the same expression set in the same order and returns the FIRST error
f raises (later expressions are not passed to f, so they are left
unmodified). Defined in terms of for_each_expression_mut itself, so
the two can never disagree about which fields carry expressions.
Sourcepub fn update_sources(&self) -> Vec<&str>
pub fn update_sources(&self) -> Vec<&str>
The data_sources keys this variable’s update rules read from.
Trait Implementations§
Source§impl Clone for ModelVariable
impl Clone for ModelVariable
Source§impl Debug for ModelVariable
impl Debug for ModelVariable
Source§impl Default for ModelVariable
The bare variable: every optional field absent, var_type a parameter.
A manual impl because VariableType has no derivable default — type
is a required field on the wire — and of the two kinds only a parameter is
coherent with nothing else set (an unknown with no defining equation is a
structural error). Construction sites are still expected to state the type
they mean: ModelVariable { var_type: .., ..Default::default() }.
impl Default for ModelVariable
The bare variable: every optional field absent, var_type a parameter.
A manual impl because VariableType has no derivable default — type
is a required field on the wire — and of the two kinds only a parameter is
coherent with nothing else set (an unknown with no defining equation is a
structural error). Construction sites are still expected to state the type
they mean: ModelVariable { var_type: .., ..Default::default() }.
Source§impl<'de> Deserialize<'de> for ModelVariable
impl<'de> Deserialize<'de> for ModelVariable
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ModelVariable
impl RefUnwindSafe for ModelVariable
impl Send for ModelVariable
impl Sync for ModelVariable
impl Unpin for ModelVariable
impl UnsafeUnpin for ModelVariable
impl UnwindSafe for ModelVariable
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Context for T
impl<T> Context for T
fn vector_from_element<V>(&self, len: usize, value: <V as VectorCommon>::T) -> Vwhere
V: Vector<C = Self>,
fn vector_from_vec<V>(&self, vec: Vec<<V as VectorCommon>::T>) -> Vwhere
V: Vector<C = Self>,
fn vector_zeros<V>(&self, len: usize) -> Vwhere
V: Vector<C = Self>,
fn dense_mat_zeros<V>(
&self,
rows: usize,
cols: usize,
) -> <V as DefaultDenseMatrix>::Mwhere
V: Vector<C = Self> + DefaultDenseMatrix,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.