1use crate::constants::FRAC_1_SQRT_3;
17use crate::newtypes::{Current, Voltage};
18use crate::pq::Pq;
19use crate::reference_frames::{Abc, AlphaBeta, AlphaBeta0, Dq, Dq0};
20use core::ops::Mul;
21
22impl Mul<Abc<Current>> for Abc<Voltage> {
23 fn mul(self, rhs: Abc<Current>) -> Pq {
24 let p = self.a * rhs.a + self.b * rhs.b + self.c * rhs.c;
25 let q = FRAC_1_SQRT_3
26 * ((self.a - self.b) * rhs.c + (self.b - self.c) * rhs.a + (self.c - self.a) * rhs.b);
27 Pq { p, q }
28 }
29 type Output = Pq;
30}
31impl Mul<Abc<Voltage>> for Abc<Current> {
32 fn mul(self, rhs: Abc<Voltage>) -> Pq {
33 rhs * self
34 }
35 type Output = Pq;
36}
37
38impl Mul<AlphaBeta<Current>> for AlphaBeta<Voltage> {
39 fn mul(self, rhs: AlphaBeta<Current>) -> Pq {
40 let p = 1.5 * (self.alpha * rhs.alpha + self.beta * rhs.beta);
41 let q = 1.5 * (self.beta * rhs.alpha - self.alpha * rhs.beta);
42 Pq { p, q }
43 }
44 type Output = Pq;
45}
46
47impl Mul<AlphaBeta<Voltage>> for AlphaBeta<Current> {
48 fn mul(self, rhs: AlphaBeta<Voltage>) -> Pq {
49 rhs * self
50 }
51 type Output = Pq;
52}
53
54impl Mul<AlphaBeta0<Current>> for AlphaBeta0<Voltage> {
55 fn mul(self, rhs: AlphaBeta0<Current>) -> Pq {
56 let p = 1.5 * (self.alpha * rhs.alpha + self.beta * rhs.beta + 2.0 * self.zero * rhs.zero);
57 let q = 1.5 * (self.beta * rhs.alpha - self.alpha * rhs.beta);
58 Pq { p, q }
59 }
60 type Output = Pq;
61}
62
63impl Mul<AlphaBeta0<Voltage>> for AlphaBeta0<Current> {
64 fn mul(self, rhs: AlphaBeta0<Voltage>) -> Pq {
65 rhs * self
66 }
67 type Output = Pq;
68}
69
70impl Mul<Dq0<Current>> for Dq0<Voltage> {
71 fn mul(self, rhs: Dq0<Current>) -> Pq {
72 let p = 1.5 * (self.d * rhs.d + self.q * rhs.q + 2.0 * self.zero * rhs.zero);
73 let q = 1.5 * (self.q * rhs.d - self.d * rhs.q);
74 Pq { p, q }
75 }
76 type Output = Pq;
77}
78
79impl Mul<Dq0<Voltage>> for Dq0<Current> {
80 fn mul(self, rhs: Dq0<Voltage>) -> Pq {
81 rhs * self
82 }
83 type Output = Pq;
84}
85
86impl Mul<Dq<Current>> for Dq<Voltage> {
87 fn mul(self, rhs: Dq<Current>) -> Pq {
88 let p = 1.5 * (self.d * rhs.d + self.q * rhs.q);
89 let q = 1.5 * (self.q * rhs.d - self.d * rhs.q);
90 Pq { p, q }
91 }
92 type Output = Pq;
93}
94
95impl Mul<Dq<Voltage>> for Dq<Current> {
96 fn mul(self, rhs: Dq<Voltage>) -> Pq {
97 rhs * self
98 }
99 type Output = Pq;
100}
101
102#[cfg(test)]
103mod tests {
104
105 use super::*;
106 use crate::trig::cos_sin;
107 use crate::trig::Theta;
108 use approx::assert_abs_diff_eq;
109
110 fn check_pqs(pq0: Pq, pq1: Pq) {
112 assert_abs_diff_eq!(f32::from(pq0.p), f32::from(pq1.p), epsilon = 0.01,);
113 assert_abs_diff_eq!(f32::from(pq0.q), f32::from(pq1.q), epsilon = 0.01,);
114 }
115
116 #[test]
117 fn multiply() {
118 let v_theta = Theta::from_degrees(20.0);
119 let i_theta = Theta::from_degrees(45.0);
120 let (cos, sin) = cos_sin(v_theta);
121
122 let v_mag = Voltage::from(240.0);
123 let i_mag = Current::from(1.0);
124 let v_zero = Voltage::from(10.0);
125 let i_zero = Current::from(-2.0);
126 let v_abc = Abc::from_polar(v_mag, v_theta) + v_zero;
127 let i_abc = Abc::from_polar(i_mag, i_theta) + i_zero;
128 let pq_abc = v_abc * i_abc;
129
130 let v_alpha_beta0 = AlphaBeta0::from(v_abc);
131 let i_alpha_beta0 = AlphaBeta0::from(i_abc);
132 let pq_alpha_beta0 = v_alpha_beta0 * i_alpha_beta0;
133
134 let v_dq0 = v_abc.to_dq0(cos, sin);
135 let i_dq0 = i_abc.to_dq0(cos, sin);
136 let pq_dq0 = v_dq0 * i_dq0;
137
138 check_pqs(pq_abc, pq_alpha_beta0);
139 check_pqs(pq_abc, pq_dq0);
140 }
141}