autd3_core/environment/
mod.rs

1use core::f32::consts::PI;
2
3use crate::common::{METER, ULTRASOUND_FREQ};
4
5#[non_exhaustive]
6#[repr(C)]
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Environment {
9    pub sound_speed: f32,
10}
11
12impl Environment {
13    /// Creates a new environment with the default sound speed (340m/s).
14    pub fn new() -> Self {
15        Self {
16            sound_speed: 340.0 * METER,
17        }
18    }
19
20    /// Sets the sound speed of envs from the temperature.
21    ///
22    /// This is equivalent to `Self::set_sound_speed_from_temp_with(t, 1.4, 8.314_463, 28.9647e-3)`.
23    pub fn set_sound_speed_from_temp(&mut self, t: f32) {
24        self.set_sound_speed_from_temp_with(t, 1.4, 8.314_463, 28.9647e-3);
25    }
26
27    /// Sets the sound speed of envs from the temperature `t`, heat capacity ratio `k`, gas constant `r`, and molar mass `m` [kg/mol].
28    pub fn set_sound_speed_from_temp_with(&mut self, t: f32, k: f32, r: f32, m: f32) {
29        let c2 = k * r * (273.15 + t) / m;
30        let c = c2.sqrt();
31        self.sound_speed = c * METER;
32    }
33
34    /// Gets the wavelength of the ultrasound.
35    #[must_use]
36    pub const fn wavelength(&self) -> f32 {
37        self.sound_speed / ULTRASOUND_FREQ.hz() as f32
38    }
39
40    /// Gets the wavenumber of the ultrasound.
41    #[must_use]
42    pub const fn wavenumber(&self) -> f32 {
43        2.0 * PI * ULTRASOUND_FREQ.hz() as f32 / self.sound_speed
44    }
45}
46
47impl Default for Environment {
48    fn default() -> Self {
49        Self::new()
50    }
51}
52
53#[cfg(test)]
54pub(crate) mod tests {
55    use super::*;
56    use crate::common::mm;
57
58    #[rstest::rstest]
59    #[case(340.29525e3, 15.)]
60    #[case(343.23497e3, 20.)]
61    #[case(349.04013e3, 30.)]
62    fn set_sound_speed_from_temp(#[case] expected: f32, #[case] temp: f32) {
63        let mut env = Environment::new();
64        env.set_sound_speed_from_temp(temp);
65        approx::assert_abs_diff_eq!(expected * mm, env.sound_speed, epsilon = 1e-3);
66    }
67
68    #[rstest::rstest]
69    #[case(8.5, 340e3)]
70    #[case(10., 400e3)]
71    fn wavelength(#[case] expect: f32, #[case] c: f32) {
72        let mut env = Environment::new();
73        env.sound_speed = c;
74        approx::assert_abs_diff_eq!(expect, env.wavelength());
75    }
76
77    #[rstest::rstest]
78    #[case(0.739_198_27, 340e3)]
79    #[case(0.628_318_55, 400e3)]
80    fn wavenumber(#[case] expect: f32, #[case] c: f32) {
81        let mut env = Environment::new();
82        env.sound_speed = c;
83        approx::assert_abs_diff_eq!(expect, env.wavenumber());
84    }
85}