Skip to main content

sciforge_core/electronics/
components.rs

1use crate::moleculars::Material;
2use sciforge_hub::prelude::physics::electronics::circuits as sf_circuits;
3
4#[derive(Debug, Clone, Copy)]
5pub struct Resistor {
6    pub material: Material,
7    pub length_m: f64,
8    pub area_m2: f64,
9}
10
11impl Resistor {
12    pub fn new(material: Material, length_m: f64, area_m2: f64) -> Self {
13        Self { material, length_m, area_m2 }
14    }
15
16    pub fn resistance_ohm(&self) -> Option<f64> {
17        self.material.resistance_ohm(self.length_m, self.area_m2)
18    }
19
20    pub fn resistance_at_ohm(&self, temperature_k: f64) -> Option<f64> {
21        self.material.resistance_at_ohm(self.length_m, self.area_m2, temperature_k)
22    }
23
24    pub fn voltage_drop_v(&self, current_a: f64) -> Option<f64> {
25        self.resistance_ohm().map(|r| sf_circuits::ohm_voltage(current_a, r))
26    }
27
28    pub fn current_a(&self, voltage_v: f64) -> Option<f64> {
29        self.resistance_ohm().map(|r| sf_circuits::ohm_current(voltage_v, r))
30    }
31
32    pub fn power_w(&self, current_a: f64) -> Option<f64> {
33        let r = self.resistance_ohm()?;
34        Some(sf_circuits::power_dc(sf_circuits::ohm_voltage(current_a, r), current_a))
35    }
36
37    pub fn ac_resistance_ohm(&self, radius_m: f64, frequency_hz: f64) -> Option<f64> {
38        self.material.ac_resistance_ohm(self.length_m, radius_m, frequency_hz)
39    }
40}
41
42pub fn series(resistors: &[Resistor]) -> Option<f64> {
43    let values: Option<Vec<f64>> = resistors.iter().map(|r| r.resistance_ohm()).collect();
44    values.map(|v| sf_circuits::series_resistance(&v))
45}
46
47pub fn parallel(resistors: &[Resistor]) -> Option<f64> {
48    let values: Option<Vec<f64>> = resistors.iter().map(|r| r.resistance_ohm()).collect();
49    values.map(|v| sf_circuits::parallel_resistance(&v))
50}
51
52#[derive(Debug, Clone, Copy)]
53pub struct Capacitor {
54    pub capacitance_f: f64,
55}
56
57impl Capacitor {
58    pub fn new(capacitance_f: f64) -> Self {
59        Self { capacitance_f }
60    }
61
62    pub fn impedance(&self, frequency_hz: f64) -> (f64, f64) {
63        sf_circuits::impedance_capacitor(self.capacitance_f, frequency_hz)
64    }
65
66    pub fn impedance_magnitude_ohm(&self, frequency_hz: f64) -> f64 {
67        let (re, im) = self.impedance(frequency_hz);
68        sf_circuits::impedance_magnitude(re, im)
69    }
70
71    pub fn impedance_phase_rad(&self, frequency_hz: f64) -> f64 {
72        let (re, im) = self.impedance(frequency_hz);
73        sf_circuits::impedance_phase(re, im)
74    }
75
76    pub fn energy_j(&self, voltage_v: f64) -> f64 {
77        sf_circuits::capacitor_energy(self.capacitance_f, voltage_v)
78    }
79
80    pub fn rc_charging_v(&self, supply_v: f64, time_s: f64, resistance_ohm: f64) -> f64 {
81        sf_circuits::rc_charging(supply_v, time_s, resistance_ohm, self.capacitance_f)
82    }
83
84    pub fn rc_discharging_v(&self, initial_v: f64, time_s: f64, resistance_ohm: f64) -> f64 {
85        sf_circuits::rc_discharging(initial_v, time_s, resistance_ohm, self.capacitance_f)
86    }
87
88    pub fn time_constant_s(&self, resistance_ohm: f64) -> f64 {
89        resistance_ohm * self.capacitance_f
90    }
91}
92
93#[derive(Debug, Clone, Copy)]
94pub struct Inductor {
95    pub inductance_h: f64,
96}
97
98impl Inductor {
99    pub fn new(inductance_h: f64) -> Self {
100        Self { inductance_h }
101    }
102
103    pub fn impedance(&self, frequency_hz: f64) -> (f64, f64) {
104        sf_circuits::impedance_inductor(self.inductance_h, frequency_hz)
105    }
106
107    pub fn impedance_magnitude_ohm(&self, frequency_hz: f64) -> f64 {
108        let (re, im) = self.impedance(frequency_hz);
109        sf_circuits::impedance_magnitude(re, im)
110    }
111
112    pub fn energy_j(&self, current_a: f64) -> f64 {
113        sf_circuits::inductor_energy(self.inductance_h, current_a)
114    }
115
116    pub fn current_rise_a(&self, voltage_v: f64, resistance_ohm: f64, time_s: f64) -> f64 {
117        sf_circuits::rl_current_rise(voltage_v, resistance_ohm, self.inductance_h, time_s)
118    }
119
120    pub fn current_decay_a(&self, initial_current_a: f64, resistance_ohm: f64, time_s: f64) -> f64 {
121        sf_circuits::rl_current_decay(initial_current_a, resistance_ohm, self.inductance_h, time_s)
122    }
123
124    pub fn time_constant_s(&self, resistance_ohm: f64) -> f64 {
125        self.inductance_h / resistance_ohm
126    }
127}
128
129#[derive(Debug, Clone, Copy)]
130pub struct RlcCircuit {
131    pub resistance_ohm: f64,
132    pub inductance_h: f64,
133    pub capacitance_f: f64,
134}
135
136impl RlcCircuit {
137    pub fn new(resistance_ohm: f64, inductance_h: f64, capacitance_f: f64) -> Self {
138        Self { resistance_ohm, inductance_h, capacitance_f }
139    }
140
141    pub fn resonant_frequency_hz(&self) -> f64 {
142        sf_circuits::rlc_resonant_frequency(self.inductance_h, self.capacitance_f)
143    }
144
145    pub fn quality_factor(&self) -> f64 {
146        sf_circuits::rlc_quality_factor(self.resistance_ohm, self.inductance_h, self.capacitance_f)
147    }
148
149    pub fn bandwidth_hz(&self) -> f64 {
150        sf_circuits::rlc_bandwidth(self.resonant_frequency_hz(), self.quality_factor())
151    }
152}