STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
engine.pipeline.thermal.graphite_geometry Namespace Reference

Classes

class  GraphiteInsertSizing

Functions

None _validate_inputs (float peak_heat_flux, float burn_time, float throat_diameter, float thermal_conductivity, Optional[float] density=None, Optional[float] specific_heat=None, Optional[Callable] heat_flux_profile=None, Optional[float] allowable_heat_flux_adjacent=None)
None _check_finite (float peak_heat_flux, float surface_temperature, float recession_rate, float burn_time, float thermal_conductivity, float backface_temperature_max, float throat_diameter, Optional[float] density=None, Optional[float] specific_heat=None)
Union[float, np.ndarray] _vectorized_heat_flux_profile (Callable[[np.ndarray], np.ndarray] heat_flux_profile, Union[float, np.ndarray] x)
float calculate_recession_allowance (float recession_rate, float burn_time)
float calculate_conduction_thickness (float thermal_conductivity, float surface_temperature, float backface_temperature_max, float peak_heat_flux)
Tuple[float, bool] calculate_conduction_thickness_transient (float thermal_conductivity, float density, float specific_heat, float surface_heat_flux, float burn_time, float delta_T_backface_max, float eta=2.5)
float calculate_initial_thickness (float recession_allowance, float conduction_thickness, float mechanical_thickness=0.001, float safety_factor=0.3)
Tuple[float, float] calculate_axial_lengths_from_profile (Callable[[np.ndarray], np.ndarray] heat_flux_profile, float allowable_heat_flux_adjacent, float throat_diameter)
Tuple[float, float] calculate_axial_length_simple (float throat_diameter, float length_factor=0.75)
float calculate_thermal_penetration_depth (float thermal_conductivity, float density, float specific_heat, float time)
Dict[str, float] throat_growth_check (float throat_diameter_initial, float recession_allowance)
Dict[str, float] verify_transient_thickness (np.ndarray time, np.ndarray recession_rate, float initial_thickness, float mechanical_thickness=0.001)
GraphiteInsertSizing size_graphite_insert (float peak_heat_flux, float surface_temperature, float recession_rate, float burn_time, float thermal_conductivity, float backface_temperature_max, float throat_diameter, Optional[float] density=None, Optional[float] specific_heat=None, Optional[float] backface_temperature_initial=None, float mechanical_thickness=0.001, float safety_factor=0.3, bool transient=False, float transient_eta=2.5, Optional[Callable[[np.ndarray], np.ndarray]] heat_flux_profile=None, Optional[float] allowable_heat_flux_adjacent=None, float axial_length_factor=0.75)
Dict[str, float] quick_back_of_envelope_sizing (float peak_heat_flux, float surface_temperature, float burn_time, float backface_temperature_max, float thermal_conductivity=1500.0, float recession_rate=6e-5, float mechanical_thickness=0.001, float safety_factor=0.3)

Detailed Description

Graphite throat insert geometry sizing based on physics-based wall model with oxidation heat feedback.

This module implements the sizing methodology from graphite_geometry.tex to determine:
- Radial thickness (recession allowance + conduction + mechanical + safety factor)
- Axial length (based on heat flux profile)
- Transient verification through burn time

The algorithm follows the method described in the LaTeX document for sizing graphite inserts
that keep the back surface within safe temperature limits while providing recession allowance
and mechanical support.

Function Documentation

◆ _check_finite()

None engine.pipeline.thermal.graphite_geometry._check_finite ( float peak_heat_flux,
float surface_temperature,
float recession_rate,
float burn_time,
float thermal_conductivity,
float backface_temperature_max,
float throat_diameter,
Optional[float] density = None,
Optional[float] specific_heat = None )
protected
Check that all inputs are finite (not NaN or Inf).

Definition at line 124 of file graphite_geometry.py.

Referenced by size_graphite_insert().

◆ _validate_inputs()

None engine.pipeline.thermal.graphite_geometry._validate_inputs ( float peak_heat_flux,
float burn_time,
float throat_diameter,
float thermal_conductivity,
Optional[float] density = None,
Optional[float] specific_heat = None,
Optional[Callable] heat_flux_profile = None,
Optional[float] allowable_heat_flux_adjacent = None )
protected
Validate inputs and raise ValueError if invalid.

Definition at line 91 of file graphite_geometry.py.

Referenced by size_graphite_insert().

◆ _vectorized_heat_flux_profile()

Union[float, np.ndarray] engine.pipeline.thermal.graphite_geometry._vectorized_heat_flux_profile ( Callable[[np.ndarray], np.ndarray] heat_flux_profile,
Union[float, np.ndarray] x )
protected
Ensure heat_flux_profile is called with vectorized input.

Parameters:
-----------
heat_flux_profile : callable
    Function that accepts np.ndarray and returns np.ndarray
x : float or np.ndarray
    Axial position(s) [m]

Returns:
--------
q : float or np.ndarray
    Heat flux [W/m²]

Definition at line 155 of file graphite_geometry.py.

Referenced by calculate_axial_lengths_from_profile().

◆ calculate_axial_length_simple()

Tuple[float, float] engine.pipeline.thermal.graphite_geometry.calculate_axial_length_simple ( float throat_diameter,
float length_factor = 0.75 )
Simple rule-of-thumb for axial half-lengths when heat flux profile is not available.

From graphite_geometry.tex:
    L_± = (0.5 to 1.0) × D_t on each side of throat

Many teams converge to a total graphite length of 1.5 to 2.5 × D_t.

Parameters:
-----------
throat_diameter : float
    Throat diameter D_t [m]
length_factor : float
    Factor to multiply D_t (default 0.75, range 0.5-1.0)

Returns:
--------
L_upstream : float
    Axial half-length upstream [m]
L_downstream : float
    Axial half-length downstream [m]

Definition at line 415 of file graphite_geometry.py.

Referenced by size_graphite_insert().

◆ calculate_axial_lengths_from_profile()

Tuple[float, float] engine.pipeline.thermal.graphite_geometry.calculate_axial_lengths_from_profile ( Callable[[np.ndarray], np.ndarray] heat_flux_profile,
float allowable_heat_flux_adjacent,
float throat_diameter )
Calculate axial half-lengths upstream and downstream separately.

The upstream shoulder sees a different q''(x) than downstream. This function
solves for both half-lengths independently.

From section "Axial length" in graphite_geometry.tex:
    q''(|x| = L_±) ≤ q''_allow,adjacent

where x < 0 is upstream and x > 0 is downstream.

Parameters:
-----------
heat_flux_profile : callable
    Function q''(x) that returns heat flux [W/m²] at axial position x [m]
    Must accept np.ndarray and return np.ndarray (vectorized).
    x=0 is at throat, x < 0 is upstream, x > 0 is downstream
allowable_heat_flux_adjacent : float
    Maximum heat flux q''_allow,adjacent [W/m²] that adjacent material can handle
throat_diameter : float
    Throat diameter D_t [m]

Returns:
--------
L_upstream : float
    Axial half-length upstream [m] (negative x direction)
L_downstream : float
    Axial half-length downstream [m] (positive x direction)

Definition at line 351 of file graphite_geometry.py.

References _vectorized_heat_flux_profile().

Referenced by size_graphite_insert().

◆ calculate_conduction_thickness()

float engine.pipeline.thermal.graphite_geometry.calculate_conduction_thickness ( float thermal_conductivity,
float surface_temperature,
float backface_temperature_max,
float peak_heat_flux )
Calculate minimum conduction thickness to keep back face below temperature limit (steady-state).

From equation (eq:tcond) in graphite_geometry.tex:
    t_cond ≥ k × (T_s - T_b,max) / q''_peak

This is a conservative estimate assuming steady-state conduction through
the remaining thickness under peak heat flux.

Parameters:
-----------
thermal_conductivity : float
    Graphite thermal conductivity [W/(m·K)]
surface_temperature : float
    Surface temperature T_s [K] from wall model at design point
backface_temperature_max : float
    Maximum allowable back-face temperature T_b,max [K] for metal substrate or adhesive
peak_heat_flux : float
    Peak convective heat flux at throat q''_peak [W/m²]

Returns:
--------
t_cond : float
    Minimum conduction thickness [m]

Definition at line 208 of file graphite_geometry.py.

References max.

Referenced by size_graphite_insert().

◆ calculate_conduction_thickness_transient()

Tuple[float, bool] engine.pipeline.thermal.graphite_geometry.calculate_conduction_thickness_transient ( float thermal_conductivity,
float density,
float specific_heat,
float surface_heat_flux,
float burn_time,
float delta_T_backface_max,
float eta = 2.5 )
Calculate minimum conduction thickness using transient semi-infinite solid bound.

For short burns, the back face heats by diffusion. This provides a conservative
transient option that often reduces over-thick designs or catches under-thick ones
when q'' spikes.

Diffusion scale:
    t_cond ≥ η * sqrt(α t_b)

Temperature rise check (independent):
    ΔT_back(t) ≈ (2 q'' / k) * sqrt(α t / π)

where η ≈ 2–3 is a safety factor capturing that finite slabs heat faster near backface.

Parameters:
-----------
thermal_conductivity : float
    Thermal conductivity k [W/(m·K)]
density : float
    Material density ρ_s [kg/m³]
specific_heat : float
    Specific heat c_p [J/(kg·K)]
surface_heat_flux : float
    Surface heat flux q'' [W/m²]
burn_time : float
    Burn time t_b [s]
delta_T_backface_max : float
    Maximum allowable back-face temperature rise T_b,max - T_init [K]
eta : float
    Safety factor (default 2.5, range 2-3) for conservatism

Returns:
--------
t_cond : float
    Minimum conduction thickness [m] (diffusion scale)
meets_backface : bool
    True if backface temperature rise is within limit with this thickness

Definition at line 246 of file graphite_geometry.py.

References max.

Referenced by size_graphite_insert().

◆ calculate_initial_thickness()

float engine.pipeline.thermal.graphite_geometry.calculate_initial_thickness ( float recession_allowance,
float conduction_thickness,
float mechanical_thickness = 0.001,
float safety_factor = 0.3 )
Calculate initial radial thickness at throat.

From equation (eq:thickness) in graphite_geometry.tex:
    t_insert,0 = Δ_ablate + t_cond + t_mech + φ_sf

where:
- Δ_ablate: recession allowance from wall model
- t_cond: conduction thickness for back-face temperature control
- t_mech: mechanical lip, fit, and strength requirements
- φ_sf: safety factor (typically 30-50% of (Δ_ablate + t_cond))

Parameters:
-----------
recession_allowance : float
    Recession allowance Δ_ablate [m]
conduction_thickness : float
    Conduction thickness t_cond [m]
mechanical_thickness : float
    Mechanical thickness t_mech [m] for groove, seating, strength
    Typical: 0.5-1.5 mm for small throats, thicker for large bores
safety_factor : float
    Safety factor as fraction (0.3 = 30%, 0.5 = 50%)
    Applied to (Δ_ablate + t_cond) to cover property scatter and profile uncertainty

Returns:
--------
t_insert_0 : float
    Initial radial thickness at throat [m]

Definition at line 309 of file graphite_geometry.py.

References max.

Referenced by size_graphite_insert().

◆ calculate_recession_allowance()

float engine.pipeline.thermal.graphite_geometry.calculate_recession_allowance ( float recession_rate,
float burn_time )
Calculate recession allowance from recession rate and burn time.

From equation (eq:q_to_rdot) in graphite_geometry.tex:
    Δ_ablate = ṙ × t_b

This is the total material that will be removed during the burn.

Parameters:
-----------
recession_rate : float
    Net recession rate [m/s] from wall model output
burn_time : float
    Total burn time [s]

Returns:
--------
delta_ablate : float
    Recession allowance [m]

Definition at line 181 of file graphite_geometry.py.

Referenced by size_graphite_insert().

◆ calculate_thermal_penetration_depth()

float engine.pipeline.thermal.graphite_geometry.calculate_thermal_penetration_depth ( float thermal_conductivity,
float density,
float specific_heat,
float time )
Calculate thermal penetration depth for 1D semi-infinite solid.

From section "Transient conduction and penetration depth" in graphite_geometry.tex:
    δ(t) = √(α × t)
    α = k / (ρ_s × c_p)

This is a conservative bound for thickness estimation. The heat footprint is narrow
and flux decays strongly away from throat, so this over-predicts for real nozzles.
Use it to bound the thickness, not to set it directly.

Parameters:
-----------
thermal_conductivity : float
    Thermal conductivity k [W/(m·K)]
density : float
    Material density ρ_s [kg/m³]
specific_heat : float
    Specific heat c_p [J/(kg·K)]
time : float
    Time t [s]

Returns:
--------
penetration_depth : float
    Thermal penetration depth δ [m]

Definition at line 445 of file graphite_geometry.py.

◆ quick_back_of_envelope_sizing()

Dict[str, float] engine.pipeline.thermal.graphite_geometry.quick_back_of_envelope_sizing ( float peak_heat_flux,
float surface_temperature,
float burn_time,
float backface_temperature_max,
float thermal_conductivity = 1500.0,
float recession_rate = 6e-5,
float mechanical_thickness = 0.001,
float safety_factor = 0.3 )
Quick back-of-envelope sizing using shop-note numbers.

From section "Quick numeric back-of-envelope" in graphite_geometry.tex:
    Δ_ablate ≈ 0.6 mm (for t_b = 10 s, ṙ = 6e-5 m/s)
    t_cond ≈ k × (T_s - T_b,max) / q''_peak
    t_insert,0 ≈ Δ_ablate + t_cond + t_mech + 0.3 × (Δ_ablate + t_cond)

Uses conservative material bounds: k = 1500 W/(m·K)

Parameters:
-----------
peak_heat_flux : float
    Peak heat flux at throat [W/m²]
surface_temperature : float
    Surface temperature [K] (from model or estimate)
burn_time : float
    Burn time [s]
backface_temperature_max : float
    Maximum back-face temperature [K]
thermal_conductivity : float
    Thermal conductivity [W/(m·K)] (default 1500, conservative lower bound)
recession_rate : float
    Recession rate [m/s] (default 6e-5 for LOX/RP-1)
mechanical_thickness : float
    Mechanical thickness [m] (default 1 mm)
safety_factor : float
    Safety factor (default 0.3 = 30%)

Returns:
--------
results : dict
    Dictionary with sizing results

Definition at line 809 of file graphite_geometry.py.

References max.

◆ size_graphite_insert()

GraphiteInsertSizing engine.pipeline.thermal.graphite_geometry.size_graphite_insert ( float peak_heat_flux,
float surface_temperature,
float recession_rate,
float burn_time,
float thermal_conductivity,
float backface_temperature_max,
float throat_diameter,
Optional[float] density = None,
Optional[float] specific_heat = None,
Optional[float] backface_temperature_initial = None,
float mechanical_thickness = 0.001,
float safety_factor = 0.3,
bool transient = False,
float transient_eta = 2.5,
Optional[Callable[[np.ndarray], np.ndarray]] heat_flux_profile = None,
Optional[float] allowable_heat_flux_adjacent = None,
float axial_length_factor = 0.75 )
Size graphite throat insert following the algorithm from graphite_geometry.tex.

This implements the full sizing algorithm (section "Algorithm you can implement"):
1. Compute q''_peak at throat (input)
2. Get T_s, ṙ from wall model (inputs)
3. Set Δ_ablate = ṙ × t_b
4. Compute t_cond from equation (eq:tcond) or transient bound
5. Choose t_insert,0 from equation (eq:thickness)
6. Select L_± based on heat flux profile or simple rule
7. Check throat growth

Parameters:
-----------
peak_heat_flux : float
    Peak convective heat flux at throat q''_peak [W/m²]
surface_temperature : float
    Surface temperature T_s [K] from wall model at design point
recession_rate : float
    Net recession rate ṙ [m/s] from wall model output
burn_time : float
    Total burn time t_b [s]
thermal_conductivity : float
    Graphite thermal conductivity k [W/(m·K)]
backface_temperature_max : float
    Maximum allowable back-face temperature T_b,max [K]
throat_diameter : float
    Throat diameter D_t [m]
density : float, optional
    Material density ρ_s [kg/m³]. Required if transient=True
specific_heat : float, optional
    Specific heat c_p [J/(kg·K)]. Required if transient=True
backface_temperature_initial : float, optional
    Initial back-face temperature T_b,init [K]. If None, assumed 300 K.
    Used for transient calculation: delta_T = T_b,max - T_b,init
mechanical_thickness : float
    Mechanical thickness t_mech [m] (default 1 mm)
safety_factor : float
    Safety factor as fraction (default 0.3 = 30%)
transient : bool
    If True, use transient conduction model (or max of steady and transient)
    If False, use only steady-state model
transient_eta : float
    Safety factor for transient model (default 2.5, range 2-3)
heat_flux_profile : callable, optional
    Function q''(x) for axial heat flux profile. Must accept np.ndarray and return np.ndarray.
    If provided, used to calculate L_± separately for upstream and downstream.
    x=0 is at throat, x < 0 is upstream, x > 0 is downstream
allowable_heat_flux_adjacent : float, optional
    Maximum heat flux for adjacent material [W/m²]. Required if heat_flux_profile provided
axial_length_factor : float
    Factor for simple L_± calculation if profile not available (default 0.75)

Returns:
--------
sizing : GraphiteInsertSizing
    Structured sizing results

Definition at line 589 of file graphite_geometry.py.

References _check_finite(), _validate_inputs(), calculate_axial_length_simple(), calculate_axial_lengths_from_profile(), calculate_conduction_thickness(), calculate_conduction_thickness_transient(), calculate_initial_thickness(), calculate_recession_allowance(), max, and throat_growth_check().

◆ throat_growth_check()

Dict[str, float] engine.pipeline.thermal.graphite_geometry.throat_growth_check ( float throat_diameter_initial,
float recession_allowance )
Check throat growth due to recession and calculate area change.

Recession at the throat increases A_t → lowers q''_peak but also changes performance.
This provides a simple post-check to warn if ΔA_t/A_t > 2-3%.

Parameters:
-----------
throat_diameter_initial : float
    Initial throat diameter D_t,0 [m]
recession_allowance : float
    Recession allowance Δ_ablate [m] (radial loss on each side)

Returns:
--------
results : dict
    Dictionary containing:
    - throat_diameter_end: D_t,end [m]
    - throat_area_initial: A_t,0 [m²]
    - throat_area_end: A_t,end [m²]
    - throat_area_change: ΔA_t [m²]
    - throat_area_change_pct: ΔA_t/A_t,0 [%]

Definition at line 483 of file graphite_geometry.py.

References max.

Referenced by size_graphite_insert().

◆ verify_transient_thickness()

Dict[str, float] engine.pipeline.thermal.graphite_geometry.verify_transient_thickness ( np.ndarray time,
np.ndarray recession_rate,
float initial_thickness,
float mechanical_thickness = 0.001 )
Verify thickness throughout burn by integrating recession rate over time.

Most of the error comes from assuming constant q'' and ṙ. This function allows
you to feed per-time-step wall-model results (q''(t), T_s(t), ṙ(t)) and integrate
consumed thickness.

Parameters:
-----------
time : np.ndarray
    Time array [s]
recession_rate : np.ndarray
    Recession rate ṙ(t) [m/s] from wall model per step
initial_thickness : float
    Initial thickness t_insert,0 [m]
mechanical_thickness : float
    Minimum mechanical thickness [m] to check against

Returns:
--------
results : dict
    Dictionary containing:
    - consumed: Total consumed thickness [m]
    - remaining: Remaining thickness at end [m]
    - min_remaining: Minimum remaining thickness during burn [m]
    - meets_mechanical: bool, whether min_remaining >= mechanical_thickness

Definition at line 528 of file graphite_geometry.py.