STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
film_cooling.py
Go to the documentation of this file.
1"""Film cooling effectiveness model."""
2
3from __future__ import annotations
4
5from typing import Dict
6
7import numpy as np
8
9from engine.pipeline.config_schemas import FilmCoolingConfig
10
11
13 mdot_total: float,
14 mdot_fuel: float,
15 gas_props: Dict[str, float],
16 film_config: FilmCoolingConfig,
17 fuel_props,
18) -> Dict[str, float]:
19 """Compute film cooling effectiveness and adjusted heat-flux factor.
20
21 Parameters
22 ----------
23 mdot_total : float
24 Total propellant mass flow [kg/s].
25 mdot_fuel : float
26 Fuel mass flow [kg/s] (before allocating film fraction).
27 gas_props : dict
28 Dictionary of hot-gas and geometry properties (Tc, rho, velocity, h_hot_base,
29 chamber length, circumference, hot surface area, etc.).
30 film_config : FilmCoolingConfig
31 Film cooling configuration object.
32 fuel_props : FluidConfig
33 Fuel fluid properties (density, cp, temperature).
34
35 Returns
36 -------
37 dict
38 Dictionary containing film effectiveness, remaining coolant flow, and
39 heat-flux reduction factor.
40 """
41 Tc = float(gas_props.get("Tc", 0.0))
42 if not film_config.enabled or mdot_total <= 0 or Tc <= 0:
43 return {
44 "enabled": False,
45 "mass_fraction": 0.0,
46 "mdot_film": 0.0,
47 "mdot_available_for_regen": mdot_fuel,
48 "effectiveness": 0.0,
49 "heat_flux_factor": 1.0,
50 "film_temperature": float(getattr(fuel_props, "temperature", 300.0)),
51 "blowing_ratio": 0.0,
52 "slot_velocity": 0.0,
53 "heat_removed": 0.0,
54 "heat_removed_surface": 0.0,
55 "heat_removed_enthalpy": 0.0,
56 "effective_gas_temperature": Tc,
57 }
58
59 mass_fraction = np.clip(film_config.mass_fraction, 0.0, 0.9)
60 mdot_film = mass_fraction * mdot_fuel
61 mdot_available = max(mdot_fuel - mdot_film, 1e-6)
62
63 fuel_temperature = float(getattr(fuel_props, "temperature", 300.0))
64 injection_temperature = (
65 film_config.injection_temperature
66 if film_config.injection_temperature is not None
67 else fuel_temperature
68 )
69
70 rho_film = float(film_config.density_override or getattr(fuel_props, "density", 800.0))
71 cp_film = float(film_config.cp_override or getattr(fuel_props, "specific_heat", 2000.0))
72
73 rho_g = float(gas_props.get("rho", 1.0))
74 velocity_g = float(gas_props.get("velocity", 1.0))
75 circumference = float(gas_props.get("circumference", 0.0))
76 chamber_length = float(gas_props.get("length", 0.0))
77 hot_area = float(gas_props.get("area", 0.0))
78 h_hot_base = float(gas_props.get("h_hot_base", 0.0))
79
80 slot_height = max(film_config.slot_height, 1e-6)
81 slot_area = max(circumference * slot_height, 1e-8)
82 velocity_film = float(mdot_film / (rho_film * slot_area) if slot_area > 0 else 0.0)
83
84 blowing_ratio = 0.0
85 if rho_g * velocity_g > 0:
86 blowing_ratio = (rho_film * velocity_film) / (rho_g * velocity_g)
87
88 base_effectiveness = film_config.effectiveness_ref
89 if blowing_ratio > 0:
90 base_effectiveness *= (
91 blowing_ratio / max(film_config.reference_blowing_ratio, 1e-6)
92 ) ** film_config.blowing_exponent
93
94 coverage_fraction = np.clip(film_config.apply_to_fraction_of_length, 0.0, 1.0)
95 coverage_length = max(coverage_fraction * chamber_length, 1e-6)
96 decay_length = max(film_config.decay_length, 1e-6)
97
98 effectiveness_avg = base_effectiveness * (decay_length / coverage_length) * (
99 1.0 - np.exp(-coverage_length / decay_length)
100 )
101
102 turbulence_intensity = float(gas_props.get("turbulence_intensity", film_config.turbulence_reference_intensity))
103 turbulence_multiplier = 1.0
104 if turbulence_intensity > 0 and film_config.turbulence_reference_intensity > 0:
105 ratio = (turbulence_intensity / film_config.turbulence_reference_intensity) ** film_config.turbulence_exponent
106 turbulence_multiplier = 1.0 / (1.0 + film_config.turbulence_sensitivity * ratio)
107 turbulence_multiplier = float(np.clip(turbulence_multiplier, film_config.turbulence_min_multiplier, 1.0))
108
109 effectiveness_avg *= turbulence_multiplier
110 effectiveness_avg = float(np.clip(effectiveness_avg, 0.0, 0.95))
111
112 heat_flux_factor = float(np.clip(1.0 - effectiveness_avg, 0.05, 1.0))
113
114 delta_T = max(Tc - injection_temperature, 0.0)
115 enthalpy_removed = mdot_film * cp_film * delta_T
116
117 reference_wall_temp = film_config.reference_wall_temperature
118 heat_flux_nominal = h_hot_base * max(Tc - reference_wall_temp, 0.0)
119 covered_area = hot_area * coverage_fraction
120 heat_removed_surface = effectiveness_avg * heat_flux_nominal * covered_area
121
122 total_heat_removed = enthalpy_removed + heat_removed_surface
123
124 effective_gas_temperature = Tc - effectiveness_avg * (Tc - injection_temperature)
125
126 return {
127 "enabled": True,
128 "mass_fraction": mass_fraction,
129 "mdot_film": mdot_film,
130 "mdot_available_for_regen": mdot_available,
131 "effectiveness": effectiveness_avg,
132 "heat_flux_factor": heat_flux_factor,
133 "film_temperature": injection_temperature,
134 "effective_gas_temperature": effective_gas_temperature,
135 "blowing_ratio": blowing_ratio,
136 "slot_velocity": velocity_film,
137 "heat_removed": float(total_heat_removed),
138 "heat_removed_surface": float(heat_removed_surface),
139 "heat_removed_enthalpy": float(enthalpy_removed),
140 "coverage_length": float(coverage_length),
141 "turbulence_intensity": turbulence_intensity,
142 "turbulence_multiplier": turbulence_multiplier,
143 }
#define max(a, b)
Definition Arduino.h:43
Dict[str, float] compute_film_cooling(float mdot_total, float mdot_fuel, Dict[str, float] gas_props, FilmCoolingConfig film_config, fuel_props)