STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
test_injector_dp_ratio_penalty.py
Go to the documentation of this file.
1"""Piecewise injector ΔP/Pc hinge penalty for Layer 1 (per-stream bands)."""
2
3import unittest
4
6 injector_dp_bands_from_requirements,
7 injector_dp_ratio_penalty_weighted,
8 injector_dp_ratios_from_eval_result,
9 injector_dp_ratio_within_gate,
10 stream_injector_dp_band_hinge_squared,
11 stream_injector_dp_raw_terms,
12 stream_injector_dp_soft_floor_squared,
13)
14
15
16class TestInjectorDpRatioPenalty(unittest.TestCase):
18 """Doubling W_DP doubles weighted penalty for identical ratios."""
19 band_o = band_f = (0.20, 0.35)
20 r_o, r_f = 0.88, 1.62
21 p_lo = injector_dp_ratio_penalty_weighted(
22 r_o, r_f, 40.0, 120.0, o_band=band_o, f_band=band_f
23 )
24 p_hi = injector_dp_ratio_penalty_weighted(
25 r_o, r_f, 80.0, 240.0, o_band=band_o, f_band=band_f
26 )
27 self.assertAlmostEqual(p_hi, 2.0 * p_lo, places=9)
28
30 """Defaults: O and F preferred intervals yield zero penalty."""
31 p = injector_dp_ratio_penalty_weighted(0.25, 0.85, 1.0, 1.0)
32 self.assertAlmostEqual(p, 0.0, places=12)
33
35 for r in (0.20, 0.27, 0.35):
36 self.assertAlmostEqual(stream_injector_dp_band_hinge_squared(r, 0.20, 0.35), 0.0, places=12)
37
39 """Fuel at 0.85 is penalized under narrow fuel band but not under default wide fuel band."""
40 narrow_all = (0.20, 0.35)
41 p_narrow = injector_dp_ratio_penalty_weighted(
42 0.25, 0.85, 1.0, 0.0, o_band=narrow_all, f_band=narrow_all
43 )
44 p_default = injector_dp_ratio_penalty_weighted(0.25, 0.85, 1.0, 0.0)
45 self.assertGreater(p_narrow, 0.0)
46 self.assertAlmostEqual(p_default, 0.0, places=12)
47
49 self.assertGreater(stream_injector_dp_band_hinge_squared(0.10, 0.20, 0.35), 0.0)
50
52 self.assertAlmostEqual(stream_injector_dp_soft_floor_squared(0.02, 0.15), (0.15 - 0.02) ** 2)
53 self.assertAlmostEqual(stream_injector_dp_soft_floor_squared(0.40, 0.15), 0.0, places=12)
54 band = (0.20, 0.37)
55 p_base = injector_dp_ratio_penalty_weighted(
56 0.014, 0.45, 100.0, 0.0, o_band=band, f_band=band, w_dp_o=100.0, w_dp_f=100.0
57 )
58 p_floor = injector_dp_ratio_penalty_weighted(
59 0.014,
60 0.45,
61 100.0,
62 0.0,
63 o_band=band,
64 f_band=band,
65 w_dp_o=100.0,
66 w_dp_f=100.0,
67 o_soft_floor=0.15,
68 w_dp_o_floor=1000.0,
69 )
70 self.assertGreater(p_floor, p_base)
71
73 """w_dp_o and w_dp_f scale hinges independently."""
74 p_sym = injector_dp_ratio_penalty_weighted(
75 0.50,
76 0.85,
77 100.0,
78 0.0,
79 w_dp_o=100.0,
80 w_dp_f=100.0,
81 )
82 p_asym = injector_dp_ratio_penalty_weighted(
83 0.50,
84 0.85,
85 100.0,
86 0.0,
87 w_dp_o=300.0,
88 w_dp_f=100.0,
89 )
90 # Higher oxidizer weight triples oxidizer hinge contribution only (fuel hinge zero inside band).
91 self.assertAlmostEqual(p_asym, 3.0 * p_sym, places=9)
92
94 band = (0.20, 0.35)
95 p_o = injector_dp_ratio_penalty_weighted(
96 0.10, 0.27, 1.0, 0.0, o_band=band, f_band=band
97 )
98 p_f = injector_dp_ratio_penalty_weighted(
99 0.27, 0.10, 1.0, 0.0, o_band=band, f_band=band
100 )
101 self.assertAlmostEqual(p_o, p_f, places=12)
102
104 d, h = stream_injector_dp_raw_terms(0.40)
105 span = 0.35 - 0.20
106 expected = ((0.40 - 0.35) / span) ** 2
107 self.assertAlmostEqual(d, expected, places=12)
108 self.assertAlmostEqual(h, 0.0, places=12)
109
111 pc = 2e6
112 res = {
113 "diagnostics": {"delta_p_injector_O": 0.5e6, "delta_p_injector_F": 0.7e6},
114 }
115 ro, rf = injector_dp_ratios_from_eval_result(pc, res)
116 self.assertAlmostEqual(ro, 0.25)
117 self.assertAlmostEqual(rf, 0.35)
118
120 pc = 1e6
121 res = {
122 "diagnostics": {"P_injector_O": 1.4e6, "P_injector_F": 1.35e6},
123 }
124 ro, rf = injector_dp_ratios_from_eval_result(pc, res)
125 self.assertAlmostEqual(ro, 0.4)
126 self.assertAlmostEqual(rf, 0.35)
127
129 reqs = {
130 "injector_dp_ratio_O_min": 0.15,
131 "injector_dp_ratio_O_max": 0.35,
132 "injector_dp_ratio_F_min": 0.15,
133 "injector_dp_ratio_F_max": 0.35,
134 }
135 o_band, f_band = injector_dp_bands_from_requirements(reqs)
136 self.assertEqual(o_band, (0.20, 0.40))
137 self.assertEqual(f_band, (0.20, 0.40))
138 self.assertTrue(injector_dp_ratio_within_gate(0.352, *o_band))
139 self.assertTrue(injector_dp_ratio_within_gate(0.342, *f_band))
140
142 """Closure noise can yield ΔP/Pc ≡ hi plus float dust; hinge is ~zero but plain ``<= hi`` can fail."""
143 lo, hi = 0.15, 0.35
144 self.assertTrue(injector_dp_ratio_within_gate(0.35, lo, hi))
145 creep = hi + 3.0e-5
146 self.assertTrue(injector_dp_ratio_within_gate(creep, lo, hi))
147 far = hi + 0.02
148 self.assertFalse(injector_dp_ratio_within_gate(far, lo, hi))
149 self.assertIsNone(injector_dp_ratio_within_gate(None, lo, hi))
150
151
152if __name__ == "__main__":
153 unittest.main()