sva_samples/physics/
mod.rs1pub mod botteldooren;
4pub mod bound;
5pub mod chaigne_askenfelt;
6pub mod chaigne_doutaut;
7pub mod darabundit_scavone;
8pub mod hammer;
9pub mod rhaouti_chaigne_joly;
10pub mod tonehole;
11pub mod willemsen_bilbao_serafin;
12
13use crate::error::SampleError;
14
15use botteldooren::{BotteldoorenParams, BotteldoorenSite};
16use chaigne_askenfelt::{ChaigneAskenfeltParams, ChaigneAskenfeltSite};
17use chaigne_doutaut::{ChaigneDoutautParams, ChaigneDoutautSite};
18use darabundit_scavone::{BoreParams, BoreSite};
19use rhaouti_chaigne_joly::{RhaoutiChaigneJolyParams, RhaoutiChaigneJolySite};
20use willemsen_bilbao_serafin::{WillemsenBilbaoSerafinParams, WillemsenBilbaoSerafinSite};
21
22pub trait Solver {
24 fn step(&mut self) -> f64;
25}
26
27#[derive(Clone, Debug, PartialEq)]
28pub enum Params {
29 ChaigneAskenfelt(ChaigneAskenfeltParams),
30 WillemsenBilbaoSerafin(WillemsenBilbaoSerafinParams),
31 DarabunditScavone(BoreParams),
32 RhaoutiChaigneJoly(RhaoutiChaigneJolyParams),
33 ChaigneDoutaut(ChaigneDoutautParams),
34 Botteldooren(BotteldoorenParams),
35}
36
37impl Params {
38 pub fn name(&self) -> &'static str {
39 match self {
40 Params::ChaigneAskenfelt(_) => "chaigne_askenfelt",
41 Params::WillemsenBilbaoSerafin(_) => "willemsen_bilbao_serafin",
42 Params::DarabunditScavone(_) => "darabundit_scavone",
43 Params::RhaoutiChaigneJoly(_) => "rhaouti_chaigne_joly",
44 Params::ChaigneDoutaut(_) => "chaigne_doutaut",
45 Params::Botteldooren(_) => "botteldooren",
46 }
47 }
48
49 pub fn valid(&self) -> bool {
50 match self {
51 Params::ChaigneAskenfelt(p) => p.valid(),
52 Params::WillemsenBilbaoSerafin(p) => p.valid(),
53 Params::DarabunditScavone(p) => p.valid(),
54 Params::RhaoutiChaigneJoly(p) => p.valid(),
55 Params::ChaigneDoutaut(p) => p.valid(),
56 Params::Botteldooren(p) => p.valid(),
57 }
58 }
59}
60
61pub fn site(p: &Params, rate: u32) -> Result<Box<dyn Solver>, SampleError> {
64 let sr = f64::from(rate);
65 Ok(match p {
66 Params::ChaigneAskenfelt(p) => Box::new(ChaigneAskenfeltSite::new(p, sr)?),
67 Params::WillemsenBilbaoSerafin(p) => Box::new(WillemsenBilbaoSerafinSite::new(p, sr)),
68 Params::DarabunditScavone(p) => Box::new(BoreSite::new(p, sr)),
69 Params::RhaoutiChaigneJoly(p) => {
70 under_ceiling(
71 "rhaouti_chaigne_joly",
72 rhaouti_chaigne_joly::node_count(p, sr),
73 rhaouti_chaigne_joly::NODE_COUNT_CEILING,
74 )?;
75 Box::new(RhaoutiChaigneJolySite::new(p, sr))
76 }
77 Params::ChaigneDoutaut(p) => Box::new(ChaigneDoutautSite::new(p, sr)),
78 Params::Botteldooren(p) => {
79 under_ceiling(
80 "botteldooren",
81 botteldooren::node_count(p.f0, p.aspect_y, p.aspect_z, sr),
82 botteldooren::NODE_COUNT_CEILING,
83 )?;
84 Box::new(BotteldoorenSite::new(p, sr))
85 }
86 })
87}
88
89fn under_ceiling(model: &'static str, nodes: f64, ceiling: usize) -> Result<(), SampleError> {
90 match nodes > ceiling as f64 {
91 true => Err(SampleError::GridTooLarge {
92 model,
93 nodes: nodes as usize,
94 ceiling,
95 }),
96 false => Ok(()),
97 }
98}
99
100pub(crate) fn raised_cosine_pulse(t: f64, amp: f64, width: f64) -> f64 {
103 match t < width {
104 true => amp * 0.5 * (1.0 - (std::f64::consts::TAU * t / width).cos()),
105 false => 0.0,
106 }
107}