Skip to content

Commit b37b681

Browse files
committed
chore: introduce evaluation input for compressor sampled
1 parent 62daf8c commit b37b681

5 files changed

Lines changed: 140 additions & 45 deletions

File tree

src/libecalc/domain/process/evaluation_input.py

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ class CompressorEvaluationInput:
2929
def __init__(
3030
self,
3131
rate_expression: TimeSeriesFlowRate | list[TimeSeriesFlowRate],
32-
fluid_factory: FluidFactoryInterface | list[FluidFactoryInterface] | None,
32+
fluid_factory: FluidFactoryInterface | list[FluidFactoryInterface],
33+
suction_pressure_expression: TimeSeriesPressure,
34+
discharge_pressure_expression: TimeSeriesPressure,
3335
power_loss_factor: TimeSeriesPowerLossFactor | None = None,
34-
suction_pressure_expression: TimeSeriesPressure | None = None,
35-
discharge_pressure_expression: TimeSeriesPressure | None = None,
3636
intermediate_pressure_expression: TimeSeriesPressure | None = None,
3737
):
3838
self._rate_expression = rate_expression
@@ -43,15 +43,15 @@ def __init__(
4343
self._intermediate_pressure_expression = intermediate_pressure_expression
4444

4545
@property
46-
def suction_pressure_expression(self) -> TimeSeriesPressure | None:
46+
def suction_pressure_expression(self) -> TimeSeriesPressure:
4747
return self._suction_pressure_expression
4848

4949
@property
50-
def discharge_pressure_expression(self) -> TimeSeriesPressure | None:
50+
def discharge_pressure_expression(self) -> TimeSeriesPressure:
5151
return self._discharge_pressure_expression
5252

5353
@property
54-
def power_loss_factor(self) -> TimeSeriesPowerLossFactor:
54+
def power_loss_factor(self) -> TimeSeriesPowerLossFactor | None:
5555
return self._power_loss_factor
5656

5757
@property
@@ -74,6 +74,68 @@ def apply_to_model(self, compressor_model: CompressorModel):
7474
if self._intermediate_pressure_expression is not None
7575
else None
7676
)
77+
suction_pressure = np.asarray(self._suction_pressure_expression.get_values(), dtype=np.float64)
78+
discharge_pressure = np.asarray(self._discharge_pressure_expression.get_values(), dtype=np.float64)
79+
80+
compressor_model.set_evaluation_input(
81+
rate=stream_day_rate,
82+
fluid_factory=self._fluid_factory,
83+
suction_pressure=suction_pressure,
84+
discharge_pressure=discharge_pressure,
85+
intermediate_pressure=intermediate_pressure,
86+
)
87+
88+
89+
class CompressorSampledEvaluationInput:
90+
"""
91+
Encapsulates all input data required to configure and apply evaluation parameters to a sampled compressor model.
92+
93+
Attributes:
94+
rate_expression (TimeSeriesFlowRate | list[TimeSeriesFlowRate]): the flow rate expression(s).
95+
power_loss_factor (TimeSeriesPowerLossFactor | None): expression for power loss factor.
96+
suction_pressure_expression (TimeSeriesPressure | None): expression for the inlet (suction) pressure.
97+
discharge_pressure_expression (TimeSeriesPressure | None): expression for the outlet (discharge) pressure.
98+
"""
99+
100+
def __init__(
101+
self,
102+
rate_expression: TimeSeriesFlowRate | list[TimeSeriesFlowRate],
103+
power_loss_factor: TimeSeriesPowerLossFactor | None = None,
104+
suction_pressure_expression: TimeSeriesPressure | None = None,
105+
discharge_pressure_expression: TimeSeriesPressure | None = None,
106+
):
107+
self._rate_expression = rate_expression
108+
self._power_loss_factor = power_loss_factor
109+
self._suction_pressure_expression = suction_pressure_expression
110+
self._discharge_pressure_expression = discharge_pressure_expression
111+
112+
@property
113+
def suction_pressure_expression(self) -> TimeSeriesPressure | None:
114+
return self._suction_pressure_expression
115+
116+
@property
117+
def discharge_pressure_expression(self) -> TimeSeriesPressure | None:
118+
return self._discharge_pressure_expression
119+
120+
@property
121+
def power_loss_factor(self) -> TimeSeriesPowerLossFactor | None:
122+
return self._power_loss_factor
123+
124+
@property
125+
def periods(self) -> Periods:
126+
if isinstance(self._rate_expression, list):
127+
return self._rate_expression[0].get_periods()
128+
return self._rate_expression.get_periods()
129+
130+
def apply_to_model(self, compressor_model: CompressorModel):
131+
rate_expr = self._rate_expression if isinstance(self._rate_expression, list) else [self._rate_expression]
132+
133+
if not isinstance(compressor_model, CompressorTrainCommonShaftMultipleStreamsAndPressures):
134+
assert len(rate_expr) == 1
135+
stream_day_rate = np.asarray(rate_expr[0].get_stream_day_values(), dtype=np.float64)
136+
else:
137+
stream_day_rate = np.array([rate.get_stream_day_values() for rate in rate_expr], dtype=np.float64)
138+
77139
suction_pressure = (
78140
np.asarray(self._suction_pressure_expression.get_values(), dtype=np.float64)
79141
if self._suction_pressure_expression is not None
@@ -87,10 +149,10 @@ def apply_to_model(self, compressor_model: CompressorModel):
87149

88150
compressor_model.set_evaluation_input(
89151
rate=stream_day_rate,
90-
fluid_factory=self._fluid_factory,
152+
fluid_factory=None,
91153
suction_pressure=suction_pressure,
92154
discharge_pressure=discharge_pressure,
93-
intermediate_pressure=intermediate_pressure,
155+
intermediate_pressure=None,
94156
)
95157

96158

@@ -110,7 +172,7 @@ def __init__(
110172
self._power_loss_factor = power_loss_factor
111173

112174
@property
113-
def power_loss_factor(self) -> TimeSeriesPowerLossFactor:
175+
def power_loss_factor(self) -> TimeSeriesPowerLossFactor | None:
114176
return self._power_loss_factor
115177

116178
@property

src/libecalc/domain/process/process_service.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
from libecalc.domain.ecalc_component import EcalcComponent
66
from libecalc.domain.process.compressor.core.base import CompressorModel, CompressorWithTurbineModel
77
from libecalc.domain.process.compressor.core.sampled import CompressorModelSampled
8-
from libecalc.domain.process.evaluation_input import CompressorEvaluationInput, PumpEvaluationInput
8+
from libecalc.domain.process.evaluation_input import (
9+
CompressorEvaluationInput,
10+
CompressorSampledEvaluationInput,
11+
PumpEvaluationInput,
12+
)
913
from libecalc.domain.process.pump.pump import PumpModel
1014
from libecalc.presentation.yaml.domain.ecalc_components import ProcessSystemComponent, SimplifiedProcessUnitComponent
1115

@@ -24,7 +28,7 @@ def register_simplified_process_unit(
2428
self,
2529
ecalc_component: EcalcComponent,
2630
simplified_process_unit: CompressorModelSampled | PumpModel | CompressorWithTurbineModel,
27-
evaluation_input: CompressorEvaluationInput | PumpEvaluationInput,
31+
evaluation_input: CompressorSampledEvaluationInput | PumpEvaluationInput,
2832
): ...
2933

3034
@abstractmethod
@@ -36,4 +40,6 @@ def map_model_to_consumer(
3640
): ...
3741

3842
@abstractmethod
39-
def get_evaluation_input(self, process_system_id: UUID) -> CompressorEvaluationInput | PumpEvaluationInput: ...
43+
def get_evaluation_input(
44+
self, process_system_id: UUID
45+
) -> CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput: ...

src/libecalc/presentation/yaml/domain/default_process_service.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55
from libecalc.domain.process.compressor.core.base import CompressorModel, CompressorWithTurbineModel
66
from libecalc.domain.process.compressor.core.sampled import CompressorModelSampled
77
from libecalc.domain.process.compressor.core.train.base import CompressorTrainModel
8-
from libecalc.domain.process.evaluation_input import CompressorEvaluationInput, PumpEvaluationInput
8+
from libecalc.domain.process.evaluation_input import (
9+
CompressorEvaluationInput,
10+
CompressorSampledEvaluationInput,
11+
PumpEvaluationInput,
12+
)
913
from libecalc.domain.process.process_service import ProcessService
1014
from libecalc.domain.process.pump.pump import PumpModel
1115
from libecalc.presentation.yaml.domain.ecalc_components import ProcessSystemComponent, SimplifiedProcessUnitComponent
@@ -15,12 +19,16 @@ class DefaultProcessService(ProcessService):
1519
def __init__(self):
1620
self._process_systems: dict[UUID, CompressorTrainModel] = {}
1721
self._simplified_process_units: dict[UUID, CompressorModelSampled | PumpModel | CompressorWithTurbineModel] = {}
18-
self._evaluation_inputs: dict[UUID, CompressorEvaluationInput | PumpEvaluationInput] = {}
22+
self._evaluation_inputs: dict[
23+
UUID, CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput
24+
] = {}
1925
self._consumer_to_model_map: dict[tuple[UUID, Period], UUID] = {}
2026
self._ecalc_components: dict[UUID, EcalcComponent] = {}
2127

2228
@property
23-
def evaluation_inputs(self) -> dict[UUID, CompressorEvaluationInput | PumpEvaluationInput]:
29+
def evaluation_inputs(
30+
self,
31+
) -> dict[UUID, CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput]:
2432
return self._evaluation_inputs
2533

2634
@property
@@ -53,7 +61,7 @@ def register_simplified_process_unit(
5361
self,
5462
ecalc_component: EcalcComponent,
5563
simplified_process_unit: CompressorModelSampled | PumpModel | CompressorWithTurbineModel,
56-
evaluation_input: CompressorEvaluationInput | PumpEvaluationInput,
64+
evaluation_input: CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput,
5765
):
5866
self._ecalc_components[ecalc_component.id] = ecalc_component
5967
self.simplified_process_units[ecalc_component.id] = simplified_process_unit
@@ -67,5 +75,7 @@ def map_model_to_consumer(
6775
):
6876
self.consumer_to_model_map[(consumer_id, period)] = ecalc_component.id
6977

70-
def get_evaluation_input(self, model_id: UUID) -> CompressorEvaluationInput | PumpEvaluationInput:
78+
def get_evaluation_input(
79+
self, model_id: UUID
80+
) -> CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput:
7181
return self.evaluation_inputs.get(model_id)

src/libecalc/presentation/yaml/mappers/consumer_function_mapper.py

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@
4848
from libecalc.domain.process.compressor.core.train.types import FluidStreamObjectForMultipleStreams
4949
from libecalc.domain.process.compressor.dto import InterstagePressureControl
5050
from libecalc.domain.process.entities.shaft import SingleSpeedShaft, VariableSpeedShaft
51-
from libecalc.domain.process.evaluation_input import CompressorEvaluationInput, PumpEvaluationInput
51+
from libecalc.domain.process.evaluation_input import (
52+
CompressorEvaluationInput,
53+
CompressorSampledEvaluationInput,
54+
PumpEvaluationInput,
55+
)
5256
from libecalc.domain.process.pump.pump import PumpModel
5357
from libecalc.domain.process.value_objects.chart.chart import ChartData
5458
from libecalc.domain.process.value_objects.chart.compressor import CompressorChart
@@ -182,6 +186,14 @@ def _all_equal(items: set) -> bool:
182186
return len(items) <= 1
183187

184188

189+
def _is_sampled_compressor(model: CompressorModel) -> bool:
190+
if isinstance(model, CompressorModelSampled):
191+
return True
192+
if isinstance(model, CompressorWithTurbineModel) and isinstance(model.compressor_model, CompressorModelSampled):
193+
return True
194+
return False
195+
196+
185197
@overload
186198
def _create_fluid_factory(fluid_model: None) -> None: ...
187199

@@ -1188,6 +1200,7 @@ def _map_multiple_streams_compressor(
11881200
intermediate_pressure=interstage_control_pressure,
11891201
)
11901202

1203+
assert fluid_factories is not None
11911204
evaluation_input = CompressorEvaluationInput(
11921205
rate_expression=rates_per_stream,
11931206
fluid_factory=fluid_factories,
@@ -1279,40 +1292,34 @@ def _map_compressor(
12791292
discharge_pressure=discharge_pressure,
12801293
)
12811294

1282-
evaluation_input = CompressorEvaluationInput(
1283-
rate_expression=stream_day_rate,
1284-
fluid_factory=fluid_factory,
1285-
power_loss_factor=power_loss_factor,
1286-
suction_pressure_expression=suction_pressure,
1287-
discharge_pressure_expression=discharge_pressure,
1288-
intermediate_pressure_expression=None,
1289-
)
1290-
12911295
model_id = uuid4()
12921296
# Register the compressor model and its evaluation input in the process service
12931297
# - If it is a sampled model, or a turbine model wrapping a sampled model, treat as non-process.
12941298
# - Otherwise, treat as a process model.
1295-
if isinstance(compressor_model, CompressorModelSampled):
1299+
if _is_sampled_compressor(compressor_model):
1300+
evaluation_input = CompressorSampledEvaluationInput(
1301+
rate_expression=stream_day_rate,
1302+
power_loss_factor=power_loss_factor,
1303+
suction_pressure_expression=suction_pressure,
1304+
discharge_pressure_expression=discharge_pressure,
1305+
)
12961306
component = SimplifiedProcessUnitComponent(id=model_id, name=model.energy_function, type=model.type)
1307+
assert isinstance(compressor_model, CompressorModelSampled | CompressorWithTurbineModel)
12971308
self._process_service.register_simplified_process_unit(
12981309
ecalc_component=component, simplified_process_unit=compressor_model, evaluation_input=evaluation_input
12991310
)
1300-
elif isinstance(compressor_model, CompressorWithTurbineModel):
1301-
if isinstance(compressor_model.compressor_model, CompressorModelSampled):
1302-
component = SimplifiedProcessUnitComponent(id=model_id, name=model.energy_function, type=model.type)
1303-
self._process_service.register_simplified_process_unit(
1304-
ecalc_component=component,
1305-
simplified_process_unit=compressor_model,
1306-
evaluation_input=evaluation_input,
1307-
)
1308-
else:
1309-
component = ProcessSystemComponent(id=model_id, name=model.energy_function, type=model.type)
1310-
self._process_service.register_process_system(
1311-
ecalc_component=component, process_system=compressor_model, evaluation_input=evaluation_input
1312-
)
1313-
13141311
else:
1312+
assert suction_pressure is not None and discharge_pressure is not None and fluid_factory is not None
1313+
evaluation_input = CompressorEvaluationInput(
1314+
rate_expression=stream_day_rate,
1315+
fluid_factory=fluid_factory,
1316+
power_loss_factor=power_loss_factor,
1317+
suction_pressure_expression=suction_pressure,
1318+
discharge_pressure_expression=discharge_pressure,
1319+
intermediate_pressure_expression=None,
1320+
)
13151321
component = ProcessSystemComponent(id=model_id, name=model.energy_function, type=model.type)
1322+
assert isinstance(evaluation_input, CompressorEvaluationInput)
13161323
self._process_service.register_process_system(
13171324
ecalc_component=component, process_system=compressor_model, evaluation_input=evaluation_input
13181325
)

src/libecalc/presentation/yaml/model.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
from libecalc.domain.process.compressor.core.base import CompressorWithTurbineModel
2424
from libecalc.domain.process.compressor.core.sampled import CompressorModelSampled
2525
from libecalc.domain.process.core.results import CompressorTrainResult, PumpModelResult
26-
from libecalc.domain.process.evaluation_input import CompressorEvaluationInput, PumpEvaluationInput
26+
from libecalc.domain.process.evaluation_input import (
27+
CompressorEvaluationInput,
28+
CompressorSampledEvaluationInput,
29+
PumpEvaluationInput,
30+
)
2731
from libecalc.domain.process.pump.pump import PumpModel
2832
from libecalc.dto import ResultOptions
2933
from libecalc.dto.component_graph import ComponentGraph
@@ -390,7 +394,9 @@ def get_process_service(self) -> DefaultProcessService:
390394
@staticmethod
391395
def evaluate_domain_models(
392396
models: dict[UUID, Any],
393-
evaluation_inputs: dict[UUID, CompressorEvaluationInput | PumpEvaluationInput],
397+
evaluation_inputs: dict[
398+
UUID, CompressorEvaluationInput | CompressorSampledEvaluationInput | PumpEvaluationInput
399+
],
394400
) -> dict[UUID, CompressorTrainResult | PumpModelResult]:
395401
"""
396402
Evaluates domain models and returns a mapping: model_id -> evaluated_result.
@@ -401,7 +407,11 @@ def evaluate_domain_models(
401407
assert all(
402408
isinstance(model, allowed_model_types) for model in models.values()
403409
), "All models must be of allowed types"
404-
allowed_evaluation_input_types = (CompressorEvaluationInput, PumpEvaluationInput)
410+
allowed_evaluation_input_types = (
411+
CompressorEvaluationInput,
412+
CompressorSampledEvaluationInput,
413+
PumpEvaluationInput,
414+
)
405415
assert all(
406416
isinstance(evaluation_input, allowed_evaluation_input_types)
407417
for evaluation_input in evaluation_inputs.values()

0 commit comments

Comments
 (0)