Skip to content

Commit f863e02

Browse files
committed
refactor: use-setter-for-asv-recirculation-instead-of-passing-values
1 parent a5463fa commit f863e02

12 files changed

Lines changed: 487 additions & 329 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ def set_evaluation_input(
121121
self._intermediate_pressure = intermediate_pressure
122122
self._fluid_model = fluid_model
123123

124+
def reset_rate_modifiers(self):
125+
for stage in self.stages:
126+
stage.rate_modifier.reset()
127+
124128
def evaluate(
125129
self,
126130
) -> CompressorTrainResult:
@@ -162,6 +166,7 @@ def evaluate(
162166
else [None] * len(self._suction_pressure),
163167
self._discharge_pressure,
164168
):
169+
self.reset_rate_modifiers()
165170
if isinstance(rate_value, np.ndarray):
166171
rate_value = list(rate_value)
167172
constraints_rate = rate_value[0]

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

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,11 @@ def evaluate_given_constraints(
126126
def calculate_compressor_train(
127127
self,
128128
constraints: CompressorTrainEvaluationInput,
129-
asv_rate_fraction: float = 0.0,
130-
asv_additional_mass_rate: float = 0.0,
131129
) -> CompressorTrainResultSingleTimeStep:
132130
"""Calculate compressor train result given inlet conditions and speed
133131
134132
Args:
135133
constraints (CompressorTrainEvaluationInput): The constraints for the evaluation.
136-
asv_rate_fraction:
137-
asv_additional_mass_rate:
138134
139135
Returns:
140136
results including conditions and calculations for each stage and power.
@@ -160,8 +156,6 @@ def calculate_compressor_train(
160156
stage_result = stage.evaluate(
161157
inlet_stream_stage=inlet_stream,
162158
speed=self.shaft.get_speed(),
163-
asv_rate_fraction=asv_rate_fraction,
164-
asv_additional_mass_rate=asv_additional_mass_rate,
165159
)
166160
stage_results.append(stage_result)
167161

@@ -705,9 +699,10 @@ def _calculate_train_result_given_asv_rate_margin(
705699
asv_rate_fraction: float,
706700
) -> CompressorTrainResultSingleTimeStep:
707701
"""Note that we use outside variables for clarity and to avoid class instances."""
702+
for stage in self.stages:
703+
stage.rate_modifier.fraction_of_available_capacity_to_recirculate = asv_rate_fraction
708704
return self.calculate_compressor_train(
709705
constraints=constraints,
710-
asv_rate_fraction=asv_rate_fraction,
711706
)
712707

713708
minimum_asv_fraction = 0.0
@@ -838,6 +833,7 @@ def _evaluate_train_with_common_asv(
838833
def _calculate_train_result_given_mass_rate(
839834
mass_rate_kg_per_hour: float,
840835
) -> CompressorTrainResultSingleTimeStep:
836+
self.reset_rate_modifiers()
841837
return self.calculate_compressor_train(
842838
constraints=constraints.create_conditions_with_new_input(
843839
new_rate=self._fluid_service.mass_rate_to_standard_rate(fluid_model, mass_rate_kg_per_hour),
@@ -847,9 +843,10 @@ def _calculate_train_result_given_mass_rate(
847843
def _calculate_train_result_given_additional_mass_rate(
848844
additional_mass_rate_kg_per_hour: float,
849845
) -> CompressorTrainResultSingleTimeStep:
846+
for stage in self.stages:
847+
stage.rate_modifier.mass_rate_to_recirculate = additional_mass_rate_kg_per_hour
850848
return self.calculate_compressor_train(
851849
constraints=constraints,
852-
asv_additional_mass_rate=additional_mass_rate_kg_per_hour,
853850
)
854851

855852
# outer bounds for minimum and maximum mass rate without individual recirculation on stages will be the

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
maximize_x_given_boolean_condition_function,
1919
)
2020
from libecalc.domain.process.core.results.compressor import TargetPressureStatus
21-
from libecalc.domain.process.entities.shaft import Shaft, VariableSpeedShaft
21+
from libecalc.domain.process.entities.shaft import Shaft
2222
from libecalc.domain.process.value_objects.fluid_stream import FluidService, FluidStream
2323
from libecalc.domain.process.value_objects.fluid_stream.fluid_model import FluidModel
2424

@@ -436,8 +436,6 @@ def _calculate_train_result(std_rate_for_stream: float) -> CompressorTrainResult
436436
def calculate_compressor_train(
437437
self,
438438
constraints: CompressorTrainEvaluationInput,
439-
asv_rate_fraction: float = 0.0,
440-
asv_additional_mass_rate: float = 0.0,
441439
) -> CompressorTrainResultSingleTimeStep:
442440
"""
443441
Simulate the compressor train for the given inlet conditions, stream rates, and shaft speed.
@@ -454,8 +452,6 @@ def calculate_compressor_train(
454452
455453
Args:
456454
constraints (CompressorTrainEvaluationInput): Pressures, stream rates, and speed for the simulation.
457-
asv_rate_fraction (float, optional): Fraction of anti-surge valve recirculation. Defaults to 0.0.
458-
asv_additional_mass_rate (float, optional): Additional mass rate for recirculation. Defaults to 0.0.
459455
460456
Returns:
461457
CompressorTrainResultSingleTimeStep: Object containing inlet/outlet streams, per-stage results, speed,
@@ -509,8 +505,6 @@ def calculate_compressor_train(
509505
rates_out_of_splitter=rates_out_of_splitter,
510506
streams_in_to_mixer=streams_in_to_mixer,
511507
speed=self.shaft.get_speed(),
512-
asv_rate_fraction=asv_rate_fraction,
513-
asv_additional_mass_rate=asv_additional_mass_rate,
514508
)
515509
)
516510

@@ -595,7 +589,8 @@ def find_and_calculate_for_compressor_train_with_two_pressure_requirements(
595589
lower_bound_for_speed=self.minimum_speed, # Only search for a solution within the bounds of the
596590
upper_bound_for_speed=self.maximum_speed, # original, complete compressor train
597591
)
598-
if math.isclose(compressor_train_first_part.shaft.get_speed(), self.minimum_speed, rel_tol=EPSILON):
592+
first_speed = compressor_train_first_part.shaft.get_speed()
593+
if math.isclose(first_speed, self.minimum_speed, rel_tol=EPSILON):
599594
compressor_train_results_first_part_with_optimal_speed_result = (
600595
compressor_train_first_part.evaluate_with_pressure_control_given_constraints(
601596
constraints=constraints_first_part,
@@ -628,8 +623,8 @@ def find_and_calculate_for_compressor_train_with_two_pressure_requirements(
628623
lower_bound_for_speed=self.minimum_speed,
629624
upper_bound_for_speed=self.maximum_speed,
630625
)
631-
632-
if math.isclose(compressor_train_last_part.shaft.get_speed(), self.minimum_speed, rel_tol=EPSILON):
626+
last_speed = compressor_train_last_part.shaft.get_speed()
627+
if math.isclose(last_speed, self.minimum_speed, rel_tol=EPSILON):
633628
compressor_train_results_last_part_with_optimal_speed_result = (
634629
compressor_train_last_part.evaluate_with_pressure_control_given_constraints(
635630
constraints=constraints_last_part,
@@ -647,8 +642,8 @@ def find_and_calculate_for_compressor_train_with_two_pressure_requirements(
647642
Then run the last part as a single speed train with the speed chosen
648643
Fixme: Need to deliver the result in a proper format below.
649644
"""
650-
if compressor_train_first_part.shaft.get_speed() > compressor_train_last_part.shaft.get_speed():
651-
compressor_train_last_part.shaft.set_speed(compressor_train_first_part.shaft.get_speed())
645+
if first_speed > last_speed:
646+
compressor_train_last_part.shaft.set_speed(first_speed)
652647
compressor_train_results_last_part_with_pressure_control = (
653648
compressor_train_last_part.evaluate_with_pressure_control_given_constraints(
654649
constraints=constraints_last_part,
@@ -660,7 +655,6 @@ def find_and_calculate_for_compressor_train_with_two_pressure_requirements(
660655
compressor_train_results_to_return_last_part = compressor_train_results_last_part_with_pressure_control
661656

662657
else:
663-
compressor_train_first_part.shaft.set_speed(compressor_train_last_part.shaft.get_speed())
664658
compressor_train_results_first_part_with_pressure_control = (
665659
compressor_train_first_part.evaluate_with_pressure_control_given_constraints(
666660
constraints=constraints_first_part,
@@ -775,7 +769,7 @@ def split_train_on_stage_number(
775769

776770
compressor_train_first_part = CompressorTrainCommonShaftMultipleStreamsAndPressures(
777771
streams=streams_first_part,
778-
shaft=VariableSpeedShaft(),
772+
shaft=compressor_train.shaft,
779773
energy_usage_adjustment_constant=compressor_train.energy_usage_adjustment_constant,
780774
energy_usage_adjustment_factor=compressor_train.energy_usage_adjustment_factor,
781775
stages=compressor_train.stages[:stage_number],
@@ -823,7 +817,7 @@ def split_train_on_stage_number(
823817
energy_usage_adjustment_factor=compressor_train.energy_usage_adjustment_factor,
824818
stages=compressor_train.stages[stage_number:],
825819
fluid_service=compressor_train._fluid_service,
826-
shaft=VariableSpeedShaft(),
820+
shaft=compressor_train.shaft,
827821
calculate_max_rate=compressor_train.calculate_max_rate
828822
if compressor_train.calculate_max_rate is not None
829823
else False,

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

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -108,54 +108,22 @@ def modify_pressure(self, inlet_stream_stage: FluidStream) -> FluidStream:
108108
return self.pressure_modifier.modify_pressure(inlet_stream_stage)
109109
return inlet_stream_stage
110110

111-
def add_recirculation_rate(
112-
self,
113-
inlet_stream_stage: FluidStream,
114-
speed: float,
115-
asv_rate_fraction: float | None = 0.0,
116-
asv_additional_mass_rate: float | None = 0.0,
117-
) -> FluidStream:
118-
"""Add recirculation rate to the inlet stream.
119-
120-
Args:
121-
inlet_stream_stage (FluidStream): Inlet fluid stream conditions.
122-
speed (float): Compressor shaft speed.
123-
asv_rate_fraction (float): Fraction of available capacity for pressure control. Defaults to 0.0.
124-
asv_additional_mass_rate (float): Additional recirculated mass rate. Defaults to 0.0.
125-
126-
Returns:
127-
FluidStream: Updated inlet stream.
128-
"""
129-
has_asv_rate_fraction = asv_rate_fraction is not None and asv_rate_fraction > 0
130-
has_asv_additional_mass_rate = asv_additional_mass_rate is not None and asv_additional_mass_rate > 0
131-
if has_asv_rate_fraction and has_asv_additional_mass_rate:
132-
raise IllegalStateException("asv_rate_fraction and asv_additional_mass_rate cannot both be > 0")
133-
if asv_rate_fraction is not None and not (0.0 <= asv_rate_fraction <= 1.0):
134-
raise IllegalStateException("asv_rate_fraction must be in [0.0, 1.0]")
135-
136-
actual_rate = inlet_stream_stage.volumetric_rate_m3_per_hour
137-
max_rate = self.compressor.compressor_chart.maximum_rate_as_function_of_speed(speed)
138-
min_rate = self.compressor.compressor_chart.minimum_rate_as_function_of_speed(speed)
139-
140-
available_capacity = max(0, max_rate - actual_rate)
141-
additional_rate = max(
142-
min_rate - actual_rate,
143-
asv_rate_fraction * available_capacity if asv_rate_fraction else 0.0,
144-
asv_additional_mass_rate / inlet_stream_stage.density if asv_additional_mass_rate else 0.0,
111+
def add_rate(self, inlet_stream_stage: FluidStream) -> FluidStream:
112+
return self.rate_modifier.add_rate(
113+
stream=inlet_stream_stage,
145114
)
146115

147-
self.rate_modifier.recirculation_mass_rate = additional_rate * inlet_stream_stage.density
148-
149-
return self.rate_modifier.add_rate(inlet_stream_stage)
116+
def remove_rate(self, outlet_stream_stage: FluidStream) -> FluidStream:
117+
return self.rate_modifier.remove_rate(
118+
stream=outlet_stream_stage,
119+
)
150120

151121
def evaluate(
152122
self,
153123
inlet_stream_stage: FluidStream,
154124
speed: float,
155125
rates_out_of_splitter: list[float] | None = None,
156126
streams_in_to_mixer: list[FluidStream] | None = None,
157-
asv_rate_fraction: float | None = 0.0,
158-
asv_additional_mass_rate: float | None = 0.0,
159127
) -> CompressorTrainStageResultSingleTimeStep:
160128
"""Evaluates a compressor train stage given the conditions and rate of the inlet stream, and the speed
161129
of the shaft driving the compressor if given.
@@ -166,10 +134,6 @@ def evaluate(
166134
speed (float): The speed of the shaft driving the compressor
167135
rates_out_of_splitter (list[float] | None, optional): Additional rates to the Splitter if defined.
168136
streams_in_to_mixer (list[FluidStream] | None, optional): Additional streams to the Mixer if defined.
169-
asv_rate_fraction (float | None, optional): Fraction of the available capacity of the compressor to fill
170-
using some kind of pressure control (on the interval [0,1]). Defaults to 0.0.
171-
asv_additional_mass_rate (float | None, optional): Additional recirculated mass rate due to
172-
pressure control. Defaults to 0.0.
173137
174138
Returns:
175139
CompressorTrainStageResultSingleTimeStep: The result of the evaluation for the compressor stage
@@ -212,11 +176,8 @@ def evaluate(
212176
inlet_stream_compressor = inlet_stream_after_liquid_remover
213177

214178
# Then additional rate is added by the RateModifier (if defined),
215-
inlet_stream_compressor_including_asv = self.add_recirculation_rate(
179+
inlet_stream_compressor_including_asv = self.add_rate(
216180
inlet_stream_stage=inlet_stream_compressor,
217-
speed=speed,
218-
asv_rate_fraction=asv_rate_fraction,
219-
asv_additional_mass_rate=asv_additional_mass_rate,
220181
)
221182

222183
# Compressor
@@ -366,10 +327,10 @@ def evaluate_given_speed_and_target_discharge_pressure(
366327
if isinstance(self.compressor.compressor_chart, CompressorChart) and speed is None:
367328
speed = self.compressor.compressor_chart.minimum_speed
368329

330+
self.rate_modifier.mass_rate_to_recirculate = 0
369331
result_no_recirculation = self.evaluate(
370332
inlet_stream_stage=inlet_stream_stage,
371333
speed=speed,
372-
asv_additional_mass_rate=0,
373334
)
374335

375336
# result_no_recirculation.inlet_stream.density_kg_per_m3 will have correct pressure and temperature
@@ -382,9 +343,9 @@ def evaluate_given_speed_and_target_discharge_pressure(
382343
- EPSILON,
383344
0,
384345
)
346+
self.rate_modifier.mass_rate_to_recirculate = max_recirculation
385347
result_max_recirculation = self.evaluate(
386348
inlet_stream_stage=inlet_stream_stage,
387-
asv_additional_mass_rate=max_recirculation,
388349
speed=speed,
389350
)
390351
if result_no_recirculation.discharge_pressure < target_discharge_pressure:
@@ -395,9 +356,9 @@ def evaluate_given_speed_and_target_discharge_pressure(
395356
def _calculate_compressor_stage(
396357
additional_mass_rate: float,
397358
) -> CompressorTrainStageResultSingleTimeStep:
359+
self.rate_modifier.mass_rate_to_recirculate = additional_mass_rate
398360
return self.evaluate(
399361
inlet_stream_stage=inlet_stream_stage,
400-
asv_additional_mass_rate=additional_mass_rate,
401362
speed=speed,
402363
)
403364

0 commit comments

Comments
 (0)