diff --git a/pywr-core/src/metric.rs b/pywr-core/src/metric.rs index d6c4fdc0..ea5a12d6 100644 --- a/pywr-core/src/metric.rs +++ b/pywr-core/src/metric.rs @@ -171,6 +171,7 @@ pub enum MetricF64 { NodeInFlow(NodeIndex), NodeOutFlow(NodeIndex), NodeMaxFlow(NodeIndex), + NodeDeficit(NodeIndex), NodeVolume(NodeIndex), NodeProportionalVolume(NodeIndex), NodeMaxVolume(NodeIndex), @@ -222,6 +223,11 @@ impl MetricF64 { .ok_or(MetricF64Error::NodeIndexNotFound(*idx))? .get_max_flow(network, state) .map_err(|e| MetricF64Error::NodeError(Box::new(e)))?), + MetricF64::NodeDeficit(idx) => { + let actual_flow = MetricF64::NodeInFlow(*idx).get_value(network, state)?; + let max_flow = MetricF64::NodeInFlow(*idx).get_value(network, state)?; + Ok((max_flow - actual_flow).max(0.0)) + } MetricF64::NodeVolume(idx) => Ok(state.get_network_state().get_node_volume(idx)?), MetricF64::NodeProportionalVolume(idx) => { Ok(state.get_network_state().get_node_proportional_volume(idx)?) diff --git a/pywr-core/src/parameters/deficit.rs b/pywr-core/src/parameters/deficit.rs deleted file mode 100644 index 2a850462..00000000 --- a/pywr-core/src/parameters/deficit.rs +++ /dev/null @@ -1,58 +0,0 @@ -use crate::metric::MetricF64; -use crate::network::Network; -use crate::parameters::{ - GeneralParameter, Parameter, ParameterCalculationError, ParameterMeta, ParameterName, ParameterState, -}; -use crate::scenario::ScenarioIndex; -use crate::state::State; -use crate::timestep::Timestep; - -/// A parameter representing the deficit between a flow metric and a max metric. -/// -/// Typically used to represent the deficit between actual inflow and requested max flow at -/// a node. -pub struct DeficitParameter { - meta: ParameterMeta, - flow: MetricF64, - max_flow: MetricF64, -} - -impl DeficitParameter { - pub fn new(name: ParameterName, flow: MetricF64, max_flow: MetricF64) -> Self { - Self { - meta: ParameterMeta::new(name), - flow, - max_flow, - } - } -} - -impl Parameter for DeficitParameter { - fn meta(&self) -> &ParameterMeta { - &self.meta - } -} - -impl GeneralParameter for DeficitParameter { - fn after( - &self, - _timestep: &Timestep, - _scenario_index: &ScenarioIndex, - model: &Network, - state: &State, - _internal_state: &mut Option>, - ) -> Result, ParameterCalculationError> { - let actual_flow = self.flow.get_value(model, state)?; - let max_flow = self.max_flow.get_value(model, state)?; - - let deficit = (max_flow - actual_flow).max(0.0); - Ok(Some(deficit)) - } - - fn as_parameter(&self) -> &dyn Parameter - where - Self: Sized, - { - self - } -} diff --git a/pywr-core/src/parameters/mod.rs b/pywr-core/src/parameters/mod.rs index 7504a11d..51eec49e 100644 --- a/pywr-core/src/parameters/mod.rs +++ b/pywr-core/src/parameters/mod.rs @@ -6,7 +6,6 @@ mod asymmetric; mod constant; mod constant_scenario; mod control_curves; -mod deficit; mod delay; mod difference; mod discount_factor; @@ -52,7 +51,6 @@ pub use control_curves::{ ApportionParameter, ControlCurveIndexParameter, ControlCurveInterpolatedParameter, ControlCurveParameter, PiecewiseInterpolatedParameter, VolumeBetweenControlCurvesParameter, }; -pub use deficit::DeficitParameter; pub use delay::DelayParameter; pub use difference::DifferenceParameter; pub use discount_factor::DiscountFactorParameter; diff --git a/pywr-schema/src/nodes/core.rs b/pywr-schema/src/nodes/core.rs index f78308c5..9a910dbb 100644 --- a/pywr-schema/src/nodes/core.rs +++ b/pywr-schema/src/nodes/core.rs @@ -10,11 +10,7 @@ use crate::parameters::Parameter; use crate::v1::{ConversionData, TryFromV1, try_convert_initial_storage, try_convert_node_attr, try_convert_node_meta}; use crate::{mermaid, node_attribute_subset_enum, node_component_subset_enum}; #[cfg(feature = "core")] -use pywr_core::{ - metric::MetricF64, - node::StorageInitialVolume as CoreStorageInitialVolume, - parameters::{DeficitParameter, ParameterName}, -}; +use pywr_core::{metric::MetricF64, node::StorageInitialVolume as CoreStorageInitialVolume}; use pywr_schema_macros::PywrVisitAll; use pywr_schema_macros::skip_serializing_none; use pywr_v1_schema::nodes::{ @@ -851,25 +847,7 @@ impl OutputNode { let metric = match attr { OutputNodeAttribute::Inflow => MetricF64::NodeInFlow(idx), - OutputNodeAttribute::Deficit => { - let deficit_parameter_name = ParameterName::new("deficit", Some(self.meta.name.as_str())); - - // Create a parameter for the deficit metric if it does not already exist - let deficit_parameter_idx = match network.get_parameter_index_by_name(&deficit_parameter_name) { - Some(p_idx) => p_idx, - None => { - let deficit_parameter = DeficitParameter::new( - deficit_parameter_name, - MetricF64::NodeInFlow(idx), - MetricF64::NodeMaxFlow(idx), - ); - - network.add_parameter(Box::new(deficit_parameter))? - } - }; - - deficit_parameter_idx.into_metric_f64_after() - } + OutputNodeAttribute::Deficit => MetricF64::NodeDeficit(idx), }; Ok(metric)