Skip to content

Commit f5816b7

Browse files
committed
refactor: use TimeSeries interfaces for CompressorConsumerFunction
1 parent 04b7740 commit f5816b7

11 files changed

Lines changed: 350 additions & 285 deletions

File tree

Lines changed: 47 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,26 @@
11
import numpy as np
22

3-
from libecalc.common.utils.rates import Rates
43
from libecalc.common.variables import ExpressionEvaluator
54
from libecalc.domain.infrastructure.energy_components.legacy_consumer.consumer_function import (
65
ConsumerFunction,
76
ConsumerFunctionResult,
87
)
9-
from libecalc.domain.infrastructure.energy_components.legacy_consumer.consumer_function.utils import (
10-
apply_condition,
11-
apply_power_loss_factor,
12-
get_condition_from_expression,
13-
get_power_loss_factor_from_expression,
14-
)
158
from libecalc.domain.process.compressor.core.base import CompressorModel, CompressorWithTurbineModel
16-
from libecalc.domain.process.compressor.core.train.variable_speed_compressor_train_common_shaft_multiple_streams_and_pressures import (
17-
VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPressures,
18-
)
19-
from libecalc.domain.process.core.results import CompressorTrainResult
20-
from libecalc.expression import Expression
9+
from libecalc.domain.process.compressor.dto import VariableSpeedCompressorTrainMultipleStreamsAndPressures
10+
from libecalc.domain.time_series_flow_rate import TimeSeriesFlowRate
11+
from libecalc.domain.time_series_power_loss_factor import TimeSeriesPowerLossFactor
12+
from libecalc.domain.time_series_pressure import TimeSeriesPressure
2113

2214

2315
class CompressorConsumerFunction(ConsumerFunction):
2416
def __init__(
2517
self,
2618
compressor_function: CompressorModel,
27-
rate_expression: Expression | list[Expression],
28-
suction_pressure_expression: Expression,
29-
discharge_pressure_expression: Expression,
30-
condition_expression: Expression | None,
31-
power_loss_factor_expression: Expression | None,
32-
intermediate_pressure_expression: Expression | None = None,
19+
rate_expression: TimeSeriesFlowRate | list[TimeSeriesFlowRate],
20+
suction_pressure_expression: TimeSeriesPressure | None,
21+
discharge_pressure_expression: TimeSeriesPressure | None,
22+
power_loss_factor_expression: TimeSeriesPowerLossFactor | None,
23+
intermediate_pressure_expression: TimeSeriesPressure | None = None,
3324
):
3425
"""Note: If multiple streams and pressures, there will be list of rate-Expressions, and there
3526
may be specification of intermediate pressure, stage number for intermediate pressure and specific
@@ -42,25 +33,24 @@ def __init__(
4233
or a list of rates expressions for multiple streams and pressures.
4334
:param suction_pressure_expression: Suction pressure expression [bara]
4435
:param discharge_pressure_expression: Discharge pressure expression [bara]
45-
:param condition_expression: Optional condition expression
4636
:param power_loss_factor_expression: Optional power loss factor expression.
4737
Typically used for power line loss subsea et.c.
4838
:param intermediate_pressure_expression: Used for multiple streams and pressures model.
4939
"""
5040
self._compressor_function = compressor_function
5141
self._rate_expression = rate_expression if isinstance(rate_expression, list) else [rate_expression]
42+
assert len(self._rate_expression) > 0
5243
self._suction_pressure_expression = suction_pressure_expression
5344
self._discharge_pressure_expression = discharge_pressure_expression
54-
self._condition_expression = condition_expression
5545
self._power_loss_factor_expression = power_loss_factor_expression
5646
self._intermediate_pressure_expression = intermediate_pressure_expression
5747

5848
@property
59-
def suction_pressure(self) -> Expression:
49+
def suction_pressure(self) -> TimeSeriesPressure | None:
6050
return self._suction_pressure_expression
6151

6252
@property
63-
def discharge_pressure(self) -> Expression:
53+
def discharge_pressure(self) -> TimeSeriesPressure | None:
6454
return self._discharge_pressure_expression
6555

6656
def evaluate(
@@ -73,102 +63,70 @@ def evaluate(
7363
:param regularity:
7464
:return:
7565
"""
76-
calendar_day_rates = np.array(
77-
[expression_evaluator.evaluate(expression=rate_expression) for rate_expression in self._rate_expression]
78-
)
79-
# Squeeze to remove axes of length one -> non-multiple streams will be 1d and not 2d.
80-
# But we don't want to squeeze multiple streams model with only one date.
81-
# That goes for CompressorWithTurbineModel with a MultipleStreamsAndPressures-train as well
8266
if isinstance(self._compressor_function, CompressorWithTurbineModel):
8367
compressor_model = self._compressor_function.compressor_model
8468
else:
8569
compressor_model = self._compressor_function
86-
if isinstance(compressor_model, VariableSpeedCompressorTrainCommonShaftMultipleStreamsAndPressures):
87-
stream_day_rate = Rates.to_stream_day(
88-
calendar_day_rates=calendar_day_rates,
89-
regularity=regularity,
90-
)
91-
else:
92-
stream_day_rate = np.atleast_1d(
93-
np.squeeze(
94-
Rates.to_stream_day(
95-
calendar_day_rates=calendar_day_rates,
96-
regularity=regularity,
97-
)
98-
)
99-
)
70+
71+
stream_day_rate = np.array([rate.get_stream_day_values() for rate in self._rate_expression], dtype=np.float64)
72+
73+
if not isinstance(compressor_model, VariableSpeedCompressorTrainMultipleStreamsAndPressures):
74+
stream_day_rate = np.atleast_1d(np.squeeze(stream_day_rate))
10075

10176
intermediate_pressure = (
102-
expression_evaluator.evaluate(expression=self._intermediate_pressure_expression)
103-
if self._intermediate_pressure_expression
77+
np.asarray(self._intermediate_pressure_expression.get_values(), dtype=np.float64)
78+
if self._intermediate_pressure_expression is not None
10479
else None
10580
)
10681
suction_pressure = (
107-
expression_evaluator.evaluate(expression=self._suction_pressure_expression)
82+
np.asarray(self._suction_pressure_expression.get_values(), dtype=np.float64)
10883
if self._suction_pressure_expression is not None
10984
else None
11085
)
11186
discharge_pressure = (
112-
expression_evaluator.evaluate(expression=self._discharge_pressure_expression)
113-
if self._discharge_pressure_expression is not None
87+
np.asarray(self._discharge_pressure_expression.get_values(), dtype=np.float64)
88+
if self._suction_pressure_expression is not None
11489
else None
11590
)
11691

117-
# Do conditioning first - set rates to zero if conditions are not met
118-
condition = get_condition_from_expression(
119-
expression_evaluator=expression_evaluator,
120-
condition_expression=self._condition_expression,
121-
)
122-
stream_day_rate_after_condition = apply_condition(
123-
input_array=stream_day_rate,
124-
condition=condition,
125-
)
126-
12792
# If the compressor model is supposed to have stages, make sure they are defined
12893
# (compressor sampled does not have stages)
129-
if isinstance(self._compressor_function, CompressorWithTurbineModel):
130-
self._compressor_function.compressor_model.check_for_undefined_stages(
131-
rate=stream_day_rate_after_condition,
132-
suction_pressure=suction_pressure,
133-
discharge_pressure=discharge_pressure,
134-
)
135-
else:
136-
self._compressor_function.check_for_undefined_stages(
137-
rate=stream_day_rate_after_condition,
138-
suction_pressure=suction_pressure,
139-
discharge_pressure=discharge_pressure,
140-
)
94+
compressor_model.check_for_undefined_stages(
95+
rate=stream_day_rate,
96+
suction_pressure=suction_pressure, # type: ignore[arg-type]
97+
discharge_pressure=discharge_pressure, # type: ignore[arg-type]
98+
)
14199

142-
compressor_train_result: CompressorTrainResult
143-
# Do not input regularity to compressor function. Handled outside
144100
# intermediate_pressure will only be different from None when we have a MultipleStreamsAndPressures train
145101
compressor_train_result = self._compressor_function.evaluate(
146-
rate=stream_day_rate_after_condition,
147-
suction_pressure=suction_pressure,
148-
discharge_pressure=discharge_pressure,
102+
rate=stream_day_rate,
103+
suction_pressure=suction_pressure, # type: ignore[arg-type]
104+
discharge_pressure=discharge_pressure, # type: ignore[arg-type]
149105
intermediate_pressure=intermediate_pressure,
150106
)
151107

152-
power_loss_factor = get_power_loss_factor_from_expression(
153-
expression_evaluator=expression_evaluator,
154-
power_loss_factor_expression=self._power_loss_factor_expression,
155-
)
108+
if self._power_loss_factor_expression is not None:
109+
energy_usage = self._power_loss_factor_expression.apply(np.asarray(compressor_train_result.energy_usage))
110+
power = (
111+
self._power_loss_factor_expression.apply(np.asarray(compressor_train_result.power))
112+
if compressor_train_result.power is not None
113+
else None
114+
)
115+
else:
116+
energy_usage = compressor_train_result.energy_usage
117+
power = compressor_train_result.power
118+
119+
periods = self._rate_expression[0].get_periods()
156120

157121
consumer_function_result = ConsumerFunctionResult(
158-
periods=expression_evaluator.get_periods(),
122+
periods=periods,
159123
is_valid=np.asarray(compressor_train_result.is_valid),
160124
energy_function_result=compressor_train_result,
161125
energy_usage_before_power_loss_factor=np.asarray(compressor_train_result.energy_usage),
162-
power_loss_factor=power_loss_factor,
163-
energy_usage=apply_power_loss_factor(
164-
energy_usage=np.asarray(compressor_train_result.energy_usage),
165-
power_loss_factor=power_loss_factor,
166-
),
167-
power=apply_power_loss_factor(
168-
energy_usage=np.asarray(compressor_train_result.power),
169-
power_loss_factor=power_loss_factor,
170-
)
171-
if compressor_train_result.power is not None
126+
power_loss_factor=np.asarray(self._power_loss_factor_expression.get_values(), dtype=np.float64)
127+
if self._power_loss_factor_expression is not None
172128
else None,
129+
energy_usage=np.asarray(energy_usage),
130+
power=np.asarray(power) if power is not None else None,
173131
)
174132
return consumer_function_result

src/libecalc/domain/time_series_pressure.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from abc import ABC, abstractmethod
22

3+
from libecalc.common.time_utils import Periods
4+
35

46
class TimeSeriesPressure(ABC):
57
"""
@@ -10,6 +12,14 @@ class TimeSeriesPressure(ABC):
1012
1113
"""
1214

15+
@abstractmethod
16+
def get_periods(self) -> Periods:
17+
"""
18+
Returns the periods associated with the flow rate time series.
19+
This is used to align the flow rate values with the corresponding periods.
20+
"""
21+
pass
22+
1323
@abstractmethod
1424
def get_values(self) -> list[float]:
1525
"""

0 commit comments

Comments
 (0)