1- from abc import ABC , abstractmethod
1+ from abc import ABC
22from collections .abc import Callable
33from functools import partial
44from typing import Generic , TypeVar , cast
@@ -69,13 +69,6 @@ def _register_pressure_control_strategies(cls):
6969 FixedSpeedPressureControl .COMMON_ASV : cls ._evaluate_train_with_common_asv ,
7070 }
7171
72- def _get_inlet_stream (self , pressure_bara : float , temperature_kelvin : float ) -> FluidStream :
73- """Helper to create a FluidStream for a given pressure and temperature."""
74- return self .fluid .get_fluid_stream (
75- pressure_bara = pressure_bara ,
76- temperature_kelvin = temperature_kelvin ,
77- )
78-
7972 def _create_constraints (
8073 self ,
8174 suction_pressure : float ,
@@ -241,28 +234,6 @@ def evaluate(
241234 ],
242235 )
243236
244- @abstractmethod
245- def evaluate_given_constraints (
246- self , constraints : CompressorTrainEvaluationInput
247- ) -> CompressorTrainResultSingleTimeStep :
248- """
249- Evaluate the compressor model based on the set constraints.
250-
251- The constraints can be:
252- * Rate (train inlet)
253- * Additional rates for each stream (if multiple streams)
254- * Suction pressure (train inlet)
255- * Discharge pressure (train outlet)
256- * Intermediate pressure (inter-stage)
257- * Speed (if variable speed)
258-
259- The evaluation is done for a single time step.
260-
261- Return:
262- CompressorTrainResultSingleTimeStep: The result of the compressor train evaluation.
263- """
264- ...
265-
266237 def calculate_pressure_ratios_per_stage (
267238 self ,
268239 suction_pressure : NDArray [np .float64 ] | float ,
@@ -983,19 +954,21 @@ def _get_max_std_rate_single_timestep(
983954 Standard volume rate [Sm3/day]
984955
985956 """
986- inlet_stream = self ._get_inlet_stream (
987- pressure_bara = constraints .suction_pressure , # type: ignore[arg-type]
957+ assert constraints .suction_pressure is not None
958+ assert constraints .rate is not None
959+ inlet_density = self .fluid_factory .create_stream_from_standard_rate (
960+ pressure_bara = constraints .suction_pressure ,
988961 temperature_kelvin = self .stages [0 ].inlet_temperature_kelvin ,
989- )
990- inlet_density = inlet_stream .density
962+ standard_rate_m3_per_day = constraints . rate ,
963+ ) .density
991964
992965 def _calculate_train_result (mass_rate : float , speed : float ) -> CompressorTrainResultSingleTimeStep :
993966 """Partial function of self.calculate_compressor_train_given_speed
994967 where we only pass mass_rate.
995968 """
996969 return self .calculate_compressor_train (
997970 constraints = constraints .create_conditions_with_new_input (
998- new_rate = self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = mass_rate ), # type: ignore[arg-type]
971+ new_rate = self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = mass_rate ), # type: ignore[arg-type]
999972 new_speed = speed ,
1000973 )
1001974 )
@@ -1006,7 +979,7 @@ def _calculate_train_result_given_ps_pd(mass_rate: float) -> CompressorTrainResu
1006979 """
1007980 return self .evaluate_given_constraints (
1008981 constraints = constraints .create_conditions_with_new_input (
1009- new_rate = self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = mass_rate ), # type: ignore[arg-type]
982+ new_rate = self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = mass_rate ), # type: ignore[arg-type]
1010983 )
1011984 )
1012985
@@ -1018,17 +991,17 @@ def _calculate_train_result_given_speed_at_stone_wall(
1018991 """
1019992 assert not isinstance (self .data_transfer_object , SingleSpeedCompressorTrainDTO )
1020993 _max_valid_mass_rate_at_given_speed = maximize_x_given_boolean_condition_function (
1021- x_min = self .stages [0 ].compressor_chart .minimum_rate_as_function_of_speed (speed ) * inlet_density , # or 0?
1022- x_max = self .stages [0 ].compressor_chart .maximum_rate_as_function_of_speed (speed ) * inlet_density ,
994+ x_min = self .stages [0 ].compressor_chart .minimum_rate_as_function_of_speed (speed ) * inlet_density , # type: ignore[arg-type]
995+ x_max = self .stages [0 ].compressor_chart .maximum_rate_as_function_of_speed (speed ) * inlet_density , # type: ignore[arg-type]
1023996 bool_func = lambda x : _calculate_train_result (mass_rate = x , speed = speed ).within_capacity ,
1024997 convergence_tolerance = 1e-3 ,
1025998 maximum_number_of_iterations = 20 ,
1026999 )
10271000
10281001 return self .calculate_compressor_train (
10291002 constraints = constraints .create_conditions_with_new_input (
1030- new_rate = self .fluid .mass_rate_to_standard_rate (
1031- mass_rate_kg_per_hour = _max_valid_mass_rate_at_given_speed
1003+ new_rate = self .fluid_factory .mass_rate_to_standard_rate (
1004+ mass_rate_kg_per_h = _max_valid_mass_rate_at_given_speed
10321005 ), # type: ignore[arg-type]
10331006 new_speed = speed ,
10341007 )
@@ -1068,7 +1041,7 @@ def _calculate_train_result_given_speed_at_stone_wall(
10681041 mass_rate = max_mass_rate_at_max_speed_first_stage
10691042 )
10701043 result_max_mass_rate_at_min_speed_first_stage = _calculate_train_result_at_min_speed_given_mass_rate (
1071- mass_rate = max_mass_rate_at_min_speed_first_stage
1044+ mass_rate = max_mass_rate_at_min_speed_first_stage # type: ignore[arg-type]
10721045 )
10731046
10741047 # Ensure that the minimum mass rate at max speed is valid for the whole train.
@@ -1171,7 +1144,7 @@ def _calculate_train_result_given_speed_at_stone_wall(
11711144 if not result_max_mass_rate_at_min_speed_first_stage .within_capacity :
11721145 max_mass_rate_at_min_speed = maximize_x_given_boolean_condition_function (
11731146 x_min = EPSILON ,
1174- x_max = max_mass_rate_at_min_speed_first_stage ,
1147+ x_max = max_mass_rate_at_min_speed_first_stage , # type: ignore[arg-type]
11751148 bool_func = lambda x : _calculate_train_result_at_min_speed_given_mass_rate (
11761149 mass_rate = x
11771150 ).within_capacity ,
@@ -1217,11 +1190,11 @@ def _calculate_train_result_given_speed_at_stone_wall(
12171190 # Check that rate_to_return, suction_pressure and discharge_pressure does not require too much power.
12181191 # If so, reduce rate such that power comes below maximum power
12191192 if not self .data_transfer_object .maximum_power :
1220- return self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = rate_to_return )
1193+ return self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = rate_to_return )
12211194 elif (
12221195 self .evaluate_given_constraints (
12231196 constraints = constraints .create_conditions_with_new_input (
1224- new_rate = self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = rate_to_return ), # type: ignore[arg-type]
1197+ new_rate = self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = rate_to_return ), # type: ignore[arg-type]
12251198 )
12261199 ).power_megawatt
12271200 > self .data_transfer_object .maximum_power
@@ -1238,13 +1211,13 @@ def _calculate_train_result_given_speed_at_stone_wall(
12381211 else :
12391212 # iterate between rate with minimum power, and the previously found rate to return, to find the
12401213 # maximum rate that gives power consumption below maximum power
1241- return self .fluid .mass_rate_to_standard_rate (
1242- mass_rate_kg_per_hour = find_root (
1214+ return self .fluid_factory .mass_rate_to_standard_rate (
1215+ mass_rate_kg_per_h = find_root (
12431216 lower_bound = result_with_minimum_rate .stage_results [0 ].mass_rate_asv_corrected_kg_per_hour ,
12441217 upper_bound = rate_to_return ,
12451218 func = lambda x : self .evaluate_given_constraints (
12461219 constraints = constraints .create_conditions_with_new_input (
1247- new_rate = self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = x ), # type: ignore[arg-type]
1220+ new_rate = self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = x ), # type: ignore[arg-type]
12481221 )
12491222 ).power_megawatt
12501223 - maximum_power * (1 - POWER_CALCULATION_TOLERANCE ),
@@ -1254,7 +1227,7 @@ def _calculate_train_result_given_speed_at_stone_wall(
12541227 )
12551228 else :
12561229 # maximum power defined, but found rate is below maximum power
1257- return self .fluid .mass_rate_to_standard_rate (mass_rate_kg_per_hour = rate_to_return )
1230+ return self .fluid_factory .mass_rate_to_standard_rate (mass_rate_kg_per_h = rate_to_return )
12581231
12591232 def calculate_compressor_train (
12601233 self ,
@@ -1279,41 +1252,36 @@ def calculate_compressor_train(
12791252 message = "Compressor train calculation requires rate and suction pressure to be set." ,
12801253 )
12811254 # Initialize stream at inlet of first compressor stage using fluid properties and inlet conditions
1282- train_inlet_stream = self ._get_inlet_stream (
1255+ train_inlet_stream = self .fluid_factory . create_stream_from_standard_rate (
12831256 pressure_bara = constraints .suction_pressure - self .stages [0 ].pressure_drop_ahead_of_stage , # type: ignore[operator]
12841257 temperature_kelvin = self .stages [0 ].inlet_temperature_kelvin ,
1258+ standard_rate_m3_per_day = constraints .rate ,
12851259 )
1286- mass_rate_kg_per_hour = self .fluid .standard_rate_to_mass_rate (standard_rates = constraints .rate )
12871260 stage_results : list [CompressorTrainStageResultSingleTimeStep ] = []
12881261 outlet_stream = train_inlet_stream
12891262 for stage in self .stages :
12901263 inlet_stream = outlet_stream
12911264 stage_result = stage .evaluate (
12921265 inlet_stream_stage = inlet_stream ,
12931266 speed = constraints .speed ,
1294- mass_rate_kg_per_hour = mass_rate_kg_per_hour , # type: ignore[arg-type]
12951267 asv_rate_fraction = asv_rate_fraction ,
12961268 asv_additional_mass_rate = asv_additional_mass_rate ,
12971269 )
12981270 stage_results .append (stage_result )
12991271
13001272 # We need to recreate the domain object from the result object. This needs cleaning up.
1301- outlet_stream = inlet_stream .set_new_pressure_and_temperature (
1302- new_pressure_bara = stage_result .outlet_stream .pressure_bara ,
1303- new_temperature_kelvin = stage_result .outlet_stream .temperature_kelvin ,
1304- )
1305-
1273+ outlet_stream = stage_result .outlet_stream
13061274 # check if target pressures are met
13071275 target_pressure_status = self .check_target_pressures (
13081276 constraints = constraints ,
13091277 results = stage_results ,
13101278 )
13111279
13121280 return CompressorTrainResultSingleTimeStep (
1313- inlet_stream = FluidStreamDTO . from_fluid_domain_object ( fluid_stream = train_inlet_stream ) ,
1314- outlet_stream = FluidStreamDTO . from_fluid_domain_object ( fluid_stream = outlet_stream ) ,
1281+ inlet_stream = train_inlet_stream ,
1282+ outlet_stream = outlet_stream ,
13151283 stage_results = stage_results ,
1316- speed = constraints .speed if constraints . speed is not None else float ( "nan" ),
1284+ speed = constraints .speed , # type: ignore[arg-type]
13171285 above_maximum_power = sum ([stage_result .power_megawatt for stage_result in stage_results ])
13181286 > self .maximum_power
13191287 if self .maximum_power
0 commit comments