matching_network_rs/
reactive_component.rs

1
2// use quantiphy_rs::Quantity;
3use dimensioned as dim;
4use std::{f64::consts::PI};
5
6#[derive(PartialEq, Debug)]
7pub enum Component {
8    L(Option<dim::si::Henry<f64>>),
9    C(Option<dim::si::Farad<f64>>),
10    Wire
11}
12
13#[derive(Debug, PartialEq, Clone)]
14pub struct ReactiveComponent {
15    reactance: dim::si::Ohm<f64>,
16    frequency: Option<dim::si::Hertz<f64>>,
17}
18
19impl ReactiveComponent {
20    
21    pub fn new(
22        reactance: dim::si::Ohm<f64>, 
23        frequency: Option<dim::si::Hertz<f64>>
24    ) -> Self {
25        Self {
26            reactance,
27            frequency,
28        }
29    }
30
31    pub fn get_reactance(&self) -> dim::si::Ohm<f64> {
32        self.reactance
33    }
34
35    pub fn get_frequency(&self) -> Option<dim::si::Hertz<f64>> {
36        self.frequency
37    }
38    
39    /// Return equivalent susceptance value [Siemens] i.e. -1/reactance
40    pub fn get_susceptance(&self) -> dim::si::Siemens<f64> {
41        // Return equivalent susceptance value
42        match self._get_component() {
43            Component::L(_) 
44            | Component::C(_) => {
45                -1.0 / self.reactance
46            },
47            Component::Wire => {
48                std::f64::INFINITY * dim::si::SIE
49            },
50        }
51    }
52
53
54    /************ private methods ************/
55
56    /// Given a frequency, resolve inductance [Henry]
57    fn _get_inductance_value(&self) -> Option<dim::si::Henry<f64>> {
58        self.frequency.map(|f| self.reactance / (2.0 * PI * f))
59    }
60    
61    /// Given a frequency, resolve capacitance [Farad]
62    fn _get_capacitance_value(&self) -> Option<dim::si::Farad<f64>> {
63        self.frequency.map(|f| -1.0 / (2.0 * PI * f * self.reactance))
64    }
65
66    fn _get_component(&self) -> Component {
67        match self.get_reactance() {
68            r if r > 0.0 * dim::si::OHM => {
69                Component::L(self._get_inductance_value())
70            },
71            r if r < 0.0 * dim::si::OHM => {
72                Component::C(self._get_capacitance_value())
73            },
74            _ => Component::Wire,
75        }
76    }
77
78    fn _get_component_str(&self) -> &str {
79        match self._get_component() {
80            Component::L(_) => "Inductor",
81            Component::C(_) => "Capacitor",
82            Component::Wire => "Wire", 
83        }
84    }
85
86}
87
88
89impl std::fmt::Display for ReactiveComponent {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91
92        let mut ans;
93    
94        ans = format!(
95            "{}:\n    X = {:.5} Ω ⇔ B = {:.5} S",  
96            self._get_component_str(), 
97            self.get_reactance() / dim::si::OHM,
98            self.get_susceptance() / dim::si::SIE,
99        );
100
101        if let Some(freq) = self.frequency {
102            ans = format!(
103                "{}\n    {} (@ {:.5?} Hz)", 
104                ans, 
105                self._get_component(),
106                freq / dim::si::HZ,
107            );
108        }
109    
110        write!(f, "{}", ans)
111    }
112}
113
114
115
116impl std::fmt::Display for Component {
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        
119        let ans = match *self {
120            Component::L(val) => {
121                match val {
122                    Some(v) => format!("L = {} H", v / dim::si::H),
123                    None => "L".to_string(),
124                }
125            },
126            Component::C(val) => {
127                match val {
128                    Some(v) => format!("C = {} F", v / dim::si::F),
129                    None => "C".to_string(),
130                }
131            },
132            Component::Wire => "".to_string(),
133        };
134
135        write!(f, "{}", ans)
136    }
137}