matching_network_rs/
matching_network.rs

1use num::complex::Complex;
2use dimensioned as dim;
3use dim::si::*;
4
5use dim::Sqrt;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
8enum MatchingNetworkConfig {
9    ShuntSeries,
10    SeriesShunt,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq)]
14pub struct Solution {
15    sol_type: MatchingNetworkConfig,
16    shunt_elem: Ohm<f64>,
17    series_elem: Ohm<f64>,
18}
19
20
21#[derive(Debug, Clone)]
22pub struct MatchingNetwork {
23    z1: Complex<Ohm<f64>>,
24    z2: Complex<Ohm<f64>>,
25    solutions: Vec<Solution>,
26}
27
28
29impl MatchingNetwork {
30    pub fn new(
31        z1: Complex<Ohm<f64>>,
32        z2: Complex<Ohm<f64>>,
33    ) -> MatchingNetwork {
34        MatchingNetwork {
35            z1,
36            z2,
37            solutions: vec![],
38        }
39    }
40
41    pub fn get_solutions(&self) -> Vec<Solution> {
42        self.solutions.clone()
43    }
44
45    pub fn eval_at(&self, freq: dim::si::Hertz<f64>) -> Vec<f64> {
46        todo!()
47    }
48
49    pub fn solve(&mut self) -> Vec<Solution> {
50
51        let mut solutions = vec![];
52        
53        let (r1, x1) = (self.z1.re, self.z1.im);
54        let (r2, x2) = (self.z2.re, self.z2.im);
55
56        if r1*(r1 - r2) + (x1*x1) >= 0.0 * dim::si::OHM * dim::si::OHM {
57            // shunt - series configuration (down coversion)
58            
59            let x_shu_1 = (r1*x2 + r2*x1 - r1*(x2 - ((r2*(r1*r1 - r2*r1 + x1*x1))/r1).sqrt()))/(r1 - r2);
60            let x_shu_2 = (r1*x2 + r2*x1 - r1*(x2 + ((r2*(r1*r1 - r2*r1 + x1*x1))/r1).sqrt()))/(r1 - r2);
61
62            let x_ser_1 = x2 - ((r2*(r1*r1 - r2*r1 + x1*x1))/r1).sqrt();
63            let x_ser_2 = x2 + ((r2*(r1*r1 - r2*r1 + x1*x1))/r1).sqrt();
64            
65            let sol1 = Solution {
66                sol_type: MatchingNetworkConfig::ShuntSeries,
67                shunt_elem: x_shu_1,
68                series_elem: x_ser_1,
69            };
70
71            let sol2 = Solution {
72                sol_type: MatchingNetworkConfig::ShuntSeries,
73                shunt_elem: x_shu_2,
74                series_elem: x_ser_2,
75            };
76
77            solutions.push(sol1);
78            if sol1 != sol2 {
79                solutions.push(sol2);
80            }
81        }
82
83
84        if r2*(r2 - r1) + x2*x2 >= 0.0 * dim::si::OHM * dim::si::OHM {
85            // series - shunt configuration (up coversion)
86
87            let x_shu_1 =  (r1*x2 + (r1*r2*(r2*r2 - r1*r2 + x2*x2)).sqrt())/(r1 - r2);
88            let x_shu_2 =  (r1*x2 - (r1*r2*(r2*r2 - r1*r2 + x2*x2)).sqrt())/(r1 - r2);
89            
90            let x_ser_1 = -(r2*x1 - (r1*r2*(r2*r2 - r1*r2 + x2*x2)).sqrt())/r2;
91            let x_ser_2 = -(r2*x1 + (r1*r2*(r2*r2 - r1*r2 + x2*x2)).sqrt())/r2;
92
93            let sol1 = Solution {
94                sol_type: MatchingNetworkConfig::SeriesShunt,
95                shunt_elem: x_shu_1,
96                series_elem: x_ser_1,
97            };
98
99            let sol2 = Solution {
100                sol_type: MatchingNetworkConfig::SeriesShunt,
101                shunt_elem: x_shu_2,
102                series_elem: x_ser_2,
103            };
104
105        
106            solutions.push(sol1);
107            if sol1 != sol2 {
108                solutions.push(sol2);
109            }
110        }
111        
112        solutions
113    }
114}
115
116
117impl std::fmt::Display for MatchingNetwork {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119
120        let mut ans;
121
122        let z1_without_uom = Complex::new(
123            self.z1.re.value_unsafe,
124            self.z1.im.value_unsafe,
125        );
126        let z2_without_uom = Complex::new(
127            self.z2.re.value_unsafe,
128            self.z2.im.value_unsafe,
129        );
130
131        ans = format!(
132            "{} Ω ==> {} Ω",
133            z1_without_uom, // / dim::si::OHM, 
134            z2_without_uom, // / dim::si::OHM,
135        );
136
137        // if let Some(freq) = self.frequency {
138        //     ans = format!(
139        //         "{}\n    {} (@ {:.5?} Hz)", 
140        //         ans, 
141        //         self._get_component(),
142        //         freq / dim::si::HZ,
143        //     );
144        // }
145    
146        write!(f, "{}", ans)
147    }
148}