space_units/quantities/
propulsion.rs1use super::mechanics::G0_MPS2;
2use super::mechanics::KG_PER_POUND;
3use super::DisplayWithUnit;
4use super::Velocity;
5
6#[must_use]
21#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
22pub struct SpecificImpulse(pub(crate) f64);
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
26pub enum SpecificImpulseUnit {
27 Second,
29 NewtonSecondPerKg,
31}
32
33impl SpecificImpulseUnit {
34 const fn symbol(self) -> &'static str {
35 match self {
36 Self::Second => "s",
37 Self::NewtonSecondPerKg => "N*s/kg",
38 }
39 }
40}
41
42impl SpecificImpulse {
43 pub const fn from_s(val: f64) -> Self {
45 Self(val)
46 }
47
48 pub const fn from_n_s_per_kg(val: f64) -> Self {
50 Self(val / G0_MPS2)
51 }
52
53 pub const fn in_s(self) -> f64 {
55 self.0
56 }
57
58 pub const fn in_n_s_per_kg(self) -> f64 {
60 self.0 * G0_MPS2
61 }
62
63 pub const fn effective_exhaust_velocity(self) -> Velocity {
65 Velocity::from_mps(self.0 * G0_MPS2)
66 }
67
68 pub const fn display_as(self, unit: SpecificImpulseUnit) -> DisplayWithUnit {
70 match unit {
71 SpecificImpulseUnit::Second => DisplayWithUnit {
72 value: self.0,
73 symbol: unit.symbol(),
74 },
75 SpecificImpulseUnit::NewtonSecondPerKg => DisplayWithUnit {
76 value: self.in_n_s_per_kg(),
77 symbol: unit.symbol(),
78 },
79 }
80 }
81
82 pub fn abs(self) -> Self {
84 Self(self.0.abs())
85 }
86}
87
88impl_quantity_display!(SpecificImpulse, "s");
89
90impl_common_ops!(SpecificImpulse);
91
92#[must_use]
107#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
108pub struct MassFlowRate(pub(crate) f64);
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub enum MassFlowRateUnit {
113 KgPerS,
115 GramPerS,
117 PoundPerS,
119 KgPerH,
121}
122
123impl MassFlowRateUnit {
124 const fn symbol(self) -> &'static str {
125 match self {
126 Self::KgPerS => "kg/s",
127 Self::GramPerS => "g/s",
128 Self::PoundPerS => "lb/s",
129 Self::KgPerH => "kg/h",
130 }
131 }
132
133 const fn kgps_per_unit(self) -> f64 {
134 match self {
135 Self::KgPerS => 1.0,
136 Self::GramPerS => 1e-3,
137 Self::PoundPerS => KG_PER_POUND,
138 Self::KgPerH => 1.0 / 3_600.0,
139 }
140 }
141}
142
143impl MassFlowRate {
144 pub const fn from_kgps(val: f64) -> Self {
146 Self(val)
147 }
148
149 pub const fn from_gps(val: f64) -> Self {
151 Self(val * 1e-3)
152 }
153
154 pub const fn from_lbps(val: f64) -> Self {
156 Self(val * KG_PER_POUND)
157 }
158
159 pub const fn from_kgph(val: f64) -> Self {
161 Self(val / 3_600.0)
162 }
163
164 pub const fn in_kgps(self) -> f64 {
166 self.0
167 }
168
169 pub const fn in_gps(self) -> f64 {
171 self.0 / 1e-3
172 }
173
174 pub const fn in_lbps(self) -> f64 {
176 self.0 / KG_PER_POUND
177 }
178
179 pub const fn in_kgph(self) -> f64 {
181 self.0 * 3_600.0
182 }
183
184 pub fn in_unit(self, unit: MassFlowRateUnit) -> f64 {
186 self.0 / unit.kgps_per_unit()
187 }
188
189 pub fn display_as(self, unit: MassFlowRateUnit) -> DisplayWithUnit {
191 DisplayWithUnit {
192 value: self.in_unit(unit),
193 symbol: unit.symbol(),
194 }
195 }
196
197 pub fn abs(self) -> Self {
199 Self(self.0.abs())
200 }
201}
202
203impl_quantity_display!(MassFlowRate, "kg/s");
204
205impl_common_ops!(MassFlowRate);