Skip to main content

rill_core_wdf/macros/
compose.rs

1/// Compose two WDF elements into Series or Parallel.
2#[macro_export]
3macro_rules! wdf_compose {
4    (
5        name: $name:ident<T>,
6        kind: Series,
7        elements: ($left:ty, $right:ty),
8    ) => {
9        #[derive(Debug, Clone, Copy)]
10        pub struct $name<T: $crate::Transcendental> {
11            pub left: $left,
12            pub right: $right,
13        }
14
15        impl<T: $crate::Transcendental> $name<T> {
16            pub fn new(left: $left, right: $right) -> Self {
17                Self { left, right }
18            }
19        }
20
21        impl<T: $crate::Transcendental> $crate::WdfElement<T> for $name<T> {
22            fn port_resistance(&self) -> T {
23                self.left.port_resistance() + self.right.port_resistance()
24            }
25            fn process_incident(&mut self, a: T) -> T {
26                let r1 = self.left.port_resistance();
27                let r2 = self.right.port_resistance();
28                let total = r1 + r2;
29                let a1 = a * (r1 / total);
30                let a2 = a * (r2 / total);
31                let b1 = self.left.process_incident(a1);
32                let b2 = self.right.process_incident(a2);
33                b1 * (r1 / total) + b2 * (r2 / total)
34            }
35            fn update_state(&mut self) {
36                self.left.update_state();
37                self.right.update_state();
38            }
39            fn voltage(&self) -> T {
40                self.left.voltage() + self.right.voltage()
41            }
42            fn current(&self) -> T { self.left.current() }
43            fn reset(&mut self) {
44                self.left.reset();
45                self.right.reset();
46            }
47        }
48    };
49    (
50        name: $name:ident<T>,
51        kind: Parallel,
52        elements: ($left:ty, $right:ty),
53    ) => {
54        #[derive(Debug, Clone, Copy)]
55        pub struct $name<T: $crate::Transcendental> {
56            pub left: $left,
57            pub right: $right,
58        }
59
60        impl<T: $crate::Transcendental> $name<T> {
61            pub fn new(left: $left, right: $right) -> Self {
62                Self { left, right }
63            }
64        }
65
66        impl<T: $crate::Transcendental> $crate::WdfElement<T> for $name<T> {
67            fn port_resistance(&self) -> T {
68                let r1 = self.left.port_resistance();
69                let r2 = self.right.port_resistance();
70                (r1 * r2) / (r1 + r2)
71            }
72            fn process_incident(&mut self, a: T) -> T {
73                let r1 = self.left.port_resistance();
74                let r2 = self.right.port_resistance();
75                let g1 = T::ONE / r1;
76                let g2 = T::ONE / r2;
77                let total_g = g1 + g2;
78                let two = T::from_f32(2.0);
79                let a1 = two * g1 / total_g;
80                let a2 = two * g2 / total_g;
81                let b1 = self.left.process_incident(a);
82                let b2 = self.right.process_incident(a);
83                a1 * b1 + a2 * b2 - a
84            }
85            fn update_state(&mut self) {
86                self.left.update_state();
87                self.right.update_state();
88            }
89            fn voltage(&self) -> T { self.left.voltage() }
90            fn current(&self) -> T {
91                self.left.current() + self.right.current()
92            }
93            fn reset(&mut self) {
94                self.left.reset();
95                self.right.reset();
96            }
97        }
98    };
99}