Skip to main content

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}