13from typing
import Dict, Tuple, Optional, List
19 config: PintleEngineConfig,
20 chamber_length: float,
21 chamber_diameter: float,
23) -> Dict[str, np.ndarray]:
25 Calculate spatial distribution of fuel impingement zones on chamber wall.
27 For pintle injectors, fuel sprays radially outward and impinges on the
28 chamber wall at specific axial and circumferential locations.
32 config : PintleEngineConfig
34 chamber_length : float
36 chamber_diameter : float
39 Number of axial points to evaluate
43 impingement_data : dict
44 - axial_positions: Array of axial positions [m]
45 - impingement_heat_flux_multiplier: Local heat flux multiplier (1.0 = baseline, >1.0 = enhanced)
46 - impingement_zones: Boolean array indicating impingement zones
47 - spray_angle: Spray angle at each position [rad]
48 - impingement_distance: Distance from injector to wall [m]
50 if not hasattr(config,
'injector')
or config.injector.type !=
"pintle":
52 positions = np.linspace(0, chamber_length, n_points)
54 "axial_positions": positions,
55 "impingement_heat_flux_multiplier": np.ones_like(positions),
56 "impingement_zones": np.zeros_like(positions, dtype=bool),
57 "spray_angle": np.zeros_like(positions),
58 "impingement_distance": np.full_like(positions, np.nan),
61 injector_config: PintleInjectorConfig = config.injector
62 geometry = injector_config.geometry
65 d_pintle_tip = geometry.fuel.d_pintle_tip
66 theta_orifice = geometry.lox.theta_orifice
67 n_orifices = geometry.lox.n_orifices
74 positions = np.linspace(0, chamber_length, n_points)
82 R_chamber = chamber_diameter / 2.0
83 R_pintle = d_pintle_tip / 2.0
88 spray_angle_deg = theta_orifice
89 spray_angle = np.deg2rad(spray_angle_deg)
94 if spray_angle > 0.01:
95 L_impinge = R_chamber / np.tan(spray_angle)
97 L_impinge = chamber_length * 0.1
101 impingement_center =
min(L_impinge, chamber_length * 0.3)
102 impingement_width = chamber_length * 0.1
105 impingement_intensity = np.exp(-0.5 * ((positions - impingement_center) / (impingement_width / 3)) ** 2)
109 base_multiplier = 1.0
111 heat_flux_multiplier = base_multiplier + (max_multiplier - base_multiplier) * impingement_intensity
114 impingement_zones = heat_flux_multiplier > 1.5
118 spray_angles = np.full_like(positions, spray_angle)
120 near_impingement = np.abs(positions - impingement_center) < impingement_width
121 spray_angles[near_impingement] = np.pi / 2.0
124 impingement_distances = np.sqrt((positions - 0) ** 2 + R_chamber ** 2)
127 "axial_positions": positions,
128 "impingement_heat_flux_multiplier": heat_flux_multiplier,
129 "impingement_zones": impingement_zones,
130 "spray_angle": spray_angles,
131 "impingement_distance": impingement_distances,
132 "impingement_center": impingement_center,
133 "impingement_width": impingement_width,
138 base_heat_flux: np.ndarray,
139 impingement_data: Dict[str, np.ndarray],
140 base_recession_rate: np.ndarray,
144 Calculate localized recession rates accounting for fuel impingement.
148 base_heat_flux : np.ndarray
149 Baseline heat flux [W/m²] at each axial position
150 impingement_data : dict
151 Output from calculate_impingement_zones()
152 base_recession_rate : np.ndarray
153 Baseline recession rate [m/s] (without impingement enhancement)
154 ablative_config : AblativeCoolingConfig
155 Ablative configuration
159 localized_recession_rate : np.ndarray
160 Enhanced recession rate [m/s] accounting for impingement
162 multiplier = impingement_data[
"impingement_heat_flux_multiplier"]
165 enhanced_heat_flux = base_heat_flux * multiplier
169 localized_recession_rate = base_recession_rate * multiplier
171 return localized_recession_rate
175 config: PintleEngineConfig,
176 axial_position: float,
177 chamber_length: float,
180 Get heat flux enhancement factor at a specific axial position.
184 config : PintleEngineConfig
186 axial_position : float
187 Axial position along chamber [m]
188 chamber_length : float
193 enhancement_factor : float
194 Heat flux multiplier (1.0 = baseline, >1.0 = enhanced)
197 positions = impingement_data[
"axial_positions"]
198 multipliers = impingement_data[
"impingement_heat_flux_multiplier"]
201 if axial_position <= positions[0]:
202 return multipliers[0]
203 elif axial_position >= positions[-1]:
204 return multipliers[-1]
206 return np.interp(axial_position, positions, multipliers)