Adding a Representation#
This guide covers the interface a new representation type must satisfy and how to register it with the Model.
Representation Interface#
Like processes, representations use std::variant dispatch. A new
representation must provide the following methods:
Required Methods#
StateSize()
std::tuple<std::size_t, std::size_t> StateSize() const;
Return
(num_variables, num_parameters)—the count of state variables and state parameters introduced by this representation.StateVariableNames()
std::set<std::string> StateVariableNames() const;
Return fully-qualified names for all state variables (e.g.,
"MODE.PHASE.SPECIES").StateParameterNames()
std::set<std::string> StateParameterNames() const;
Return names for all state parameters (e.g.,
"MODE.geometric_mean_radius").PhaseStatePrefixes()
std::map<std::string, std::set<std::string>> PhaseStatePrefixes() const;
Return a map from phase name to the set of mode/section prefixes. Processes use this to expand reactions across all instances.
GetPropertyProvider<DenseMatrixPolicy>(…)
template<typename DenseMatrixPolicy> AerosolPropertyProvider<DenseMatrixPolicy> GetPropertyProvider( AerosolProperty property, const std::unordered_map<std::string, std::size_t>& param_indices, const std::unordered_map<std::string, std::size_t>& var_indices, const std::string& phase_name) const;
Create a provider for the requested property. The provider must:
Populate
dependent_variable_indiceswith the state variable indices that the property depends on.Implement
ComputeValuefor the forcing function path.Implement
ComputeValueAndDerivativesfor the Jacobian path, writing partial derivatives into the partials matrix.
SetDefaultParameters(state) (optional but recommended)
Write default parameter values (GMD, GSD, section bounds) into a solver state. Convenience for users setting up initial conditions.
Provider Contract#
The AerosolPropertyProvider struct is the bridge between
representations and processes:
dependent_variable_indices: fixed at creation time, used by the process to determine Jacobian sparsity and map partials to state variable indices.ComputeValue: called on the forcing path (no derivatives needed).ComputeValueAndDerivatives: called on the Jacobian path. Column \(k\) of the partials matrix corresponds to \(\partial P / \partial y_k\) where \(y_k\) is the state variable atdependent_variable_indices[k].
Registering the New Type#
Add the header to [include/miam/representation.hpp](include/miam/representation.hpp).
Add the type to the
RepresentationVariantin [include/miam/model.hpp](include/miam/model.hpp):using RepresentationVariant = std::variant< SingleMomentMode, TwoMomentMode, UniformSection, MyNewRepresentation // ← add here >;
Testing Providers#
Verify each provider with:
Value test: set known state values, call
ComputeValue, compare against an analytical expectation.Derivative test: call
ComputeValueAndDerivatives, compare partial derivatives against finite-difference approximations:double dP_dy = (P(y + h) - P(y - h)) / (2 * h);
Sparsity test: verify that
dependent_variable_indicesis consistent with which partials are non-zero.