1
1
import math
2
- from abc import abstractmethod
3
2
4
3
import numpy as np
5
4
from numpy .typing import NDArray
@@ -79,15 +78,62 @@ class CompressorTrainSimplified(CompressorTrainModel):
79
78
given and the generic unified chart is scaled by these.
80
79
"""
81
80
82
- @abstractmethod
83
- def get_stages (
81
+ def check_for_undefined_stages (
84
82
self ,
85
83
rate : NDArray [np .float64 ],
86
84
suction_pressure : NDArray [np .float64 ],
87
85
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
91
137
92
138
def _evaluate_rate_ps_pd (
93
139
self ,
@@ -111,10 +157,6 @@ def _evaluate_rate_ps_pd(
111
157
:param discharge_pressure: discharge pressure [bara]
112
158
:return: train result
113
159
"""
114
- if isinstance (self , CompressorTrainSimplifiedUnknownStages ):
115
- self .stages = self .get_stages (
116
- rate = rate , suction_pressure = suction_pressure , discharge_pressure = discharge_pressure
117
- )
118
160
119
161
pressure_ratios_per_stage = self .calculate_pressure_ratios_per_stage (
120
162
suction_pressure = suction_pressure , discharge_pressure = discharge_pressure
@@ -348,9 +390,8 @@ def __init__(
348
390
super ().__init__ (data_transfer_object )
349
391
self .data_transfer_object = data_transfer_object
350
392
351
- def get_stages (
393
+ def define_undefined_stages (
352
394
self ,
353
- rate : NDArray [np .float64 ],
354
395
suction_pressure : NDArray [np .float64 ],
355
396
discharge_pressure : NDArray [np .float64 ],
356
397
) -> list [CompressorTrainStage ]:
@@ -582,14 +623,13 @@ def __init__(
582
623
super ().__init__ (data_transfer_object )
583
624
self .data_transfer_object = data_transfer_object
584
625
585
- def get_stages (
626
+ def define_undefined_stages (
586
627
self ,
587
- rate : NDArray [np .float64 ],
588
628
suction_pressure : NDArray [np .float64 ],
589
629
discharge_pressure : NDArray [np .float64 ],
590
630
) -> 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
593
633
return []
594
634
595
635
pressure_ratios = discharge_pressure / suction_pressure
0 commit comments