55from libecalc .common .list .list_utils import array_to_list
66from libecalc .common .logger import logger
77from libecalc .common .units import Unit
8- from libecalc .common .utils .rates import Rates
98from libecalc .common .variables import ExpressionEvaluator
109from libecalc .domain .infrastructure .energy_components .legacy_consumer .consumer_function import (
1110 ConsumerFunction ,
1211 ConsumerFunctionResult ,
1312)
14- from libecalc .domain .infrastructure .energy_components .legacy_consumer .consumer_function .utils import (
15- apply_condition ,
16- apply_power_loss_factor ,
17- get_condition_from_expression ,
18- get_power_loss_factor_from_expression ,
19- )
20- from libecalc .domain .infrastructure .energy_components .legacy_consumer .tabulated .common import (
21- Variable ,
22- VariableExpression ,
23- )
2413from libecalc .domain .infrastructure .energy_components .legacy_consumer .tabulated .tabular_energy_function import (
2514 TabularEnergyFunction ,
2615)
2716from libecalc .domain .process .core .results import EnergyFunctionResult
28- from libecalc .expression import Expression
17+ from libecalc .domain .time_series_power_loss_factor import TimeSeriesPowerLossFactor
18+ from libecalc .domain .time_series_variable import TimeSeriesVariable
2919
3020
3121class TabularConsumerFunction (ConsumerFunction ):
3222 """
3323 Consumer function based on tabulated energy usage data.
3424
3525 This class evaluates energy usage (power or fuel) for a consumer by:
36- - Evaluating variable expressions to obtain input values .
37- - Interpolating tabular data using these values via `TabularEnergyFunction`.
38- - Optionally applying a condition and a power loss factor.
26+ - Evaluating time series variables (with condition and rate conversion applied) .
27+ - Interpolating tabular data using these variable values via `TabularEnergyFunction`.
28+ - Optionally applying a power loss factor.
3929
4030 The result is energy usage in [MW] (electricity) or [Sm3/day] (fuel).
4131 For electricity, power is also included in the result.
@@ -45,9 +35,8 @@ class TabularConsumerFunction(ConsumerFunction):
4535 data (list[list[float]]): Tabular data, one list per header.
4636 energy_usage_adjustment_constant (float): Constant to adjust energy usage.
4737 energy_usage_adjustment_factor (float): Factor to adjust energy usage.
48- variables_expressions (list[VariableExpression]): Variable expressions to evaluate.
49- condition_expression (Expression | None): Optional condition for evaluation.
50- power_loss_factor_expression (Expression | None): Optional power loss factor expression.
38+ variables (list[TimeSeriesVariable]): Variables to evaluate and use for interpolation.
39+ power_loss_factor (TimeSeriesPowerLossFactor | None): Optional power loss factor.
5140 """
5241
5342 def __init__ (
@@ -56,9 +45,8 @@ def __init__(
5645 data : list [list [float ]],
5746 energy_usage_adjustment_constant : float ,
5847 energy_usage_adjustment_factor : float ,
59- variables_expressions : list [VariableExpression ],
60- condition_expression : Expression | None = None ,
61- power_loss_factor_expression : Expression | None = None ,
48+ variables : list [TimeSeriesVariable ],
49+ power_loss_factor : TimeSeriesPowerLossFactor | None = None ,
6250 ):
6351 """Tabulated consumer function [MW] (energy) or [Sm3/day] (fuel)."""
6452 # Consistency of variables between tabulated_energy_function and variables_expressions must be validated up
@@ -69,21 +57,24 @@ def __init__(
6957 energy_usage_adjustment_constant = energy_usage_adjustment_constant ,
7058 energy_usage_adjustment_factor = energy_usage_adjustment_factor ,
7159 )
72- self ._variables_expressions = variables_expressions
60+ self ._variables = variables
7361
74- self ._condition_expression = condition_expression
7562 # Typically used for power line loss subsea et.c.
76- self ._power_loss_factor_expression = power_loss_factor_expression
63+ self ._power_loss_factor = power_loss_factor
7764
7865 def evaluate (
7966 self ,
8067 expression_evaluator : ExpressionEvaluator ,
8168 regularity : list [float ],
8269 ) -> ConsumerFunctionResult :
8370 """
84- Evaluates the consumer function for given input data.
71+ Evaluates the consumer function for the given input data.
8572
86- See the class docstring for a detailed description of the evaluation process.
73+ Steps:
74+ 1. Evaluates all variables (with condition and rate conversion).
75+ 2. Interpolates the tabular energy function using these values.
76+ 3. Optionally applies a power loss factor.
77+ 4. Returns a result object with energy usage, validity, and related data.
8778
8879 Args:
8980 expression_evaluator (ExpressionEvaluator): Evaluator for variable and condition expressions.
@@ -93,76 +84,41 @@ def evaluate(
9384 ConsumerFunctionResult: Result containing energy usage, validity, and related data.
9485 """
9586
96- variables_for_calculation = []
97- # If some of these are rates, we need to calculate stream day rate for use
98- # Also take a copy of the calendar day rate and stream day rate for input to result object
99- for variable in self ._variables_expressions :
100- variable_values = expression_evaluator .evaluate (variable .expression )
101- if variable .name .lower () == "rate" :
102- variable_values = Rates .to_stream_day (
103- calendar_day_rates = variable_values ,
104- regularity = regularity ,
105- )
106- variables_for_calculation .append (Variable (name = variable .name , values = variable_values .tolist ()))
107-
10887 energy_function_result = self .evaluate_variables (
109- variables = variables_for_calculation ,
88+ variables = self . _variables ,
11089 )
11190
112- condition = get_condition_from_expression (
113- condition_expression = self ._condition_expression ,
114- expression_evaluator = expression_evaluator ,
115- )
116- # for tabular, is_valid is based on energy_usage being NaN. This will also (correctly) change potential
117- # invalid points to valid where the condition sets energy_usage to zero
118- energy_function_result .energy_usage = array_to_list (
119- apply_condition (
120- input_array = np .asarray (energy_function_result .energy_usage ),
121- condition = condition ,
122- )
123- )
124- energy_function_result .power = (
125- array_to_list (
126- apply_condition (
127- input_array = np .asarray (energy_function_result .power ),
128- condition = condition ,
129- )
91+ # Apply power loss factor if present
92+ if self ._power_loss_factor is not None :
93+ energy_usage = self ._power_loss_factor .apply (
94+ energy_usage = np .asarray (energy_function_result .energy_usage , dtype = np .float64 )
13095 )
131- if energy_function_result .power is not None
132- else None
133- )
134-
135- power_loss_factor = get_power_loss_factor_from_expression (
136- expression_evaluator = expression_evaluator ,
137- power_loss_factor_expression = self ._power_loss_factor_expression ,
138- )
96+ power_loss_factor = self ._power_loss_factor .get_values (length = len (energy_usage ))
97+ else :
98+ energy_usage = energy_function_result .energy_usage
99+ power_loss_factor = None
139100
140101 return ConsumerFunctionResult (
141- periods = expression_evaluator .get_periods (),
102+ periods = self . _variables [ 0 ] .get_periods (),
142103 is_valid = np .asarray (energy_function_result .is_valid ),
143104 energy_function_result = energy_function_result ,
144- energy_usage_before_power_loss_factor = np .asarray (energy_function_result .energy_usage ),
145- power_loss_factor = power_loss_factor ,
146- energy_usage = apply_power_loss_factor (
147- energy_usage = np .asarray (energy_function_result .energy_usage ),
148- power_loss_factor = power_loss_factor ,
149- ),
105+ energy_usage_before_power_loss_factor = np .asarray (energy_function_result .energy_usage , dtype = np .float64 ),
106+ power_loss_factor = np .asarray (power_loss_factor , dtype = np .float64 ),
107+ energy_usage = np .asarray (energy_usage , dtype = np .float64 ),
150108 )
151109
152- def evaluate_variables (self , variables : list [Variable ]) -> EnergyFunctionResult :
110+ def evaluate_variables (self , variables : list [TimeSeriesVariable ]) -> EnergyFunctionResult :
153111 """
154- Interpolates energy usage for the provided variable values.
155-
156- See the class docstring for a detailed description of the evaluation process.
112+ Interpolates energy usage for the provided variables.
157113
158114 Args:
159- variables (list[Variable ]): List of variables with names and values for interpolation.
115+ variables (list[TimeSeriesVariable ]): List of variables to evaluate and use for interpolation.
160116
161117 Returns:
162118 EnergyFunctionResult: Result containing energy usage, units, and power (if applicable).
163119 """
164120
165- variables_map_by_name = {variable .name : variable .values for variable in variables }
121+ variables_map_by_name = {variable .name : variable .get_values () for variable in variables }
166122 _check_variables_match_required (
167123 variables_to_evaluate = list (variables_map_by_name .keys ()),
168124 required_variables = self ._tabular_energy_function .required_variables ,
0 commit comments