cellular_raza_concepts/
cell.rs

1use crate::errors::{CalcError, RngError};
2use crate::interaction::*;
3use crate::mechanics::{Mechanics, Position, Velocity};
4
5use serde::{Deserialize, Serialize};
6
7// TODO move this module to cpu_os_threads backend except for traits
8
9/// This is a unique identifier which is deterministic even in multi-threading situations.
10/// Its components are
11/// 1. PlainIndex of Voxel where it was created
12/// 2. Count the number of cells that have already been created in this voxel since simulation begin.
13// TODO consider making this an associated type of the Id trait
14pub type CellularIdentifier = (u64, u64);
15
16/// Specifies how to retrieve a unique identifier of an object.
17pub trait Id {
18    /// The identifier type is usually chosen to be completely unique and repeatable across
19    /// different simulations.
20    type Identifier;
21
22    /// Retrieves the Identifier from the object.
23    fn get_id(&self) -> Self::Identifier;
24    /// Returns a reference to the id of the object.
25    fn ref_id(&self) -> &Self::Identifier;
26}
27
28/// A container struct containing meta-information of a given Cell
29/// Some variables such as id are not required and not desired to be
30/// initialized by the user. This [CellAgentBox] acts as a container around the cell
31/// to hold these variables.
32#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
33pub struct CellAgentBox<Cel> {
34    id: CellularIdentifier,
35    parent_id: Option<CellularIdentifier>,
36    /// The user-defined cell which is stored inside this container.
37    pub cell: Cel,
38}
39
40impl<Cel> Id for CellAgentBox<Cel> {
41    type Identifier = CellularIdentifier;
42
43    fn get_id(&self) -> CellularIdentifier {
44        self.id
45    }
46
47    fn ref_id(&self) -> &CellularIdentifier {
48        &self.id
49    }
50}
51
52impl<Cel> CellAgentBox<Cel> {
53    /// Simple method to retrieve the [CellularIdentifier] of the parent cell if existing.
54    pub fn get_parent_id(&self) -> Option<CellularIdentifier> {
55        self.parent_id
56    }
57}
58
59// Auto-implement traits for CellAgentBox which where also implemented for Agent
60impl<Pos, Vel, For, Inf, A> Interaction<Pos, Vel, For, Inf> for CellAgentBox<A>
61where
62    A: Interaction<Pos, Vel, For, Inf> + Serialize + for<'a> Deserialize<'a>,
63{
64    fn get_interaction_information(&self) -> Inf {
65        self.cell.get_interaction_information()
66    }
67
68    fn calculate_force_between(
69        &self,
70        own_pos: &Pos,
71        own_vel: &Vel,
72        ext_pos: &Pos,
73        ext_vel: &Vel,
74        ext_information: &Inf,
75    ) -> Result<(For, For), CalcError> {
76        self.cell
77            .calculate_force_between(own_pos, own_vel, ext_pos, ext_vel, ext_information)
78    }
79
80    fn is_neighbor(&self, own_pos: &Pos, ext_pos: &Pos, ext_inf: &Inf) -> Result<bool, CalcError> {
81        self.cell.is_neighbor(own_pos, ext_pos, ext_inf)
82    }
83
84    fn react_to_neighbors(&mut self, neighbors: usize) -> Result<(), CalcError> {
85        self.cell.react_to_neighbors(neighbors)
86    }
87}
88
89impl<A, Pos> Position<Pos> for CellAgentBox<A>
90where
91    A: Position<Pos>,
92{
93    fn pos(&self) -> Pos {
94        self.cell.pos()
95    }
96
97    fn set_pos(&mut self, pos: &Pos) {
98        self.cell.set_pos(pos)
99    }
100}
101
102impl<A, Vel> Velocity<Vel> for CellAgentBox<A>
103where
104    A: Velocity<Vel>,
105{
106    fn velocity(&self) -> Vel {
107        self.cell.velocity()
108    }
109
110    fn set_velocity(&mut self, velocity: &Vel) {
111        self.cell.set_velocity(velocity)
112    }
113}
114
115impl<Pos, Vel, For, Float, A> Mechanics<Pos, Vel, For, Float> for CellAgentBox<A>
116where
117    A: Mechanics<Pos, Vel, For, Float>,
118{
119    /* fn pos(&self) -> Pos {
120        self.cell.pos()
121    }
122
123    fn velocity(&self) -> Vel {
124        self.cell.velocity()
125    }
126
127    fn set_pos(&mut self, pos: &Pos) {
128        self.cell.set_pos(pos);
129    }
130
131    fn set_velocity(&mut self, velocity: &Vel) {
132        self.cell.set_velocity(velocity);
133    }*/
134
135    fn get_random_contribution(
136        &self,
137        rng: &mut rand_chacha::ChaCha8Rng,
138        dt: Float,
139    ) -> Result<(Pos, Vel), RngError> {
140        self.cell.get_random_contribution(rng, dt)
141    }
142
143    fn calculate_increment(&self, force: For) -> Result<(Pos, Vel), CalcError> {
144        self.cell.calculate_increment(force)
145    }
146}
147
148impl<Cel> CellAgentBox<Cel> {
149    /// Create a new [CellAgentBox] at a specific voxel with a voxel-unique number
150    /// of cells that has already been created at this position.
151    // TODO make this generic with respect to voxel_index
152    pub fn new(
153        voxel_index: u64,
154        n_cell: u64,
155        cell: Cel,
156        parent_id: Option<CellularIdentifier>,
157    ) -> CellAgentBox<Cel> {
158        CellAgentBox::<Cel> {
159            id: (voxel_index, n_cell),
160            parent_id,
161            cell,
162        }
163    }
164}
165
166#[doc(inline)]
167pub use cellular_raza_concepts_derive::CellAgent;