STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
copv_calculator.py
Go to the documentation of this file.
1"""Helper to calculate COPV consumption coefficients from physical parameters.
2
3For a COPV system:
4- Volume: V_copv [m³]
5- Initial pressure: P_copv_0 [Pa]
6- Regulated pressure: P_reg [Pa]
7- Gas: GN2 (gaseous nitrogen)
8- Flow characteristics: depends on regulator and valve sizing
9"""
10
11from __future__ import annotations
12
13from typing import Optional
14import numpy as np
15
16# Constants
17PSI_TO_PA = 6894.76
18R_N2 = 296.8 # Gas constant for N2 [J/(kg·K)]
19T_N2 = 293.0 # Typical N2 temperature [K]
20
21
23 V_copv_L: float,
24 P_copv_psi: float,
25 P_reg_psi: float,
26 max_flow_rate_kg_s: Optional[float] = None,
27 burn_time_s: Optional[float] = None,
28) -> dict:
29 """
30 Estimate COPV consumption coefficients from physical parameters.
31
32 Parameters:
33 -----------
34 V_copv_L : float
35 COPV volume [L]
36 P_copv_psi : float
37 Initial COPV pressure [psi]
38 P_reg_psi : float
39 Regulated pressure [psi]
40 max_flow_rate_kg_s : float, optional
41 Maximum expected flow rate from COPV [kg/s]
42 If None, estimated from typical values
43 burn_time_s : float, optional
44 Expected burn time [s]
45 If None, estimated from pressure drop
46
47 Returns:
48 --------
49 params : dict
50 Dictionary with estimated coefficients:
51 - copv_cF: [Pa/s per unit u_F]
52 - copv_cO: [Pa/s per unit u_O]
53 - copv_loss: [Pa/s]
54 - reg_ratio: P_reg / P_copv
55 """
56 V_copv_m3 = V_copv_L / 1000.0
57 P_copv_Pa = P_copv_psi * PSI_TO_PA
58 P_reg_Pa = P_reg_psi * PSI_TO_PA
59
60 # Calculate regulator ratio
61 reg_ratio = P_reg_Pa / P_copv_Pa
62
63 # Estimate mass flow rate if not provided
64 # For a regulator, flow is approximately: mdot = Cd * A * sqrt(2*rho*deltaP)
65 # Simplified: assume typical flow for pressure regulation
66 if max_flow_rate_kg_s is None:
67 # Estimate from typical regulator sizing
68 # For 1000 psi regulated from 2750 psi, typical flow ~0.1-0.5 kg/s
69 # This is a rough estimate - should be measured or calculated from regulator specs
70 delta_P = P_copv_Pa - P_reg_Pa
71 # Rough estimate: mdot ~ 0.001 * sqrt(delta_P) for typical regulator
72 max_flow_rate_kg_s = 0.001 * np.sqrt(delta_P)
73
74 # Estimate pressure drop rate
75 # Using ideal gas law: P = (m*R*T)/V
76 # dP/dt = (R*T/V) * (dm/dt)
77 # For blowdown: dm/dt is negative (mass leaving)
78
79 # Mass in COPV initially
80 m0 = (P_copv_Pa * V_copv_m3) / (R_N2 * T_N2)
81
82 # Pressure drop rate when flow is maximum
83 # dP/dt = -(R*T/V) * mdot
84 dP_dt_max = -(R_N2 * T_N2 / V_copv_m3) * max_flow_rate_kg_s
85
86 # Convert to consumption coefficient
87 # Model: dP_copv/dt = -cF*u_F - cO*u_O - loss
88 # When u=1.0, dP/dt = -cF (or -cO)
89 # So cF = -dP_dt_max (positive value)
90 copv_c = abs(dP_dt_max)
91
92 # Split between fuel and oxidizer (assume equal for now)
93 copv_cF = copv_c / 2.0
94 copv_cO = copv_c / 2.0
95
96 # Leakage/heat loss (small, ~0.1% of max consumption)
97 copv_loss = copv_c * 0.001
98
99 return {
100 "copv_cF": float(copv_cF),
101 "copv_cO": float(copv_cO),
102 "copv_loss": float(copv_loss),
103 "reg_ratio": float(reg_ratio),
104 "estimated_max_flow_kg_s": float(max_flow_rate_kg_s),
105 "estimated_dP_dt_max_Pa_s": float(abs(dP_dt_max)),
106 }
107
108
110 V_copv_L: float,
111 P_copv_psi: float,
112 P_reg_psi: float,
113 regulator_Cv: Optional[float] = None,
114 valve_Cv_F: Optional[float] = None,
115 valve_Cv_O: Optional[float] = None,
116) -> dict:
117 """
118 Calculate COPV coefficients from regulator and valve Cv values.
119
120 Parameters:
121 -----------
122 V_copv_L : float
123 COPV volume [L]
124 P_copv_psi : float
125 Initial COPV pressure [psi]
126 P_reg_psi : float
127 Regulated pressure [psi]
128 regulator_Cv : float, optional
129 Regulator flow coefficient Cv
130 valve_Cv_F : float, optional
131 Fuel valve flow coefficient Cv
132 valve_Cv_O : float, optional
133 Oxidizer valve flow coefficient Cv
134
135 Returns:
136 --------
137 params : dict
138 Dictionary with calculated coefficients
139 """
140 V_copv_m3 = V_copv_L / 1000.0
141 P_copv_Pa = P_copv_psi * PSI_TO_PA
142 P_reg_Pa = P_reg_psi * PSI_TO_PA
143
144 # Flow through valve: Q = Cv * sqrt(deltaP / SG)
145 # For gas: mdot = Cv * 0.048 * sqrt(deltaP * rho)
146 # Simplified model
147
148 if regulator_Cv is None:
149 # Default: assume regulator can handle flow
150 regulator_Cv = 1.0
151
152 if valve_Cv_F is None:
153 valve_Cv_F = 0.5 # Typical small solenoid valve
154
155 if valve_Cv_O is None:
156 valve_Cv_O = 0.5
157
158 # Calculate flow rates (simplified)
159 # mdot = Cv * K * sqrt(P_upstream - P_downstream) * rho
160 # For N2 at regulator conditions
161 rho_N2_reg = P_reg_Pa / (R_N2 * T_N2) # Density at regulator pressure
162
163 # Flow through fuel valve
164 delta_P_F = P_reg_Pa - 3e6 # Assume 3 MPa tank pressure
165 mdot_F_max = valve_Cv_F * 0.01 * np.sqrt(max(delta_P_F, 0)) * rho_N2_reg
166
167 # Flow through oxidizer valve
168 delta_P_O = P_reg_Pa - 3.5e6 # Assume 3.5 MPa tank pressure
169 mdot_O_max = valve_Cv_O * 0.01 * np.sqrt(max(delta_P_O, 0)) * rho_N2_reg
170
171 # Pressure drop rates
172 dP_dt_F = -(R_N2 * T_N2 / V_copv_m3) * mdot_F_max
173 dP_dt_O = -(R_N2 * T_N2 / V_copv_m3) * mdot_O_max
174
175 copv_cF = abs(dP_dt_F)
176 copv_cO = abs(dP_dt_O)
177 copv_loss = (copv_cF + copv_cO) * 0.001
178
179 reg_ratio = P_reg_Pa / P_copv_Pa
180
181 return {
182 "copv_cF": float(copv_cF),
183 "copv_cO": float(copv_cO),
184 "copv_loss": float(copv_loss),
185 "reg_ratio": float(reg_ratio),
186 "mdot_F_max_kg_s": float(mdot_F_max),
187 "mdot_O_max_kg_s": float(mdot_O_max),
188 }
189
190
191
#define max(a, b)
Definition Arduino.h:43
dict calculate_from_regulator_specs(float V_copv_L, float P_copv_psi, float P_reg_psi, Optional[float] regulator_Cv=None, Optional[float] valve_Cv_F=None, Optional[float] valve_Cv_O=None)
dict estimate_copv_coefficients(float V_copv_L, float P_copv_psi, float P_reg_psi, Optional[float] max_flow_rate_kg_s=None, Optional[float] burn_time_s=None)