cellular_raza_concepts/interaction.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
use crate::errors::CalcError;
/// Trait describing force-interactions between cellular agents.
pub trait Interaction<Pos, Vel, Force, Inf = ()> {
/// Get additional information of cellular properties (ie. for cell-specific interactions).
/// For now, this can also be used to get the mass of the other cell-agent.
/// In the future, we will probably provide a custom function for this.
fn get_interaction_information(&self) -> Inf;
/// Calculates the forces (velocity-derivative) on the corresponding external position given
/// external velocity.
/// By providing velocities, we can calculate terms that are related to friction.
/// The function returns two forces, one acting on the current agent and the other on the
/// external agent.
fn calculate_force_between(
&self,
own_pos: &Pos,
own_vel: &Vel,
ext_pos: &Pos,
ext_vel: &Vel,
ext_info: &Inf,
) -> Result<(Force, Force), CalcError>;
/// Checks if the other cell represented by position and information is a neighbor to the current one or not.
#[allow(unused)]
fn is_neighbor(&self, own_pos: &Pos, ext_pos: &Pos, ext_inf: &Inf) -> Result<bool, CalcError> {
Ok(false)
}
/// Reacts to the results gathered by the [Interaction::is_neighbor]
/// method and changes the state of the cell.
#[allow(unused)]
fn react_to_neighbors(&mut self, neighbors: usize) -> Result<(), CalcError> {
Ok(())
}
// TODO
// fn contact_function(&mut self, other_cell: &C, environment: &mut Env) -> Result<(), SimulationError>;
}
impl<Pos, Vel, For, Inf> Interaction<Pos, Vel, For, Inf>
for Box<dyn Interaction<Pos, Vel, For, Inf>>
{
fn get_interaction_information(&self) -> Inf {
use core::ops::Deref;
self.deref().get_interaction_information()
}
fn calculate_force_between(
&self,
own_pos: &Pos,
own_vel: &Vel,
ext_pos: &Pos,
ext_vel: &Vel,
ext_info: &Inf,
) -> Result<(For, For), CalcError> {
use core::ops::Deref;
self.deref()
.calculate_force_between(own_pos, own_vel, ext_pos, ext_vel, ext_info)
}
fn is_neighbor(&self, own_pos: &Pos, ext_pos: &Pos, ext_inf: &Inf) -> Result<bool, CalcError> {
use core::ops::Deref;
self.deref().is_neighbor(own_pos, ext_pos, ext_inf)
}
fn react_to_neighbors(&mut self, neighbors: usize) -> Result<(), CalcError> {
use core::ops::DerefMut;
self.deref_mut().react_to_neighbors(neighbors)
}
}