Skip to content

Commit b62e2b0

Browse files
committed
refactor: move generation of generic from input chart
1 parent 92c7457 commit b62e2b0

File tree

4 files changed

+94
-18
lines changed

4 files changed

+94
-18
lines changed

src/libecalc/domain/infrastructure/energy_components/legacy_consumer/consumer_function/compressor_consumer_function.py

+15
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ def evaluate(
119119
condition=condition,
120120
)
121121

122+
# If the compressor model is supposed to have stages, make sure they are defined
123+
# (compressor sampled does not have stages)
124+
if isinstance(self._compressor_function, CompressorWithTurbineModel):
125+
self._compressor_function.compressor_model.check_for_undefined_stages(
126+
rate=stream_day_rate_after_condition,
127+
suction_pressure=suction_pressure,
128+
discharge_pressure=discharge_pressure,
129+
)
130+
else:
131+
self._compressor_function.check_for_undefined_stages(
132+
rate=stream_day_rate_after_condition,
133+
suction_pressure=suction_pressure,
134+
discharge_pressure=discharge_pressure,
135+
)
136+
122137
compressor_train_result: CompressorTrainResult
123138
# Do not input regularity to compressor function. Handled outside
124139
# intermediate_pressure will only be different from None when we have a MultipleStreamsAndPressures train

src/libecalc/domain/process/compressor/core/base.py

+8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@ def evaluate_rate_ps_pd(
4949
"""
5050
raise NotImplementedError
5151

52+
def check_for_undefined_stages(
53+
self,
54+
rate: NDArray[np.float64],
55+
suction_pressure: NDArray[np.float64],
56+
discharge_pressure: NDArray[np.float64],
57+
) -> None:
58+
pass
59+
5260

5361
class CompressorWithTurbineModel(CompressorModel):
5462
def __init__(

src/libecalc/domain/process/compressor/core/train/simplified_train.py

+56-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import math
2-
from abc import abstractmethod
32

43
import numpy as np
54
from numpy.typing import NDArray
@@ -79,15 +78,62 @@ class CompressorTrainSimplified(CompressorTrainModel):
7978
given and the generic unified chart is scaled by these.
8079
"""
8180

82-
@abstractmethod
83-
def get_stages(
81+
def check_for_undefined_stages(
8482
self,
8583
rate: NDArray[np.float64],
8684
suction_pressure: NDArray[np.float64],
8785
discharge_pressure: NDArray[np.float64],
88-
) -> list[CompressorTrainStage]:
89-
"""Implemented in subclasses."""
90-
raise NotImplementedError
86+
) -> None:
87+
# All stages are there, but compressor chart can still be None (GENERIC_FROM_INPUT)
88+
self.stages = self.define_undefined_stages(
89+
suction_pressure=suction_pressure,
90+
discharge_pressure=discharge_pressure,
91+
)
92+
pressure_ratios_per_stage = self.calculate_pressure_ratios_per_stage(
93+
suction_pressure=suction_pressure, discharge_pressure=discharge_pressure
94+
)
95+
stage_inlet_pressure = suction_pressure
96+
mass_rate_kg_per_hour = self.fluid.standard_rate_to_mass_rate(standard_rates=rate)
97+
for stage_number, stage in enumerate(self.stages):
98+
inlet_temperature_kelvin = stage.inlet_temperature_kelvin
99+
inlet_streams = self.fluid.get_fluid_streams(
100+
pressure_bara=stage_inlet_pressure,
101+
temperature_kelvin=np.full_like(rate, fill_value=inlet_temperature_kelvin, dtype=float),
102+
)
103+
inlet_densities_kg_per_m3 = np.asarray([stream.density for stream in inlet_streams])
104+
inlet_actual_rate_m3_per_hour = mass_rate_kg_per_hour / inlet_densities_kg_per_m3
105+
stage_outlet_pressure = np.multiply(stage_inlet_pressure, pressure_ratios_per_stage)
106+
if isinstance(stage, UndefinedCompressorStage):
107+
# Static efficiency regardless of rate and head. This happens if Generic chart from input is used.
108+
def efficiency_as_function_of_rate_and_head(rates, heads):
109+
return np.full_like(rates, fill_value=stage.polytropic_efficiency, dtype=float)
110+
111+
polytropic_enthalpy_change_joule_per_kg, polytropic_efficiency = (
112+
calculate_enthalpy_change_head_iteration(
113+
inlet_streams=inlet_streams,
114+
inlet_temperature_kelvin=inlet_temperature_kelvin,
115+
inlet_pressure=stage_inlet_pressure,
116+
outlet_pressure=stage_outlet_pressure,
117+
molar_mass=self.fluid.molar_mass_kg_per_mol,
118+
polytropic_efficiency_vs_rate_and_head_function=efficiency_as_function_of_rate_and_head,
119+
inlet_actual_rate_m3_per_hour=inlet_actual_rate_m3_per_hour,
120+
)
121+
)
122+
123+
head_joule_per_kg = polytropic_enthalpy_change_joule_per_kg * polytropic_efficiency
124+
self.stages[stage_number] = CompressorTrainStage(
125+
compressor_chart=CompressorChartCreator.from_rate_and_head_values(
126+
actual_volume_rates_m3_per_hour=inlet_actual_rate_m3_per_hour,
127+
heads_joule_per_kg=head_joule_per_kg,
128+
polytropic_efficiency=stage.polytropic_efficiency,
129+
),
130+
inlet_temperature_kelvin=stage.inlet_temperature_kelvin,
131+
remove_liquid_after_cooling=stage.remove_liquid_after_cooling,
132+
pressure_drop_ahead_of_stage=stage.pressure_drop_ahead_of_stage,
133+
)
134+
stage_inlet_pressure = stage_outlet_pressure
135+
136+
return None
91137

92138
def _evaluate_rate_ps_pd(
93139
self,
@@ -111,10 +157,6 @@ def _evaluate_rate_ps_pd(
111157
:param discharge_pressure: discharge pressure [bara]
112158
:return: train result
113159
"""
114-
if isinstance(self, CompressorTrainSimplifiedUnknownStages):
115-
self.stages = self.get_stages(
116-
rate=rate, suction_pressure=suction_pressure, discharge_pressure=discharge_pressure
117-
)
118160

119161
pressure_ratios_per_stage = self.calculate_pressure_ratios_per_stage(
120162
suction_pressure=suction_pressure, discharge_pressure=discharge_pressure
@@ -348,9 +390,8 @@ def __init__(
348390
super().__init__(data_transfer_object)
349391
self.data_transfer_object = data_transfer_object
350392

351-
def get_stages(
393+
def define_undefined_stages(
352394
self,
353-
rate: NDArray[np.float64],
354395
suction_pressure: NDArray[np.float64],
355396
discharge_pressure: NDArray[np.float64],
356397
) -> list[CompressorTrainStage]:
@@ -582,14 +623,13 @@ def __init__(
582623
super().__init__(data_transfer_object)
583624
self.data_transfer_object = data_transfer_object
584625

585-
def get_stages(
626+
def define_undefined_stages(
586627
self,
587-
rate: NDArray[np.float64],
588628
suction_pressure: NDArray[np.float64],
589629
discharge_pressure: NDArray[np.float64],
590630
) -> list[CompressorTrainStage]:
591-
if len(rate) == 0:
592-
# Unable to figure out stages and pressure ratios if there are no rates as input
631+
if len(suction_pressure) == 0:
632+
# Unable to figure out stages and pressure ratios if there are no suction_pressures as input
593633
return []
594634

595635
pressure_ratios = discharge_pressure / suction_pressure

tests/libecalc/core/models/compressor_modelling/test_simplified_compressor_train.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,11 @@ def test_simplified_compressor_train_unknown_stages(simplified_compressor_train_
148148
compressor_train = CompressorTrainSimplifiedUnknownStages(
149149
data_transfer_object=simplified_compressor_train_unknown_stages_dto,
150150
)
151-
151+
compressor_train.check_for_undefined_stages(
152+
rate=np.linspace(start=1000, stop=10000, num=10),
153+
suction_pressure=np.linspace(start=10, stop=20, num=10),
154+
discharge_pressure=np.linspace(start=200, stop=400, num=10),
155+
)
152156
compressor_train.evaluate_rate_ps_pd(
153157
rate=np.linspace(start=1000, stop=10000, num=10),
154158
suction_pressure=np.linspace(start=10, stop=20, num=10),
@@ -162,6 +166,11 @@ def test_simplified_compressor_train_unknown_stages_with_constant_power_adjustme
162166
compressor_train_energy_function = CompressorTrainSimplifiedUnknownStages(
163167
data_transfer_object=simplified_compressor_train_unknown_stages_dto,
164168
)
169+
compressor_train_energy_function.check_for_undefined_stages(
170+
rate=np.linspace(start=1000, stop=10000, num=10),
171+
suction_pressure=np.linspace(start=10, stop=20, num=10),
172+
discharge_pressure=np.linspace(start=200, stop=400, num=10),
173+
)
165174
result_comparison = compressor_train_energy_function.evaluate_rate_ps_pd(
166175
rate=np.linspace(start=1000, stop=10000, num=10),
167176
suction_pressure=np.linspace(start=10, stop=20, num=10),
@@ -401,7 +410,11 @@ def test_compressor_train_simplified_unknown_stages(
401410
simple_compressor_train_model = CompressorTrainSimplifiedUnknownStages(
402411
data_transfer_object=simplified_compressor_train_unknown_stages_generic_compressor_from_input_dto,
403412
)
404-
413+
simple_compressor_train_model.check_for_undefined_stages(
414+
rate=rates,
415+
suction_pressure=suction_pressures,
416+
discharge_pressure=discharge_pressures,
417+
)
405418
results = simple_compressor_train_model.evaluate_rate_ps_pd(
406419
rate=rates,
407420
suction_pressure=suction_pressures,

0 commit comments

Comments
 (0)