de-virtualize GenericSim
this should let us fold the GenericSim and MaterialSim traits together.
This commit is contained in:
@@ -217,77 +217,6 @@ impl<R: Real> CellStateWithM<R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> dyn GenericSim + 'a {
|
||||
pub fn get<C: Coord>(&self, at: C) -> Sample {
|
||||
self.sample(at.to_meters(self.feature_size()))
|
||||
}
|
||||
|
||||
/// Apply `F` to each Cell, and sum the results.
|
||||
pub fn map_sum<F, Ret>(&self, f: F) -> Ret
|
||||
where
|
||||
F: Fn(&Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Send,
|
||||
{
|
||||
self.map_sum_enumerated(|_at: Index, cell| f(cell))
|
||||
}
|
||||
|
||||
pub fn map_sum_enumerated<C, F, Ret>(&self, f: F) -> Ret
|
||||
where C: Coord,
|
||||
F: Fn(C, &Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Send,
|
||||
{
|
||||
let (w, h, d) = (self.width(), self.height(), self.depth());
|
||||
(0..d).into_par_iter().map(
|
||||
|z| (0..h).into_par_iter().map_with(z,
|
||||
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|
||||
|&mut (z, y), x|
|
||||
{
|
||||
let at = Index(Vec3u::new(x, y, z));
|
||||
f(C::from_index(at, self.feature_size()), &self.get(at))
|
||||
}))).flatten().flatten().sum()
|
||||
}
|
||||
|
||||
pub fn volume_of_region<R: Region + ?Sized>(&self, region: &R) -> u32 {
|
||||
self.map_sum_over(region, |_| 1)
|
||||
}
|
||||
|
||||
/// Apply `F` to each Cell, and sum the results.
|
||||
pub fn map_sum_over<F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
|
||||
where
|
||||
F: Fn(&Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Default + Send,
|
||||
Reg: Region + ?Sized
|
||||
{
|
||||
self.map_sum_over_enumerated(region, |_at: Index, cell| f(cell))
|
||||
}
|
||||
|
||||
pub fn map_sum_over_enumerated<C, F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
|
||||
where C: Coord,
|
||||
F: Fn(C, &Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Default + Send,
|
||||
Reg: Region + ?Sized,
|
||||
{
|
||||
let (w, h, d) = (self.width(), self.height(), self.depth());
|
||||
(0..d).into_par_iter().map(
|
||||
|z| (0..h).into_par_iter().map_with(z,
|
||||
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|
||||
|&mut (z, y), x|
|
||||
{
|
||||
let at = Index(Vec3u::new(x, y, z));
|
||||
let meters = at.to_meters(self.feature_size());
|
||||
if region.contains(meters) {
|
||||
f(C::from_index(at, self.feature_size()), &self.get(at))
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
}))).flatten().flatten().sum()
|
||||
}
|
||||
|
||||
pub fn current<C: Coord>(&self, c: C) -> Vec3<f32> {
|
||||
self.get(c).current_density() * self.feature_size() * self.feature_size()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: the Send/Sync bounds here could be removed with some refactoring
|
||||
pub trait GenericSim: Send + Sync {
|
||||
fn meta(&self) -> SimMeta<f32>;
|
||||
@@ -327,4 +256,73 @@ pub trait GenericSim: Send + Sync {
|
||||
fn time(&self) -> f32 {
|
||||
self.timestep() * self.step_no() as f32
|
||||
}
|
||||
|
||||
fn get<C: Coord>(&self, at: C) -> Sample {
|
||||
self.sample(at.to_meters(self.feature_size()))
|
||||
}
|
||||
|
||||
/// Apply `F` to each Cell, and sum the results.
|
||||
fn map_sum<F, Ret>(&self, f: F) -> Ret
|
||||
where
|
||||
F: Fn(&Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Send,
|
||||
{
|
||||
self.map_sum_enumerated(|_at: Index, cell| f(cell))
|
||||
}
|
||||
|
||||
fn map_sum_enumerated<C, F, Ret>(&self, f: F) -> Ret
|
||||
where C: Coord,
|
||||
F: Fn(C, &Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Send,
|
||||
{
|
||||
let (w, h, d) = (self.width(), self.height(), self.depth());
|
||||
(0..d).into_par_iter().map(
|
||||
|z| (0..h).into_par_iter().map_with(z,
|
||||
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|
||||
|&mut (z, y), x|
|
||||
{
|
||||
let at = Index(Vec3u::new(x, y, z));
|
||||
f(C::from_index(at, self.feature_size()), &self.get(at))
|
||||
}))).flatten().flatten().sum()
|
||||
}
|
||||
|
||||
fn volume_of_region<R: Region + ?Sized>(&self, region: &R) -> u32 {
|
||||
self.map_sum_over(region, |_| 1)
|
||||
}
|
||||
|
||||
/// Apply `F` to each Cell, and sum the results.
|
||||
fn map_sum_over<F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
|
||||
where
|
||||
F: Fn(&Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Default + Send,
|
||||
Reg: Region + ?Sized
|
||||
{
|
||||
self.map_sum_over_enumerated(region, |_at: Index, cell| f(cell))
|
||||
}
|
||||
|
||||
fn map_sum_over_enumerated<C, F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
|
||||
where C: Coord,
|
||||
F: Fn(C, &Sample) -> Ret + Sync,
|
||||
Ret: Sum<Ret> + Default + Send,
|
||||
Reg: Region + ?Sized,
|
||||
{
|
||||
let (w, h, d) = (self.width(), self.height(), self.depth());
|
||||
(0..d).into_par_iter().map(
|
||||
|z| (0..h).into_par_iter().map_with(z,
|
||||
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|
||||
|&mut (z, y), x|
|
||||
{
|
||||
let at = Index(Vec3u::new(x, y, z));
|
||||
let meters = at.to_meters(self.feature_size());
|
||||
if region.contains(meters) {
|
||||
f(C::from_index(at, self.feature_size()), &self.get(at))
|
||||
} else {
|
||||
Default::default()
|
||||
}
|
||||
}))).flatten().flatten().sum()
|
||||
}
|
||||
|
||||
fn current<C: Coord>(&self, c: C) -> Vec3<f32> {
|
||||
self.get(c).current_density() * self.feature_size() * self.feature_size()
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user