use crate::data::ImageData;
#[derive(Debug, Clone)]
pub struct AMRLevel {
pub level: usize,
pub blocks: Vec<ImageData>,
pub spacing: [f64; 3],
}
#[derive(Debug, Clone, Default)]
pub struct AMRDataSet {
pub levels: Vec<AMRLevel>,
}
impl AMRDataSet {
pub fn new() -> Self {
Self::default()
}
pub fn add_level(&mut self, spacing: [f64; 3]) -> usize {
let level = self.levels.len();
self.levels.push(AMRLevel {
level,
blocks: Vec::new(),
spacing,
});
level
}
pub fn add_block(&mut self, level: usize, block: ImageData) -> usize {
let idx = self.levels[level].blocks.len();
self.levels[level].blocks.push(block);
idx
}
pub fn num_levels(&self) -> usize {
self.levels.len()
}
pub fn num_blocks(&self, level: usize) -> usize {
self.levels[level].blocks.len()
}
pub fn block(&self, level: usize, idx: usize) -> &ImageData {
&self.levels[level].blocks[idx]
}
pub fn total_blocks(&self) -> usize {
self.levels.iter().map(|l| l.blocks.len()).sum()
}
pub fn coarsest_spacing(&self) -> [f64; 3] {
self.levels.first().map_or([0.0; 3], |l| l.spacing)
}
pub fn finest_spacing(&self) -> [f64; 3] {
self.levels.last().map_or([0.0; 3], |l| l.spacing)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn amr_basic() {
let mut amr = AMRDataSet::new();
let l0 = amr.add_level([1.0, 1.0, 1.0]);
let l1 = amr.add_level([0.5, 0.5, 0.5]);
let mut block0 = ImageData::with_dimensions(10, 10, 1);
block0.set_spacing([1.0, 1.0, 1.0]);
amr.add_block(l0, block0);
let mut block1 = ImageData::with_dimensions(20, 20, 1);
block1.set_spacing([0.5, 0.5, 0.5]);
amr.add_block(l1, block1);
assert_eq!(amr.num_levels(), 2);
assert_eq!(amr.num_blocks(0), 1);
assert_eq!(amr.num_blocks(1), 1);
assert_eq!(amr.total_blocks(), 2);
assert_eq!(amr.coarsest_spacing(), [1.0, 1.0, 1.0]);
assert_eq!(amr.finest_spacing(), [0.5, 0.5, 0.5]);
}
#[test]
fn amr_multiple_blocks() {
let mut amr = AMRDataSet::new();
let l0 = amr.add_level([2.0, 2.0, 2.0]);
amr.add_block(l0, ImageData::with_dimensions(5, 5, 5));
amr.add_block(l0, ImageData::with_dimensions(5, 5, 5));
amr.add_block(l0, ImageData::with_dimensions(5, 5, 5));
assert_eq!(amr.num_blocks(0), 3);
assert_eq!(amr.total_blocks(), 3);
assert_eq!(amr.block(0, 1).dimensions(), [5, 5, 5]);
}
}