STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
physics_based_replacements.py
Go to the documentation of this file.
1"""Physics-based replacements for arbitrary multipliers.
2
3This module provides physics-based calculations to replace arbitrary factors
4and multipliers throughout the codebase.
5"""
6
7from __future__ import annotations
8
9from typing import Dict, Optional
10import numpy as np
11
12
14 D_chamber: float,
15 d_pintle_tip: float,
16 fuel_velocity: float,
17 lox_velocity: float,
18 Re_chamber: float,
19) -> float:
20 """
21 Calculate recirculation length based on physics.
22
23 Physics:
24 - Recirculation length scales with chamber diameter
25 - Depends on Reynolds number (turbulent flow)
26 - Depends on velocity ratio (fuel/LOX)
27 - Typical: L_recirc = 0.2-0.4 * D_chamber for turbulent jets
28
29 Parameters:
30 -----------
31 D_chamber : float
32 Chamber diameter [m]
33 d_pintle_tip : float
34 Pintle tip diameter [m]
35 fuel_velocity : float
36 Fuel injection velocity [m/s]
37 lox_velocity : float
38 LOX injection velocity [m/s]
39 Re_chamber : float
40 Chamber Reynolds number
41
42 Returns:
43 --------
44 L_recirc : float
45 Recirculation length [m]
46 """
47 # Base recirculation length from turbulent jet theory
48 # For turbulent jets: L_recirc ~ 0.2-0.4 * D_chamber
49 # Depends on Reynolds number: higher Re = longer recirculation
50 Re_factor = np.clip(Re_chamber / 1e5, 0.5, 2.0) # Normalize to 1e5
51 base_factor = 0.2 + 0.1 * np.log10(max(Re_factor, 0.1)) # 0.2-0.3 range
52
53 # Velocity ratio effect: higher velocity ratio = longer recirculation
54 velocity_ratio = fuel_velocity / (lox_velocity + 1e-10)
55 velocity_factor = 1.0 + 0.2 * np.clip(velocity_ratio - 1.0, 0.0, 2.0)
56
57 # Pintle size effect: larger pintle = larger recirculation zone
58 pintle_ratio = d_pintle_tip / (D_chamber + 1e-10)
59 pintle_factor = 1.0 + 0.3 * np.clip(pintle_ratio - 0.1, 0.0, 0.3)
60
61 L_recirc = base_factor * D_chamber * velocity_factor * pintle_factor
62
63 return float(np.clip(L_recirc, 0.1 * D_chamber, 0.5 * D_chamber))
64
65
67 evaporation_length: float,
68 chamber_length: float,
69 SMD: float,
70 target_smd: float,
71 Pc: float,
72 Tc: float,
73) -> float:
74 """
75 Calculate evaporation factor based on physics.
76
77 Physics:
78 - If evaporation_length < chamber_length: good evaporation
79 - Factor based on d^2-law evaporation: t_evap ~ d^2 / K
80 - Accounts for incomplete evaporation when L_evap > L_chamber
81
82 Parameters:
83 -----------
84 evaporation_length : float
85 Evaporation length [m]
86 chamber_length : float
87 Chamber length [m]
88 SMD : float
89 Sauter mean diameter [m]
90 target_smd : float
91 Target SMD [m]
92 Pc : float
93 Chamber pressure [Pa]
94 Tc : float
95 Chamber temperature [K]
96
97 Returns:
98 --------
99 evap_factor : float
100 Evaporation factor (0-1, higher = better)
101 """
102 if chamber_length <= 0:
103 return 0.5 # Unknown
104
105 # Evaporation ratio: how much of chamber is needed for evaporation
106 evap_ratio = evaporation_length / chamber_length
107
108 # Physics: evaporation efficiency based on residence time vs evaporation time
109 # If L_evap << L_chamber: complete evaporation (factor → 1)
110 # If L_evap >> L_chamber: incomplete evaporation (factor → 0)
111 # Model: efficiency = exp(-L_evap / L_chamber) for L_evap > L_chamber
112 if evap_ratio <= 1.0:
113 # Complete evaporation within chamber
114 evap_factor = 1.0 - 0.2 * evap_ratio # Slight penalty for longer evaporation
115 else:
116 # Incomplete evaporation
117 # Use exponential decay: efficiency drops as L_evap increases
118 evap_factor = np.exp(-(evap_ratio - 1.0))
119
120 # Droplet size effect: larger droplets = slower evaporation
121 if SMD > 0 and target_smd > 0:
122 smd_penalty = (SMD / target_smd) ** 0.5 # Square root scaling (d^2 law)
123 evap_factor = evap_factor / smd_penalty
124
125 return float(np.clip(evap_factor, 0.1, 1.0))
126
127
129 SMD: float,
130 target_smd: float,
131 Re_injector: float,
132 We_injector: float,
133) -> float:
134 """
135 Calculate SMD factor based on physics.
136
137 Physics:
138 - Smaller droplets → better mixing
139 - Factor based on mixing time: t_mix ~ d^2 / D
140 - Accounts for spray quality from Weber/Reynolds numbers
141
142 Parameters:
143 -----------
144 SMD : float
145 Actual Sauter mean diameter [m]
146 target_smd : float
147 Target SMD [m]
148 Re_injector : float
149 Injector Reynolds number
150 We_injector : float
151 Injector Weber number
152
153 Returns:
154 --------
155 smd_factor : float
156 SMD factor (0-1, higher = better mixing)
157 """
158 if SMD <= 0 or target_smd <= 0:
159 # Estimate from injector conditions
160 # Higher We → better breakup → smaller droplets
161 we_factor = np.clip(We_injector / 15.0, 0.5, 2.0) # Normalize to We=15
162 estimated_factor = 0.5 + 0.3 * np.log10(max(we_factor, 0.1))
163 return float(np.clip(estimated_factor, 0.3, 0.9))
164
165 # Physics: mixing time scales with d^2 (diffusion limited)
166 # Smaller droplets → faster mixing
167 smd_ratio = SMD / target_smd
168
169 # Mixing efficiency: efficiency ~ 1 / (1 + (d/d_target)^2)
170 # This comes from diffusion time scaling: t ~ d^2
171 smd_factor = 1.0 / (1.0 + (smd_ratio - 1.0) ** 2)
172
173 return float(np.clip(smd_factor, 0.1, 1.0))
174
175
177 heat_flux_chamber: float,
178 Pc: float,
179 V_chamber: float,
180 V_throat: float,
181 gamma: float,
182 D_chamber: float,
183 D_throat: float,
184) -> float:
185 """
186 Calculate throat heat flux using Bartz correlation (physics-based).
187
188 Physics:
189 - Bartz correlation: q_throat / q_chamber = f(V, P, D)
190 - Accounts for velocity, pressure, and diameter effects
191 - No arbitrary multipliers
192
193 Parameters:
194 -----------
195 heat_flux_chamber : float
196 Chamber heat flux [W/m²]
197 Pc : float
198 Chamber pressure [Pa]
199 V_chamber : float
200 Chamber velocity [m/s]
201 V_throat : float
202 Throat velocity [m/s] (sonic)
203 gamma : float
204 Specific heat ratio
205 D_chamber : float
206 Chamber diameter [m]
207 D_throat : float
208 Throat diameter [m]
209
210 Returns:
211 --------
212 heat_flux_throat : float
213 Throat heat flux [W/m²]
214 """
215 if V_chamber <= 0 or V_throat <= 0:
216 return heat_flux_chamber * 1.3 # Fallback
217
218 # Bartz correlation for heat flux ratio
219 # q_throat / q_chamber = (V_throat/V_chamber)^0.8 × (P_throat/P_chamber)^0.2 × (D_chamber/D_throat)^0.1
220
221 # Velocity ratio (dominant)
222 velocity_ratio = V_throat / V_chamber
223 velocity_factor = velocity_ratio ** 0.8
224
225 # Pressure ratio (throat is at critical pressure)
226 P_throat = Pc * ((2.0 / (gamma + 1.0)) ** (gamma / (gamma - 1.0)))
227 pressure_ratio = P_throat / Pc
228 pressure_factor = pressure_ratio ** 0.2
229
230 # Diameter ratio (smaller throat = higher heat flux)
231 diameter_ratio = D_chamber / (D_throat + 1e-10)
232 diameter_factor = diameter_ratio ** 0.1
233
234 # Total heat flux ratio
235 heat_flux_ratio = velocity_factor * pressure_factor * diameter_factor
236
237 heat_flux_throat = heat_flux_chamber * heat_flux_ratio
238
239 return float(heat_flux_throat)
240
241
243 Re_throat: float,
244 velocity_ratio: float,
245 D_chamber: float,
246 D_throat: float,
247) -> float:
248 """
249 Calculate turbulence enhancement at throat based on physics.
250
251 Physics:
252 - Turbulence increases near throat due to:
253 1. Higher Reynolds number (sonic conditions)
254 2. Flow acceleration (velocity gradient)
255 3. Geometry change (diameter reduction)
256
257 Parameters:
258 -----------
259 Re_throat : float
260 Throat Reynolds number
261 velocity_ratio : float
262 V_throat / V_chamber
263 D_chamber : float
264 Chamber diameter [m]
265 D_throat : float
266 Throat diameter [m]
267
268 Returns:
269 --------
270 enhancement : float
271 Turbulence enhancement factor
272 """
273 # Reynolds number effect: higher Re → more turbulent
274 Re_factor = np.clip(Re_throat / 1e5, 0.5, 2.0)
275 Re_enhancement = 1.0 + 0.15 * np.log10(max(Re_factor, 0.1))
276
277 # Velocity gradient effect: acceleration → turbulence
278 velocity_enhancement = 1.0 + 0.1 * (velocity_ratio - 1.0)
279
280 # Geometry effect: diameter reduction → flow acceleration → turbulence
281 diameter_ratio = D_chamber / (D_throat + 1e-10)
282 geometry_enhancement = 1.0 + 0.05 * np.log10(max(diameter_ratio, 1.0))
283
284 enhancement = Re_enhancement * velocity_enhancement * geometry_enhancement
285
286 return float(np.clip(enhancement, 1.0, 1.3))
287
288
290 heat_flux_local: float,
291 heat_flux_avg: float,
292 thermal_conductivity: float,
293 backface_temp_limit: float,
294 surface_temp: float,
295) -> float:
296 """
297 Calculate graphite thickness multiplier based on thermal requirements.
298
299 Physics:
300 - Thickness needed to maintain backface temperature
301 - t ~ k × (T_surface - T_backface) / q
302 - Higher heat flux → thicker graphite needed
303
304 Parameters:
305 -----------
306 heat_flux_local : float
307 Local heat flux [W/m²]
308 heat_flux_avg : float
309 Average heat flux [W/m²]
310 thermal_conductivity : float
311 Graphite thermal conductivity [W/(m·K)]
312 backface_temp_limit : float
313 Maximum backface temperature [K]
314 surface_temp : float
315 Surface temperature [K]
316
317 Returns:
318 --------
319 multiplier : float
320 Thickness multiplier (relative to average)
321 """
322 if heat_flux_avg <= 0:
323 return 1.0
324
325 # Required thickness scales with heat flux and temperature difference
326 # t = k × ΔT / q
327 delta_T = surface_temp - backface_temp_limit
328
329 if delta_T <= 0:
330 return 1.0
331
332 # Thickness ratio = heat flux ratio (for same ΔT and k)
333 heat_flux_ratio = heat_flux_local / heat_flux_avg
334
335 # Minimum thickness (mechanical) + thermal thickness
336 # Multiplier = (t_min + t_thermal_local) / (t_min + t_thermal_avg)
337 # For simplicity, assume t_min << t_thermal, so multiplier ≈ heat_flux_ratio
338 # But add bounds for safety
339 multiplier = 0.8 + 0.4 * np.clip(heat_flux_ratio - 0.5, 0.0, 2.0)
340
341 return float(np.clip(multiplier, 0.7, 1.8))
342
#define max(a, b)
Definition Arduino.h:43
float calculate_throat_heat_flux_physics(float heat_flux_chamber, float Pc, float V_chamber, float V_throat, float gamma, float D_chamber, float D_throat)
float calculate_recirculation_length_physics(float D_chamber, float d_pintle_tip, float fuel_velocity, float lox_velocity, float Re_chamber)
float calculate_smd_factor_physics(float SMD, float target_smd, float Re_injector, float We_injector)
float calculate_turbulence_enhancement_physics(float Re_throat, float velocity_ratio, float D_chamber, float D_throat)
float calculate_evaporation_factor_physics(float evaporation_length, float chamber_length, float SMD, float target_smd, float Pc, float Tc)
float calculate_graphite_thickness_multiplier_physics(float heat_flux_local, float heat_flux_avg, float thermal_conductivity, float backface_temp_limit, float surface_temp)