1use super::DisplayWithUnit;
2#[cfg(feature = "std")]
3use super::Velocity;
4
5#[must_use]
22#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
23pub struct Energy(pub(crate) f64);
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum EnergyUnit {
28 Joule,
30 KiloJoule,
32 MegaJoule,
34 WattHour,
36 KiloWattHour,
38 ElectronVolt,
40 KiloElectronVolt,
42 MegaElectronVolt,
44 Erg,
46 Btu,
48 Calorie,
50}
51
52impl EnergyUnit {
53 const fn symbol(self) -> &'static str {
54 match self {
55 Self::Joule => "J",
56 Self::KiloJoule => "kJ",
57 Self::MegaJoule => "MJ",
58 Self::WattHour => "Wh",
59 Self::KiloWattHour => "kWh",
60 Self::ElectronVolt => "eV",
61 Self::KiloElectronVolt => "keV",
62 Self::MegaElectronVolt => "MeV",
63 Self::Erg => "erg",
64 Self::Btu => "BTU",
65 Self::Calorie => "cal",
66 }
67 }
68
69 const fn joules_per_unit(self) -> f64 {
70 match self {
71 Self::Joule => 1.0,
72 Self::KiloJoule => 1e3,
73 Self::MegaJoule => 1e6,
74 Self::WattHour => 3_600.0,
75 Self::KiloWattHour => 3.6e6,
76 Self::ElectronVolt => 1.602_176_634e-19,
77 Self::KiloElectronVolt => 1.602_176_634e-16,
78 Self::MegaElectronVolt => 1.602_176_634e-13,
79 Self::Erg => 1e-7,
80 Self::Btu => 1_055.06,
81 Self::Calorie => 4.184,
82 }
83 }
84}
85
86impl Energy {
87 pub const fn from_j(val: f64) -> Self {
89 Self(val)
90 }
91
92 pub const fn from_kj(val: f64) -> Self {
94 Self(val * 1e3)
95 }
96
97 pub const fn from_mj(val: f64) -> Self {
99 Self(val * 1e6)
100 }
101
102 pub const fn from_wh(val: f64) -> Self {
104 Self(val * 3_600.0)
105 }
106
107 pub const fn from_kwh(val: f64) -> Self {
109 Self(val * 3.6e6)
110 }
111
112 pub const fn from_ev(val: f64) -> Self {
114 Self(val * 1.602_176_634e-19)
115 }
116
117 pub const fn from_kev(val: f64) -> Self {
119 Self(val * 1.602_176_634e-16)
120 }
121
122 pub const fn from_mev(val: f64) -> Self {
124 Self(val * 1.602_176_634e-13)
125 }
126
127 pub const fn from_erg(val: f64) -> Self {
129 Self(val * 1e-7)
130 }
131
132 pub const fn from_btu(val: f64) -> Self {
134 Self(val * 1_055.06)
135 }
136
137 pub const fn from_cal(val: f64) -> Self {
139 Self(val * 4.184)
140 }
141
142 pub const fn in_j(self) -> f64 {
144 self.0
145 }
146
147 pub const fn in_kj(self) -> f64 {
149 self.0 / 1e3
150 }
151
152 pub const fn in_mj(self) -> f64 {
154 self.0 / 1e6
155 }
156
157 pub const fn in_wh(self) -> f64 {
159 self.0 / 3_600.0
160 }
161
162 pub const fn in_kwh(self) -> f64 {
164 self.0 / 3.6e6
165 }
166
167 pub const fn in_ev(self) -> f64 {
169 self.0 / 1.602_176_634e-19
170 }
171
172 pub const fn in_kev(self) -> f64 {
174 self.0 / 1.602_176_634e-16
175 }
176
177 pub const fn in_mev(self) -> f64 {
179 self.0 / 1.602_176_634e-13
180 }
181
182 pub const fn in_erg(self) -> f64 {
184 self.0 / 1e-7
185 }
186
187 pub const fn in_btu(self) -> f64 {
189 self.0 / 1_055.06
190 }
191
192 pub const fn in_cal(self) -> f64 {
194 self.0 / 4.184
195 }
196
197 pub fn in_unit(self, unit: EnergyUnit) -> f64 {
199 self.0 / unit.joules_per_unit()
200 }
201
202 pub fn display_as(self, unit: EnergyUnit) -> DisplayWithUnit {
204 DisplayWithUnit {
205 value: self.in_unit(unit),
206 symbol: unit.symbol(),
207 }
208 }
209
210 pub fn abs(self) -> Self {
212 Self(self.0.abs())
213 }
214}
215
216impl_quantity_display!(Energy, "J");
217
218impl_common_ops!(Energy);
219
220#[must_use]
237#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
238pub struct Power(pub(crate) f64);
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq)]
242pub enum PowerUnit {
243 Watt,
245 KiloWatt,
247 MegaWatt,
249 Horsepower,
251}
252
253impl PowerUnit {
254 const fn symbol(self) -> &'static str {
255 match self {
256 Self::Watt => "W",
257 Self::KiloWatt => "kW",
258 Self::MegaWatt => "MW",
259 Self::Horsepower => "hp",
260 }
261 }
262
263 const fn watts_per_unit(self) -> f64 {
264 match self {
265 Self::Watt => 1.0,
266 Self::KiloWatt => 1e3,
267 Self::MegaWatt => 1e6,
268 Self::Horsepower => 745.7,
269 }
270 }
271}
272
273impl Power {
274 pub const fn from_w(val: f64) -> Self {
276 Self(val)
277 }
278
279 pub const fn from_kw(val: f64) -> Self {
281 Self(val * 1e3)
282 }
283
284 pub const fn from_mw(val: f64) -> Self {
286 Self(val * 1e6)
287 }
288
289 pub const fn from_hp(val: f64) -> Self {
291 Self(val * 745.7)
292 }
293
294 pub const fn in_w(self) -> f64 {
296 self.0
297 }
298
299 pub const fn in_kw(self) -> f64 {
301 self.0 / 1e3
302 }
303
304 pub const fn in_mw(self) -> f64 {
306 self.0 / 1e6
307 }
308
309 pub const fn in_hp(self) -> f64 {
311 self.0 / 745.7
312 }
313
314 pub fn in_unit(self, unit: PowerUnit) -> f64 {
316 self.0 / unit.watts_per_unit()
317 }
318
319 pub fn display_as(self, unit: PowerUnit) -> DisplayWithUnit {
321 DisplayWithUnit {
322 value: self.in_unit(unit),
323 symbol: unit.symbol(),
324 }
325 }
326
327 pub fn abs(self) -> Self {
329 Self(self.0.abs())
330 }
331}
332
333impl_quantity_display!(Power, "W");
334
335impl_common_ops!(Power);
336
337#[must_use]
353#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
354pub struct Pressure(pub(crate) f64);
355
356#[derive(Debug, Clone, Copy, PartialEq, Eq)]
358pub enum PressureUnit {
359 Pascal,
361 KiloPascal,
363 MegaPascal,
365 GigaPascal,
367 Bar,
369 MilliBar,
371 Atmosphere,
373 Psi,
375 Torr,
377 MmHg,
379}
380
381impl PressureUnit {
382 const fn symbol(self) -> &'static str {
383 match self {
384 Self::Pascal => "Pa",
385 Self::KiloPascal => "kPa",
386 Self::MegaPascal => "MPa",
387 Self::GigaPascal => "GPa",
388 Self::Bar => "bar",
389 Self::MilliBar => "mbar",
390 Self::Atmosphere => "atm",
391 Self::Psi => "psi",
392 Self::Torr => "torr",
393 Self::MmHg => "mmHg",
394 }
395 }
396
397 const fn pa_per_unit(self) -> f64 {
398 match self {
399 Self::Pascal => 1.0,
400 Self::KiloPascal => 1e3,
401 Self::MegaPascal => 1e6,
402 Self::GigaPascal => 1e9,
403 Self::Bar => 1e5,
404 Self::MilliBar => 100.0,
405 Self::Atmosphere => 101_325.0,
406 Self::Psi => 6_894.757,
407 Self::Torr | Self::MmHg => 133.322,
408 }
409 }
410}
411
412impl Pressure {
413 pub const fn from_pa(val: f64) -> Self {
415 Self(val)
416 }
417
418 pub const fn from_bar(val: f64) -> Self {
420 Self(val * 1e5)
421 }
422
423 pub const fn from_kpa(val: f64) -> Self {
425 Self(val * 1e3)
426 }
427
428 pub const fn from_mpa(val: f64) -> Self {
430 Self(val * 1e6)
431 }
432
433 pub const fn from_gpa(val: f64) -> Self {
435 Self(val * 1e9)
436 }
437
438 pub const fn from_mbar(val: f64) -> Self {
440 Self(val * 100.0)
441 }
442
443 pub const fn from_atm(val: f64) -> Self {
445 Self(val * 101_325.0)
446 }
447
448 pub const fn from_psi(val: f64) -> Self {
450 Self(val * 6_894.757)
451 }
452
453 pub const fn from_torr(val: f64) -> Self {
455 Self(val * 133.322)
456 }
457
458 pub const fn from_mmhg(val: f64) -> Self {
460 Self(val * 133.322)
461 }
462
463 pub const fn in_pa(self) -> f64 {
465 self.0
466 }
467
468 pub const fn in_bar(self) -> f64 {
470 self.0 / 1e5
471 }
472
473 pub const fn in_kpa(self) -> f64 {
475 self.0 / 1e3
476 }
477
478 pub const fn in_mpa(self) -> f64 {
480 self.0 / 1e6
481 }
482
483 pub const fn in_gpa(self) -> f64 {
485 self.0 / 1e9
486 }
487
488 pub const fn in_mbar(self) -> f64 {
490 self.0 / 100.0
491 }
492
493 pub const fn in_atm(self) -> f64 {
495 self.0 / 101_325.0
496 }
497
498 pub const fn in_psi(self) -> f64 {
500 self.0 / 6_894.757
501 }
502
503 pub const fn in_torr(self) -> f64 {
505 self.0 / 133.322
506 }
507
508 pub const fn in_mmhg(self) -> f64 {
510 self.0 / 133.322
511 }
512
513 pub fn in_unit(self, unit: PressureUnit) -> f64 {
515 self.0 / unit.pa_per_unit()
516 }
517
518 pub fn display_as(self, unit: PressureUnit) -> DisplayWithUnit {
520 DisplayWithUnit {
521 value: self.in_unit(unit),
522 symbol: unit.symbol(),
523 }
524 }
525
526 pub fn abs(self) -> Self {
528 Self(self.0.abs())
529 }
530}
531
532impl_quantity_display!(Pressure, "Pa");
533
534impl_common_ops!(Pressure);
535
536#[must_use]
555#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Default)]
556pub struct SpecificEnergy(pub(crate) f64);
557
558#[derive(Debug, Clone, Copy, PartialEq, Eq)]
560pub enum SpecificEnergyUnit {
561 JoulePerKg,
563 KiloJoulePerKg,
565 MegaJoulePerKg,
567 Km2PerS2,
569}
570
571impl SpecificEnergyUnit {
572 const fn symbol(self) -> &'static str {
573 match self {
574 Self::JoulePerKg => "J/kg",
575 Self::KiloJoulePerKg => "kJ/kg",
576 Self::MegaJoulePerKg => "MJ/kg",
577 Self::Km2PerS2 => "km^2/s^2",
578 }
579 }
580
581 const fn jpkg_per_unit(self) -> f64 {
582 match self {
583 Self::JoulePerKg => 1.0,
584 Self::KiloJoulePerKg => 1e3,
585 Self::MegaJoulePerKg | Self::Km2PerS2 => 1e6,
586 }
587 }
588}
589
590impl SpecificEnergy {
591 pub const fn from_j_per_kg(val: f64) -> Self {
593 Self(val)
594 }
595
596 pub const fn from_km2ps2(val: f64) -> Self {
598 Self(val * 1e6)
599 }
600
601 pub const fn from_kj_per_kg(val: f64) -> Self {
603 Self(val * 1e3)
604 }
605
606 pub const fn from_mj_per_kg(val: f64) -> Self {
608 Self(val * 1e6)
609 }
610
611 pub const fn in_j_per_kg(self) -> f64 {
613 self.0
614 }
615
616 pub const fn in_km2ps2(self) -> f64 {
618 self.0 / 1e6
619 }
620
621 pub const fn in_kj_per_kg(self) -> f64 {
623 self.0 / 1e3
624 }
625
626 pub const fn in_mj_per_kg(self) -> f64 {
628 self.0 / 1e6
629 }
630
631 pub fn in_unit(self, unit: SpecificEnergyUnit) -> f64 {
633 self.0 / unit.jpkg_per_unit()
634 }
635
636 pub fn display_as(self, unit: SpecificEnergyUnit) -> DisplayWithUnit {
638 DisplayWithUnit {
639 value: self.in_unit(unit),
640 symbol: unit.symbol(),
641 }
642 }
643
644 pub fn abs(self) -> Self {
646 Self(self.0.abs())
647 }
648
649 #[cfg(feature = "std")]
651 pub fn sqrt(self) -> Velocity {
652 Velocity(self.0.sqrt())
653 }
654}
655
656impl_quantity_display!(SpecificEnergy, "J/kg");
657
658impl_common_ops!(SpecificEnergy);