use crate::cell::CellBox;
use crate::errors::*;
use core::hash::Hash;
use std::ops::{Add, Mul};
use num::Zero;
use serde::{Deserialize, Serialize};
use super::cycle::CycleEvent;
pub trait Domain<C, I, V>: Send + Sync + Serialize + for<'a> Deserialize<'a> {
fn apply_boundary(&self, cell: &mut C) -> Result<(), BoundaryError>;
fn get_neighbor_voxel_indices(&self, index: &I) -> Vec<I>;
fn get_voxel_index(&self, cell: &C) -> I;
fn get_all_indices(&self) -> Vec<I>;
fn generate_contiguous_multi_voxel_regions(
&self,
n_regions: usize,
) -> Result<Vec<Vec<(I, V)>>, CalcError>;
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum BoundaryCondition<ConcVecExtracellular> {
Neumann(ConcVecExtracellular),
Dirichlet(ConcVecExtracellular),
Value(ConcVecExtracellular),
}
pub trait Index: Ord + Hash + Eq + Clone + Send + Sync + Serialize + std::fmt::Debug {}
impl<T> Index for T where T: Ord + Hash + Eq + Clone + Send + Sync + Serialize + std::fmt::Debug {}
pub trait Concentration:
Sized + Add<Self, Output = Self> + Mul<f64, Output = Self> + Send + Sync + Zero
{
}
impl<T> Concentration for T where
T: Sized + Add<Self, Output = Self> + Mul<f64, Output = Self> + Send + Sync + Zero
{
}
pub trait Voxel<Ind, Pos, Vel, Force>:
Send + Sync + Clone + Serialize + for<'a> Deserialize<'a>
{
fn custom_force_on_cell(&self, _pos: &Pos, _vel: &Vel) -> Option<Result<Force, CalcError>> {
None
}
fn get_index(&self) -> Ind;
}
pub trait ExtracellularMechanics<
Ind,
Pos,
ConcVec,
ConcGradient,
ConcTotal = ConcVec,
ConcBoundary = ConcVec,
>: Send + Sync + Clone + Serialize + for<'a> Deserialize<'a>
{
fn get_extracellular_at_point(&self, pos: &Pos) -> Result<ConcVec, RequestError>;
fn get_total_extracellular(&self) -> ConcTotal;
#[cfg(feature = "gradients")]
fn update_extracellular_gradient(
&mut self,
boundaries: &[(Ind, BoundaryCondition<ConcBoundary>)],
) -> Result<(), CalcError>;
#[cfg(feature = "gradients")]
fn get_extracellular_gradient_at_point(&self, pos: &Pos) -> Result<ConcGradient, RequestError>;
fn set_total_extracellular(&mut self, concentration_total: &ConcTotal)
-> Result<(), CalcError>;
fn calculate_increment(
&self,
total_extracellular: &ConcTotal,
point_sources: &[(Pos, ConcVec)],
boundaries: &[(Ind, BoundaryCondition<ConcBoundary>)],
) -> Result<ConcTotal, CalcError>;
fn boundary_condition_to_neighbor_voxel(
&self,
neighbor_index: &Ind,
) -> Result<BoundaryCondition<ConcBoundary>, IndexError>;
}
pub trait Controller<C, O> {
fn measure<'a, I>(&self, cells: I) -> Result<O, CalcError>
where
C: 'a + Serialize + for<'b> Deserialize<'b>,
I: IntoIterator<Item = &'a CellBox<C>> + Clone;
fn adjust<'a, 'b, I, J>(&mut self, measurements: I, cells: J) -> Result<(), ControllerError>
where
O: 'a,
C: 'b + Serialize + for<'c> Deserialize<'c>,
I: Iterator<Item = &'a O>,
J: Iterator<Item = (&'b mut CellBox<C>, &'b mut Vec<CycleEvent>)>;
}
impl<C> Controller<C, ()> for () {
fn measure<'a, I>(&self, _cells: I) -> Result<(), CalcError>
where
C: 'a + Serialize + for<'b> Deserialize<'b>,
I: IntoIterator<Item = &'a CellBox<C>> + Clone,
{
Ok(())
}
#[allow(unused)]
fn adjust<'a, 'b, I, J>(&mut self, measurements: I, cells: J) -> Result<(), ControllerError>
where
(): 'a,
C: 'b + Serialize + for<'c> Deserialize<'c>,
I: Iterator<Item = &'a ()>,
J: Iterator<Item = (&'b mut CellBox<C>, &'b mut Vec<CycleEvent>)>,
{
Ok(())
}
}