stem_wire/resistance.rs
1/*!
2Provides analytical formulas for computing the electrical resistance of
3homogeneous conductors with idealized geometries, including rectangular
4prisms (cuboids), cylindrical segments (axial, radial, and tangential),
5and hollow spheres.
6
7All functions assume:
8
9- Steady-state conduction (no displacement current),
10- Homogeneous and isotropic material properties,
11- Idealized geometric shapes,
12- Current distributions consistent with the analytical solutions.
13
14The parameter `fraction`, where present, represents the geometric fraction
15of the full body (e.g. `1.0` = full geometry, `0.5` = half).
16
17These utilities are primarily intended for use in
18[`Wire::resistance`](crate::wire::Wire::resistance).
19*/
20
21use std::f64::consts::PI;
22use std::f64::consts::TAU;
23use stem_material::uom::si::f64::*;
24
25/**
26Calculates the electrical resistance of a homogeneous conductor
27with uniform cross-sectional area.
28
29Implemented relation:
30
31`R = L / (σ · A)`
32
33where:
34
35- `L` is the conductor length,
36- `A` is the cross-sectional area,
37- `σ` is the electrical conductivity.
38
39Division by zero (e.g. zero area or conductivity) results in infinite resistance.
40
41# Examples
42
43```
44use approx::assert_abs_diff_eq;
45
46use stem_wire::prelude::*;
47use stem_wire::resistance::conductor_area;
48
49let conductivity = ElectricalConductivity::new::<siemens_per_meter>(6e7);
50let length = Length::new::<meter>(6.0);
51let area = Area::new::<square_meter>(1e-6);
52
53let r = conductor_area(conductivity, length, area);
54assert_abs_diff_eq!(r.get::<ohm>(), 0.1, epsilon=1e-3);
55```
56*/
57pub fn conductor_area(
58 conductivity: ElectricalConductivity,
59 length: Length,
60 area: Area,
61) -> ElectricalResistance {
62 length / (area * conductivity)
63}
64
65/**
66Calculates the electrical resistance of a homogeneous rectangular
67prism (cuboid) traversed by a current flowing between two opposing faces.
68
69The current flows along `length`, while `width` and `height`
70define the rectangular cross-sectional area.
71
72Implemented relation:
73
74R = L / (σ · width · height)
75
76Division by zero results in infinite resistance.
77
78# Examples
79
80```
81use approx::assert_abs_diff_eq;
82
83use stem_wire::prelude::*;
84use stem_wire::resistance::quader;
85
86let result = quader(
87 ElectricalConductivity::new::<siemens_per_meter>(5.0),
88 Length::new::<meter>(20.0),
89 Length::new::<meter>(2.0),
90 Length::new::<meter>(1.0),
91);
92assert_eq!(result.get::<ohm>(), 2.0);
93
94// Zero cross-sectional dimension
95let result = quader(
96 ElectricalConductivity::new::<siemens_per_meter>(5.0),
97 Length::new::<meter>(20.0),
98 Length::new::<meter>(2.0),
99 Length::new::<meter>(0.0),
100);
101assert!(result.is_infinite());
102```
103*/
104pub fn quader(
105 conductivity: ElectricalConductivity,
106 length: Length,
107 width: Length,
108 height: Length,
109) -> ElectricalResistance {
110 length / (width * height * conductivity)
111}
112
113/**
114Calculates the electrical resistance of a hollow cylindrical segment
115with current flowing axially between its circular end faces.
116
117Cross-sectional area:
118
119A = π (r_outer² − r_inner²)
120
121Implemented relation:
122
123R = L / (σ · A · fraction)
124
125Requires `r_outer ≥ r_inner`.
126Division by zero results in infinite resistance.
127
128# Examples
129
130```
131use approx::assert_abs_diff_eq;
132
133use stem_wire::prelude::*;
134use stem_wire::resistance::cylinder_axial;
135
136// Full cylinder
137let result = cylinder_axial(
138 ElectricalConductivity::new::<siemens_per_meter>(5.0),
139 Length::new::<meter>(20.0),
140 Length::new::<meter>(2.0),
141 Length::new::<meter>(0.0),
142 1.0
143);
144approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.318309, epsilon = 1e-6);
145
146// Half cylinder
147let result = cylinder_axial(
148 ElectricalConductivity::new::<siemens_per_meter>(5.0),
149 Length::new::<meter>(20.0),
150 Length::new::<meter>(2.0),
151 Length::new::<meter>(0.0),
152 0.5
153);
154approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.636619, epsilon = 1e-6);
155```
156*/
157pub fn cylinder_axial(
158 conductivity: ElectricalConductivity,
159 length: Length,
160 outer_radius: Length,
161 inner_radius: Length,
162 fraction: f64,
163) -> ElectricalResistance {
164 use stem_material::uom::typenum::P2;
165
166 let area = PI * (outer_radius.powi(P2::new()) - inner_radius.powi(P2::new()));
167
168 length / (area * conductivity * fraction)
169}
170
171/**
172Calculates the electrical resistance of a hollow cylindrical segment
173with current flowing radially from the inner radius to the outer radius.
174
175Implemented relation:
176
177R = ln(r_outer / r_inner) / (2π L σ · fraction)
178
179Requires `r_outer > r_inner`.
180Division by zero results in infinite resistance.
181
182# Examples
183
184```
185use approx::assert_abs_diff_eq;
186
187use stem_wire::prelude::*;
188use stem_wire::resistance::cylinder_radial;
189
190// Full cylinder
191let result = cylinder_radial(
192 ElectricalConductivity::new::<siemens_per_meter>(5.0),
193 Length::new::<meter>(20.0),
194 Length::new::<meter>(2.0),
195 Length::new::<meter>(1.0),
196 1.0
197);
198approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.0011031, epsilon = 1e-6);
199
200// Half cylinder
201let result = cylinder_radial(
202 ElectricalConductivity::new::<siemens_per_meter>(5.0),
203 Length::new::<meter>(20.0),
204 Length::new::<meter>(2.0),
205 Length::new::<meter>(1.0),
206 0.5
207);
208approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.0022064, epsilon = 1e-6);
209```
210*/
211pub fn cylinder_radial(
212 conductivity: ElectricalConductivity,
213 length: Length,
214 outer_radius: Length,
215 inner_radius: Length,
216 fraction: f64,
217) -> ElectricalResistance {
218 (outer_radius / inner_radius).ln() / (TAU * length * conductivity * fraction)
219}
220
221/**
222Calculates the electrical resistance of a hollow cylindrical segment
223with current flowing tangentially (circumferential direction).
224
225Implemented relation:
226
227R = (2π · fraction) / (σ · L · ln(r_outer / r_inner))
228
229Requires `r_outer > r_inner`.
230Division by zero results in infinite resistance.
231
232# Examples
233
234```
235use approx::assert_abs_diff_eq;
236
237use stem_wire::prelude::*;
238use stem_wire::resistance::cylinder_tangential;
239
240// Full cylinder
241let result = cylinder_tangential(
242 ElectricalConductivity::new::<siemens_per_meter>(5.0),
243 Length::new::<meter>(20.0),
244 Length::new::<meter>(2.0),
245 Length::new::<meter>(1.0),
246 1.0
247);
248approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.0906472, epsilon = 1e-6);
249
250// Half cylinder
251let result = cylinder_tangential(
252 ElectricalConductivity::new::<siemens_per_meter>(5.0),
253 Length::new::<meter>(20.0),
254 Length::new::<meter>(2.0),
255 Length::new::<meter>(1.0),
256 0.5
257);
258approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.0906472/2.0, epsilon = 1e-6);
259```
260*/
261pub fn cylinder_tangential(
262 conductivity: ElectricalConductivity,
263 length: Length,
264 outer_radius: Length,
265 inner_radius: Length,
266 fraction: f64,
267) -> ElectricalResistance {
268 TAU * fraction / (length * conductivity * (outer_radius / inner_radius).ln())
269}
270
271/**
272Calculates the electrical resistance of a hollow spherical shell
273with current flowing radially from the inner sphere to the outer sphere.
274
275Implemented relation:
276
277R = (1 / (4π σ · fraction)) · (1/r_inner − 1/r_outer)
278
279Requires `r_outer > r_inner`.
280Division by zero results in infinite resistance.
281
282```
283use approx::assert_abs_diff_eq;
284
285use stem_wire::prelude::*;
286use stem_wire::resistance::sphere_radial;
287
288// Full sphere
289let result = sphere_radial(
290 ElectricalConductivity::new::<siemens_per_meter>(5.0),
291 Length::new::<meter>(2.0),
292 Length::new::<meter>(1.0),
293 1.0
294);
295approx::assert_abs_diff_eq!(result.get::<ohm>(), 0.0079577, epsilon = 1e-6);
296
297// Half sphere
298let result = sphere_radial(
299 ElectricalConductivity::new::<siemens_per_meter>(5.0),
300 Length::new::<meter>(2.0),
301 Length::new::<meter>(1.0),
302 0.5
303);
304approx::assert_abs_diff_eq!(result.get::<ohm>(), 2.0*0.0079577, epsilon = 1e-6);
305```
306*/
307pub fn sphere_radial(
308 conductivity: ElectricalConductivity,
309 outer_radius: Length,
310 inner_radius: Length,
311 fraction: f64,
312) -> ElectricalResistance {
313 (f64::from(outer_radius / inner_radius) - 1.0)
314 / (4.0 * PI * conductivity * outer_radius * fraction)
315}