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)
    }
}