use crate::{Grid1d, Side};
use std::sync::Arc;
pub struct NaturalBcs1d<'a> {
pub(crate) functions: Vec<Arc<dyn Fn(f64) -> f64 + Send + Sync + 'a>>,
pub(crate) sides: [bool; 2], }
impl<'a> NaturalBcs1d<'a> {
pub fn new() -> Self {
NaturalBcs1d {
functions: vec![
Arc::new(|_| 0.0), Arc::new(|_| 0.0), ],
sides: [false; 2],
}
}
pub fn set(&mut self, side: Side, f: impl Fn(f64) -> f64 + Send + Sync + 'a) {
let index = side as usize;
self.functions[index] = Arc::new(f);
self.sides[index] = true;
}
pub(crate) fn enabled_m(&self, m: usize, grid: &Grid1d) -> bool {
if m == 0 {
self.sides[0]
} else if m == grid.nx() - 1 {
self.sides[1]
} else {
false
}
}
}
#[cfg(test)]
mod tests {
use super::NaturalBcs1d;
use crate::{Grid1d, Side};
#[test]
fn new_works() {
let natural_bcs = NaturalBcs1d::new();
assert_eq!(natural_bcs.sides, [false, false]);
assert_eq!((natural_bcs.functions[0])(0.0), 0.0);
assert_eq!((natural_bcs.functions[1])(0.0), 0.0);
}
#[test]
fn set_works() {
let mut natural_bcs = NaturalBcs1d::new();
natural_bcs.set(Side::Xmin, |_| -10.0);
natural_bcs.set(Side::Xmax, |_| 10.0);
assert_eq!(natural_bcs.sides, [true, true]);
assert_eq!((natural_bcs.functions[0])(0.0), -10.0);
assert_eq!((natural_bcs.functions[1])(0.0), 10.0);
}
#[test]
#[should_panic]
fn set_panics_on_invalid_side() {
let mut natural_bcs = NaturalBcs1d::new();
natural_bcs.set(Side::Ymin, |_| 0.0);
}
#[test]
fn enabled_m_works() {
let grid = Grid1d::new_uniform(0.0, 1.0, 3).unwrap();
let mut natural_bcs = NaturalBcs1d::new();
natural_bcs.set(Side::Xmin, |_| -10.0);
assert!(natural_bcs.enabled_m(0, &grid));
assert!(!natural_bcs.enabled_m(1, &grid));
assert!(!natural_bcs.enabled_m(2, &grid));
natural_bcs.set(Side::Xmax, |_| 10.0);
assert!(natural_bcs.enabled_m(0, &grid));
assert!(!natural_bcs.enabled_m(1, &grid));
assert!(natural_bcs.enabled_m(2, &grid));
}
}