Skip to content

Commit da0726f

Browse files
authored
refactor: use setter for asv recirculation instead of passing values (#1283)
chore: update snapshot
1 parent 5cf8b6e commit da0726f

File tree

10 files changed

+229
-98
lines changed

10 files changed

+229
-98
lines changed

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: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ def evaluate_given_constraints(
102102
fixed_speed: float | None = None,
103103
) -> CompressorTrainResultSingleTimeStep:
104104
if constraints.rate > 0: # type: ignore[operator]
105+
self.reset_rate_modifiers()
105106
if fixed_speed is None:
106107
self.find_fixed_shaft_speed_given_constraints(constraints=constraints)
107108
train_result = self.calculate_compressor_train(
@@ -125,15 +126,11 @@ def evaluate_given_constraints(
125126
def calculate_compressor_train(
126127
self,
127128
constraints: CompressorTrainEvaluationInput,
128-
asv_rate_fraction: float = 0.0,
129-
asv_additional_mass_rate: float = 0.0,
130129
) -> CompressorTrainResultSingleTimeStep:
131130
"""Calculate compressor train result given inlet conditions and speed
132131
133132
Args:
134133
constraints (CompressorTrainEvaluationInput): The constraints for the evaluation.
135-
asv_rate_fraction:
136-
asv_additional_mass_rate:
137134
138135
Returns:
139136
results including conditions and calculations for each stage and power.
@@ -158,8 +155,6 @@ def calculate_compressor_train(
158155
inlet_stream = outlet_stream
159156
stage_result = stage.evaluate(
160157
inlet_stream_stage=inlet_stream,
161-
asv_rate_fraction=asv_rate_fraction,
162-
asv_additional_mass_rate=asv_additional_mass_rate,
163158
)
164159
stage_results.append(stage_result)
165160

@@ -704,9 +699,10 @@ def _calculate_train_result_given_asv_rate_margin(
704699
asv_rate_fraction: float,
705700
) -> CompressorTrainResultSingleTimeStep:
706701
"""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
707704
return self.calculate_compressor_train(
708705
constraints=constraints,
709-
asv_rate_fraction=asv_rate_fraction,
710706
)
711707

712708
minimum_asv_fraction = 0.0
@@ -837,6 +833,7 @@ def _evaluate_train_with_common_asv(
837833
def _calculate_train_result_given_mass_rate(
838834
mass_rate_kg_per_hour: float,
839835
) -> CompressorTrainResultSingleTimeStep:
836+
self.reset_rate_modifiers()
840837
return self.calculate_compressor_train(
841838
constraints=constraints.create_conditions_with_new_input(
842839
new_rate=self._fluid_service.mass_rate_to_standard_rate(fluid_model, mass_rate_kg_per_hour),
@@ -846,9 +843,10 @@ def _calculate_train_result_given_mass_rate(
846843
def _calculate_train_result_given_additional_mass_rate(
847844
additional_mass_rate_kg_per_hour: float,
848845
) -> CompressorTrainResultSingleTimeStep:
846+
for stage in self.stages:
847+
stage.rate_modifier.mass_rate_to_recirculate = additional_mass_rate_kg_per_hour
849848
return self.calculate_compressor_train(
850849
constraints=constraints,
851-
asv_additional_mass_rate=additional_mass_rate_kg_per_hour,
852850
)
853851

854852
# 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: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ def _calculate_train_result(std_rate_for_stream: float) -> CompressorTrainResult
393393
"""Partial function of self.evaluate_given_constraints
394394
where we only pass std_rate_per_stream.
395395
"""
396+
self.reset_rate_modifiers()
396397
std_rates_std_m3_per_day_per_stream[constraints.stream_to_maximize] = std_rate_for_stream
397398
return self.evaluate_given_constraints(
398399
constraints=constraints.create_conditions_with_new_input(
@@ -405,6 +406,7 @@ def _calculate_train_result(std_rate_for_stream: float) -> CompressorTrainResult
405406
constraints=constraints,
406407
)
407408
if not train_result.is_valid:
409+
self.reset_rate_modifiers()
408410
zero_stream_result = _calculate_train_result(std_rate_for_stream=EPSILON)
409411
if not zero_stream_result.is_valid:
410412
return 0.0
@@ -436,8 +438,6 @@ def _calculate_train_result(std_rate_for_stream: float) -> CompressorTrainResult
436438
def calculate_compressor_train(
437439
self,
438440
constraints: CompressorTrainEvaluationInput,
439-
asv_rate_fraction: float = 0.0,
440-
asv_additional_mass_rate: float = 0.0,
441441
) -> CompressorTrainResultSingleTimeStep:
442442
"""
443443
Simulate the compressor train for the given inlet conditions, stream rates, and shaft speed.
@@ -454,8 +454,6 @@ def calculate_compressor_train(
454454
455455
Args:
456456
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.
459457
460458
Returns:
461459
CompressorTrainResultSingleTimeStep: Object containing inlet/outlet streams, per-stage results, speed,
@@ -508,8 +506,6 @@ def calculate_compressor_train(
508506
inlet_stream_stage=stage_inlet_stream,
509507
rates_out_of_splitter=rates_out_of_splitter,
510508
streams_in_to_mixer=streams_in_to_mixer,
511-
asv_rate_fraction=asv_rate_fraction,
512-
asv_additional_mass_rate=asv_additional_mass_rate,
513509
)
514510
)
515511

@@ -624,13 +620,13 @@ def find_and_calculate_for_compressor_train_with_two_pressure_requirements(
624620
assert isinstance(compressor_train_last_part._fluid_model, list) # for mypy
625621
compressor_train_last_part._fluid_model[0] = compressor_train_last_part.streams[0].fluid_model
626622

623+
# Get the speed found for the last part - will be used to compare with the first part
627624
shaft_speed_last_part = compressor_train_last_part.find_fixed_shaft_speed_given_constraints(
628625
constraints=constraints_last_part,
629626
lower_bound_for_speed=self.minimum_speed,
630627
upper_bound_for_speed=self.maximum_speed,
631628
)
632629

633-
# Get the speed found for the last part - will be used to compare with the first part
634630
if math.isclose(shaft_speed_last_part, self.minimum_speed, rel_tol=EPSILON):
635631
compressor_train_results_last_part_with_optimal_speed_result = (
636632
compressor_train_last_part.evaluate_with_pressure_control_given_constraints(

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

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -101,51 +101,21 @@ def modify_pressure(self, inlet_stream_stage: FluidStream) -> FluidStream:
101101
return self.pressure_modifier.modify_pressure(inlet_stream_stage)
102102
return inlet_stream_stage
103103

104-
def add_recirculation_rate(
105-
self,
106-
inlet_stream_stage: FluidStream,
107-
asv_rate_fraction: float | None = 0.0,
108-
asv_additional_mass_rate: float | None = 0.0,
109-
) -> FluidStream:
110-
"""Add recirculation rate to the inlet stream.
111-
112-
Args:
113-
inlet_stream_stage (FluidStream): Inlet fluid stream conditions.
114-
asv_rate_fraction (float): Fraction of available capacity for pressure control. Defaults to 0.0.
115-
asv_additional_mass_rate (float): Additional recirculated mass rate. Defaults to 0.0.
116-
117-
Returns:
118-
FluidStream: Updated inlet stream.
119-
"""
120-
has_asv_rate_fraction = asv_rate_fraction is not None and asv_rate_fraction > 0
121-
has_asv_additional_mass_rate = asv_additional_mass_rate is not None and asv_additional_mass_rate > 0
122-
if has_asv_rate_fraction and has_asv_additional_mass_rate:
123-
raise IllegalStateException("asv_rate_fraction and asv_additional_mass_rate cannot both be > 0")
124-
if asv_rate_fraction is not None and not (0.0 <= asv_rate_fraction <= 1.0):
125-
raise IllegalStateException("asv_rate_fraction must be in [0.0, 1.0]")
126-
127-
actual_rate = inlet_stream_stage.volumetric_rate_m3_per_hour
128-
max_rate = self.compressor.get_max_rate()
129-
min_rate = self.compressor.get_min_rate()
130-
131-
available_capacity = max(0.0, max_rate - actual_rate)
132-
additional_rate = max(
133-
min_rate - actual_rate,
134-
asv_rate_fraction * available_capacity if asv_rate_fraction else 0.0,
135-
asv_additional_mass_rate / inlet_stream_stage.density if asv_additional_mass_rate else 0.0,
104+
def add_rate(self, inlet_stream_stage: FluidStream) -> FluidStream:
105+
return self.rate_modifier.add_rate(
106+
stream=inlet_stream_stage,
136107
)
137108

138-
self.rate_modifier.recirculation_mass_rate = additional_rate * inlet_stream_stage.density
139-
140-
return self.rate_modifier.add_rate(inlet_stream_stage)
109+
def remove_rate(self, outlet_stream_stage: FluidStream) -> FluidStream:
110+
return self.rate_modifier.remove_rate(
111+
stream=outlet_stream_stage,
112+
)
141113

142114
def evaluate(
143115
self,
144116
inlet_stream_stage: FluidStream,
145117
rates_out_of_splitter: list[float] | None = None,
146118
streams_in_to_mixer: list[FluidStream] | None = None,
147-
asv_rate_fraction: float | None = 0.0,
148-
asv_additional_mass_rate: float | None = 0.0,
149119
) -> CompressorTrainStageResultSingleTimeStep:
150120
"""Evaluates a compressor train stage given the conditions and rate of the inlet stream, and the speed
151121
of the shaft driving the compressor if given.
@@ -155,10 +125,6 @@ def evaluate(
155125
the first one is the stage inlet stream, the others enter the stage at the Mixer.
156126
rates_out_of_splitter (list[float] | None, optional): Additional rates to the Splitter if defined.
157127
streams_in_to_mixer (list[FluidStream] | None, optional): Additional streams to the Mixer if defined.
158-
asv_rate_fraction (float | None, optional): Fraction of the available capacity of the compressor to fill
159-
using some kind of pressure control (on the interval [0,1]). Defaults to 0.0.
160-
asv_additional_mass_rate (float | None, optional): Additional recirculated mass rate due to
161-
pressure control. Defaults to 0.0.
162128
163129
Returns:
164130
CompressorTrainStageResultSingleTimeStep: The result of the evaluation for the compressor stage
@@ -201,10 +167,8 @@ def evaluate(
201167
inlet_stream_compressor = inlet_stream_after_liquid_remover
202168

203169
# Then additional rate is added by the RateModifier (if defined),
204-
inlet_stream_compressor_including_asv = self.add_recirculation_rate(
170+
inlet_stream_compressor_including_asv = self.add_rate(
205171
inlet_stream_stage=inlet_stream_compressor,
206-
asv_rate_fraction=asv_rate_fraction,
207-
asv_additional_mass_rate=asv_additional_mass_rate,
208172
)
209173

210174
# Compressor
@@ -332,9 +296,9 @@ def evaluate_given_speed_and_target_discharge_pressure(
332296
"""
333297
# If no speed is defined for CompressorChart, use the minimum speed
334298

299+
self.rate_modifier.mass_rate_to_recirculate = 0
335300
result_no_recirculation = self.evaluate(
336301
inlet_stream_stage=inlet_stream_stage,
337-
asv_additional_mass_rate=0,
338302
)
339303

340304
# result_no_recirculation.inlet_stream.density_kg_per_m3 will have correct pressure and temperature
@@ -347,9 +311,9 @@ def evaluate_given_speed_and_target_discharge_pressure(
347311
- EPSILON,
348312
0,
349313
)
314+
self.rate_modifier.mass_rate_to_recirculate = max_recirculation
350315
result_max_recirculation = self.evaluate(
351316
inlet_stream_stage=inlet_stream_stage,
352-
asv_additional_mass_rate=max_recirculation,
353317
)
354318
if result_no_recirculation.discharge_pressure < target_discharge_pressure:
355319
return result_no_recirculation
@@ -359,9 +323,9 @@ def evaluate_given_speed_and_target_discharge_pressure(
359323
def _calculate_compressor_stage(
360324
additional_mass_rate: float,
361325
) -> CompressorTrainStageResultSingleTimeStep:
326+
self.rate_modifier.mass_rate_to_recirculate = additional_mass_rate
362327
return self.evaluate(
363328
inlet_stream_stage=inlet_stream_stage,
364-
asv_additional_mass_rate=additional_mass_rate,
365329
)
366330

367331
result_mass_rate = find_root(

0 commit comments

Comments
 (0)