1use cellular_raza_concepts::reactions_old::*;
2use cellular_raza_concepts::*;
3
4use serde::{Deserialize, Serialize};
5
6use num::Zero;
7
8#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct ModularCell<Mec, Int, Cyc, React, IntExtracellular> {
16 pub mechanics: Mec,
18 pub interaction: Int,
20 pub interaction_extracellular: IntExtracellular,
22 pub cycle: Cyc,
24 pub cellular_reactions: React,
26 pub volume: f64,
28}
29
30#[derive(Clone, Debug, Serialize, Deserialize)]
32pub struct NoCellularReactions;
33
34impl CellularReactions<Nothing, Nothing> for NoCellularReactions
35where
36 Nothing: num::Zero,
37 Nothing: num::Zero,
38{
39 fn calculate_intra_and_extracellular_reaction_increment(
40 &self,
41 _internal_concentration_vector: &Nothing,
42 _external_concentration_vector: &Nothing,
43 ) -> Result<(Nothing, Nothing), CalcError> {
44 Ok((<Nothing>::zero(), <Nothing>::zero()))
45 }
46
47 fn get_intracellular(&self) -> Nothing {
48 <Nothing>::zero()
49 }
50
51 fn set_intracellular(&mut self, _concentration_vector: Nothing) {}
52}
53
54pub type Nothing = nalgebra::SVector<f64, 0>;
56
57impl<Pos, Vel, For, Float, Mec, Int, Cyc, React, IntExtracellular> Mechanics<Pos, Vel, For, Float>
58 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
59where
60 Mec: Mechanics<Pos, Vel, For, Float>,
61{
62 fn get_random_contribution(
63 &self,
64 rng: &mut rand_chacha::ChaCha8Rng,
65 dt: Float,
66 ) -> Result<(Pos, Vel), RngError> {
67 self.mechanics.get_random_contribution(rng, dt)
68 }
69
70 fn calculate_increment(&self, force: For) -> Result<(Pos, Vel), CalcError> {
71 self.mechanics.calculate_increment(force)
72 }
73}
74
75impl<Pos, Mec, Int, Cyc, React, InteractionExtracellular> cellular_raza_concepts::Position<Pos>
76 for ModularCell<Mec, Int, Cyc, React, InteractionExtracellular>
77where
78 Mec: Position<Pos>,
79{
80 fn set_pos(&mut self, pos: &Pos) {
81 self.mechanics.set_pos(pos)
82 }
83
84 fn pos(&self) -> Pos {
85 self.mechanics.pos()
86 }
87}
88
89impl<Vel, Mec, Int, Cyc, React, InteractionExtracellular> Velocity<Vel>
90 for ModularCell<Mec, Int, Cyc, React, InteractionExtracellular>
91where
92 Mec: Velocity<Vel>,
93{
94 fn set_velocity(&mut self, velocity: &Vel) {
95 self.mechanics.set_velocity(velocity);
96 }
97
98 fn velocity(&self) -> Vel {
99 self.mechanics.velocity()
100 }
101}
102
103impl<Inf, Mec, Int, Cyc, React, IntExtracellular> InteractionInformation<Inf>
104 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
105where
106 Int: InteractionInformation<Inf>,
107{
108 fn get_interaction_information(&self) -> Inf {
109 self.interaction.get_interaction_information()
110 }
111}
112
113impl<Pos, Vel, For, Inf, Mec, Int, Cyc, React, IntExtracellular> Interaction<Pos, Vel, For, Inf>
114 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
115where
116 Int: Interaction<Pos, Vel, For, Inf>,
117{
118 fn calculate_force_between(
119 &self,
120 own_pos: &Pos,
121 own_vel: &Vel,
122 ext_pos: &Pos,
123 ext_vel: &Vel,
124 ext_information: &Inf,
125 ) -> Result<(For, For), CalcError> {
126 self.interaction.calculate_force_between(
127 own_pos,
128 own_vel,
129 ext_pos,
130 ext_vel,
131 ext_information,
132 )
133 }
134}
135
136impl<Mec, Int, Cyc, React, IntExtracellular> Volume
137 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
138{
139 fn get_volume(&self) -> f64 {
140 self.volume
141 }
142}
143
144impl<Mec, Int, Cyc, Float, React, IntExtracellular> Cycle<Self, Float>
145 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
146where
147 Cyc: Cycle<Self, Float>,
148{
149 fn update_cycle(
150 rng: &mut rand_chacha::ChaCha8Rng,
151 dt: &Float,
152 cell: &mut Self,
153 ) -> Option<CycleEvent> {
154 Cyc::update_cycle(rng, dt, cell)
155 }
156
157 fn divide(rng: &mut rand_chacha::ChaCha8Rng, cell: &mut Self) -> Result<Self, DivisionError> {
158 Cyc::divide(rng, cell)
159 }
160
161 fn update_conditional_phased_death(
162 rng: &mut rand_chacha::ChaCha8Rng,
163 dt: &Float,
164 cell: &mut Self,
165 ) -> Result<bool, DeathError> {
166 Cyc::update_conditional_phased_death(rng, dt, cell)
167 }
168}
169
170impl<ConcVecIntracellular, ConcVecExtracellular, Mec, Int, Cyc, React, IntExtracellular>
171 CellularReactions<ConcVecIntracellular, ConcVecExtracellular>
172 for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
173where
174 React: CellularReactions<ConcVecIntracellular, ConcVecExtracellular>,
175{
176 fn calculate_intra_and_extracellular_reaction_increment(
177 &self,
178 internal_concentration_vector: &ConcVecIntracellular,
179 external_concentration_vector: &ConcVecExtracellular,
180 ) -> Result<(ConcVecIntracellular, ConcVecExtracellular), CalcError> {
181 self.cellular_reactions
182 .calculate_intra_and_extracellular_reaction_increment(
183 internal_concentration_vector,
184 external_concentration_vector,
185 )
186 }
187
188 fn get_intracellular(&self) -> ConcVecIntracellular {
189 self.cellular_reactions.get_intracellular()
190 }
191
192 fn set_intracellular(&mut self, concentration_vector: ConcVecIntracellular) {
193 self.cellular_reactions
194 .set_intracellular(concentration_vector)
195 }
196}
197
198#[derive(Clone, Debug, Serialize, Deserialize)]
200pub struct NoExtracellularGradientSensing;
201
202impl<C, ConcGradientExtracellular> InteractionExtracellularGradient<C, ConcGradientExtracellular>
203 for NoExtracellularGradientSensing
204{
205 fn sense_gradient(
206 _cell: &mut C,
207 _extracellular_gradient: &ConcGradientExtracellular,
208 ) -> Result<(), CalcError> {
209 Ok(())
210 }
211}
212
213impl<Mec, Int, Cyc, React, IntExtracellular, ConcGradientExtracellular>
214 InteractionExtracellularGradient<
215 ModularCell<Mec, Int, Cyc, React, IntExtracellular>,
216 ConcGradientExtracellular,
217 > for ModularCell<Mec, Int, Cyc, React, IntExtracellular>
218where
219 IntExtracellular: InteractionExtracellularGradient<Self, ConcGradientExtracellular>,
220{
221 fn sense_gradient(
222 cell: &mut Self,
223 extracellular_gradient: &ConcGradientExtracellular,
224 ) -> Result<(), CalcError> {
225 IntExtracellular::sense_gradient(cell, extracellular_gradient)
226 }
227}