1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Magba is licensed under The 3-Clause BSD, see LICENSE.
* Copyright 2025 Sira Pornsiriprasert <code@psira.me>
*/
use nalgebra::Vector3;
use crate::crate_utils::define_source;
define_source! {
/// Cylinder magnet source.
///
/// # References
///
/// - Caciagli, Alessio, Roel J. Baars, Albert P. Philipse, and Bonny W. M. Kuipers. “Exact Expression for the Magnetic Field of a Finite Cylinder with Arbitrary Uniform Magnetization.” Journal of Magnetism and Magnetic Materials 456 (June 15, 2018): 423–32. <https://doi.org/10.1016/j.jmmm.2018.02.003>.
/// - Derby, Norman, and Stanislaw Olbert. “Cylindrical Magnets and Ideal Solenoids.” American Journal of Physics 78, no. 3 (March 1, 2010): 229–35. <https://doi.org/10.1119/1.3256157>.
/// - Ortner, Michael, and Lucas Gabriel Coliado Bandeira. “Magpylib: A Free Python Package for Magnetic Field Computation.” SoftwareX 11 (January 1, 2020): 100466. <https://doi.org/10.1016/j.softx.2020.100466>.
CylinderMagnet
field_fn: cylinder_B
args: {
polarization: Vector3<T> = Vector3::z(),
diameter: T = T::one();
validate diameter > T::zero();
error "Diameter cannot be negative.",
height: T = T::one();
validate height > T::zero();
error "Height cannot be negative.",
}
arg_display: "pol={}, d={}, h={}";
arg_fmt: [format_vector3, format_float, format_float]
docs: {
new: {
/// Construct a [CylinderMagnet].
///
/// # Examples
///
/// ```
/// # use magba::magnets::CylinderMagnet;
/// # use nalgebra::*;
/// let magnet = CylinderMagnet::new(
/// [0.0, 0.0, 0.0], // position: Center of the cylinder (m)
/// UnitQuaternion::identity(), // orientation as unit quaternion
/// [0.0, 0.0, 1.0], // polarization (T)
/// 0.01, // diameter (m)
/// 0.02, // height (m)
/// );
/// ```
}
}
}
#[cfg(all(test, feature = "std"))]
crate::testing_util::generate_tests! {
CylinderMagnet
filename: cylinder
params: { polarization: vector![1.0, 2.0, 3.0], d: 0.1, h: 0.2}
rtols: {
static: 5e-10,
static_small: 5e-10,
translate: 2e-10,
rotate: 2e-10,
}
p95_rtols: {
static: 5e-10,
static_small: 5e-10,
translate: 5e-10,
rotate: 5e-10,
}
f32_rtols: {
static: 5e-2,
static_small: 5e-2,
translate: 5e-2,
rotate: 1e-2,
}
f32_p95_rtols: {
static: 5e-4,
static_small: 5e-4,
translate: 5e-4,
rotate: 5e-4,
}
}
#[cfg(test)]
mod tests {
use crate::magnets::CylinderMagnet;
#[test]
#[should_panic]
fn test_init_validation() {
let _ = CylinderMagnet::<f64>::new(
[0.0; 3],
nalgebra::UnitQuaternion::identity(),
[0.0, 0.0, 1.0],
-1.0_f64,
1.0_f64,
);
}
#[test]
#[should_panic]
fn test_set_diameter_validation() {
let mut magnet = CylinderMagnet::<f64>::default();
magnet.set_diameter(-1.0_f64);
}
#[test]
#[should_panic]
fn test_with_diameter_validation() {
let _: CylinderMagnet<f64> = CylinderMagnet::<f64>::default().with_diameter(-1.0_f64);
}
#[test]
#[should_panic]
fn test_set_height_validation() {
let mut magnet = CylinderMagnet::<f64>::default();
magnet.set_height(-1.0_f64);
}
#[test]
#[should_panic]
fn test_with_height_validation() {
let _: CylinderMagnet<f64> = CylinderMagnet::<f64>::default().with_height(-1.0_f64);
}
}