BioCMAMC-ST
two_meta_nb.hpp
1#ifndef __TWOMETA_MODEL_NB_HPP__
2#define __TWOMETA_MODEL_NB_HPP__
3
4#include <common/traits.hpp>
5#include <mc/macros.hpp>
6#include <mc/prng/prng_extension.hpp>
7#include <mc/traits.hpp>
8#include <models/uptake_dyn.hpp>
9#include <models/utils.hpp>
10#include <string_view>
11
12namespace Models
13{
14
15 struct TwoMetaNb
16 {
17 using uniform_weight = std::true_type; // Using type alias
18 using Self = TwoMetaNb;
19 using FloatType = float;
20 using Config = std::nullopt_t;
21
22 enum class particle_var : int
23 {
24 age = INDEX_FROM_ENUM(Uptakeparticle_var::COUNT),
29 nu_eff_1, // This is not itself a model property but stored to be exported
30 nu_eff_2, // This is not itself a model property but stored to be exported
31 // TODO FIND BETTER WAY TO STORE/GET CONTRIBUTIONS
37 };
38
39 static constexpr std::size_t n_var = INDEX_FROM_ENUM(particle_var::COUNT);
40 static constexpr std::string_view name = "two_mode_nb";
42
43 // Constants BEGIN
44 MODEL_CONSTANT FloatType MolarMassG =
46 MODEL_CONSTANT FloatType MolarMassO2 =
48
49 MODEL_CONSTANT FloatType l_max_m = 5e-6; // m
50 MODEL_CONSTANT FloatType l_c_m = 3e-6; // m
51 MODEL_CONSTANT FloatType d_m = 0.3e-6; // m
52 MODEL_CONSTANT FloatType l_min_m = 0.9e-6; // m
53
54 MODEL_CONSTANT FloatType dl_max_ms =
55 10 * 2e-10; // m/s https://doi.org/10.7554/eLife.67495;
56
57 MODEL_CONSTANT FloatType lin_density =
58 c_linear_density(static_cast<FloatType>(1000), d_m);
59
60 MODEL_CONSTANT FloatType y_sx_1 =
61 1. / 2.217737e+00; // Mode 1 S to X yield (mass)
62 MODEL_CONSTANT FloatType y_sx_2 = y_sx_1 / 3.; // Mode 2 S to X yield (mass)
63 MODEL_CONSTANT FloatType y_sa = 0.8; // S to A yield (mass)
64 MODEL_CONSTANT FloatType y_os_molar = 3; // 3 mol o2 per mol for glucose
65
66 MODEL_CONSTANT FloatType tau_1 = 1000.; // s
67 MODEL_CONSTANT FloatType tau_2 = 1000.; // s
68
70 MODEL_CONSTANT FloatType phi_o2_max =
71 10 * phi_max / MolarMassG * y_os_molar * MolarMassO2; // kgS/s
73
74 MODEL_CONSTANT FloatType k_o =
75 0.0001; // g/L: Anane et. al 2017 (Biochem. Eng. J) (g/g)
76 MODEL_CONSTANT FloatType k = 1e-2;
77 MODEL_CONSTANT FloatType k_perm = 1e-3;
78 MODEL_CONSTANT FloatType beta = 7;
79 MODEL_CONSTANT FloatType tau_ap_1 = 300;
80 MODEL_CONSTANT FloatType tau_ap_2 = 200;
81 MODEL_CONSTANT FloatType tau_ap_3 = 1000;
82
83 MODEL_CONSTANT auto length_c_dist =
85 l_c_m, l_c_m / 2., l_min_m, l_max_m); // use in out_str_l3
86
87 MODEL_CONSTANT FloatType adder_mean = 1.5e-6; // m
88 MODEL_CONSTANT auto adder_dist =
91 adder_mean / 2.,
92 adder_mean / 20.,
93 adder_mean * 10); // use in out_str_l3
94 // Constants END
95
96 KOKKOS_INLINE_FUNCTION static double mass(std::size_t idx,
97 const SelfParticle& arr)
98 {
99 return GET_PROPERTY(Self::particle_var::length) * lin_density;
100 }
101
102 static std::vector<std::string_view> names()
103 {
104 return {"age",
105 "length",
106 "nu1",
107 "nu2",
108 "nu_eff_1",
109 "nu_eff_2",
110 "a_p1",
111 "a_p2",
112 "a_p3",
113 "phi_o2",
114 "phi_g",
115 "phi_pts"};
116 }
117
118 static std::vector<std::size_t> get_number()
119 {
120 return {INDEX_FROM_ENUM(particle_var::age),
121 INDEX_FROM_ENUM(particle_var::length),
122 INDEX_FROM_ENUM(particle_var::nu1),
123 INDEX_FROM_ENUM(particle_var::nu2),
124 INDEX_FROM_ENUM(particle_var::nu_eff_1),
125 INDEX_FROM_ENUM(particle_var::nu_eff_2),
126 INDEX_FROM_ENUM(Uptakeparticle_var::ap_1),
127 INDEX_FROM_ENUM(Uptakeparticle_var::ap_2),
128 INDEX_FROM_ENUM(Uptakeparticle_var::ap_3),
129 INDEX_FROM_ENUM(particle_var::contrib_phi_o2),
130 INDEX_FROM_ENUM(particle_var::contrib_phi_s),
131 INDEX_FROM_ENUM(particle_var::phi_pts)};
132 }
133
134 static KOKKOS_INLINE_FUNCTION void preinit()
135 {
136 Kokkos::printf("[Model]: PRENINIT:BEGIN\r\n");
137 // Kokkos::printf("[Model]: phi_max:%.12f\r\n", phi_pts_max * 1e12);
138 // Kokkos::printf("[Model]: PRENINIT:END\r\n");
139 }
140
141 KOKKOS_INLINE_FUNCTION static void
142 init(const MC::KPRNG::pool_type& random_pool,
143 std::size_t idx,
144 const SelfParticle& arr);
145
146 KOKKOS_INLINE_FUNCTION static MC::Status
147 update(const MC::KPRNG::pool_type& random_pool,
148 FloatType d_t,
149 std::size_t idx,
150 const SelfParticle& arr,
151 const MC::LocalConcentration& c);
152
153 KOKKOS_INLINE_FUNCTION static void
154 division(const MC::KPRNG::pool_type& random_pool,
155 std::size_t idx,
156 std::size_t idx2,
157 const SelfParticle& arr,
158 const SelfParticle& buffer_arr);
159
160 KOKKOS_INLINE_FUNCTION static void
161 contribution(std::size_t idx,
162 std::size_t position,
163 double weight,
164 const SelfParticle& arr,
165 const MC::ContributionView& contributions);
166 };
167
168 CHECK_MODEL(TwoMetaNb)
169
170 KOKKOS_INLINE_FUNCTION void
171 TwoMetaNb::init([[maybe_unused]] const MC::KPRNG::pool_type& random_pool,
172 std::size_t idx,
173 const SelfParticle& arr)
174 {
175
176 // auto& v = init_uptake_cst;
177 constexpr auto local_ac = adder_dist;
178
179 constexpr auto length_dist = MC::Distributions::TruncatedNormal<FloatType>(
180 l_c_m / 2, l_c_m / 5., l_min_m, l_max_m);
181
182 constexpr auto mu_nu_dist = nu_max_kg_s * 0.1;
183 constexpr auto nu_1_initial_dist =
185 mu_nu_dist, mu_nu_dist / 7., 0., static_cast<double>(nu_max_kg_s));
186
187 auto gen = random_pool.get_state();
188 auto l = length_dist.draw(gen);
189
190 GET_PROPERTY(Self::particle_var::length) = l;
191 GET_PROPERTY(Self::particle_var::l_cp) = l + local_ac.draw(gen);
192 GET_PROPERTY(particle_var::nu1) = nu_1_initial_dist.draw(gen);
193 random_pool.free_state(gen);
194 GET_PROPERTY(particle_var::contrib_phi_s) = 0;
195
196 Uptake<Self>::init(random_pool, idx, arr);
197 }
198
199 KOKKOS_INLINE_FUNCTION MC::Status
200 TwoMetaNb::update([[maybe_unused]] const MC::KPRNG::pool_type& random_pool,
201 FloatType d_t,
202 std::size_t idx,
203 const SelfParticle& arr,
204 const MC::LocalConcentration& concentrations)
205 {
206 const auto phi_s =
208 d_t,
209 idx,
210 arr,
211 concentrations,
212 &GET_PROPERTY(Self::particle_var::phi_pts));
213
214 const auto o = Kokkos::max(static_cast<FloatType>(concentrations(1)), 0.F);
215
216 const auto phi_o2 = (phi_o2_max)*o / (o + k_o); // gO2/s
217
218 const auto nu_1_star =
220 Kokkos::min(phi_s / MolarMassG,
221 phi_o2 / MolarMassO2 / y_os_molar); // gX/s
222
223 const auto s_1_star = (1.F / y_sx_1 * nu_1_star);
224
225 const auto phi_s_residual_1_star = Kokkos::max(phi_s - s_1_star, 0.F);
226 KOKKOS_ASSERT(phi_s_residual_1_star >= 0.F);
227
228 const auto nu_2_star = y_sx_2 * phi_s_residual_1_star; // gX/s
229
230 auto& nu_eff_1 = GET_PROPERTY(Self::particle_var::nu_eff_1);
231 auto& nu_eff_2 = GET_PROPERTY(Self::particle_var::nu_eff_2);
232 auto& nu_1 = GET_PROPERTY(Self::particle_var::nu1);
233 auto& nu_2 = GET_PROPERTY(Self::particle_var::nu2);
234
235 nu_eff_1 = Kokkos::min(nu_1_star, nu_1); // gX/s
236
237 const auto s_1 = (1.F / y_sx_1 * nu_eff_1);
238 const auto phi_s_residual_1 = Kokkos::max(phi_s - s_1, 0.F);
239
240 nu_eff_2 = Kokkos::min(y_sx_2 * phi_s_residual_1,
241 nu_2); // gX/s
242
243 const auto sum_nu = (nu_eff_1 + nu_eff_2);
244
245 const auto s_growth = s_1 + (1 / y_sx_2 * nu_eff_2);
246
247 const auto s_overflow = phi_s - s_growth;
248
249 KOKKOS_ASSERT(nu_eff_1 >= 0.F);
250 KOKKOS_ASSERT(nu_eff_2 >= 0.F);
251
252 // CONTRIBS
253 GET_PROPERTY(Self::particle_var::contrib_phi_s) = -phi_s;
255 -1.F *
257 0.F * nu_eff_2);
258
260 nu_eff_2 / y_sx_2 * y_sa + (s_overflow > 0. ? y_sa * (s_overflow) : 0);
261
262 // ODE
263 nu_1 += d_t * ((nu_1_star - nu_1) / tau_1);
264
265 nu_2 += d_t * ((nu_2_star - nu_2) / tau_2);
266
267 GET_PROPERTY(Self::particle_var::length) += d_t * (sum_nu / lin_density);
268
269 GET_PROPERTY(Self::particle_var::age) += d_t;
270
271 return (GET_PROPERTY(Self::particle_var::length) >
272 GET_PROPERTY(Self::particle_var::l_cp))
275 }
276
277 KOKKOS_INLINE_FUNCTION void
279 std::size_t idx,
280 std::size_t idx2,
281 const SelfParticle& arr,
282 const SelfParticle& child_buffer_arr)
283 {
284 constexpr FloatType half = 0.5;
285 constexpr auto local_ac = adder_dist;
286 const FloatType new_current_length =
287 GET_PROPERTY(particle_var::length) / static_cast<FloatType>(2.);
288
289 GET_PROPERTY(Self::particle_var::length) = new_current_length;
290 GET_PROPERTY(Self::particle_var::age) = 0;
291
292 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::length) =
293 new_current_length;
294
295 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::age) = 0;
296
297 const auto nu_1_o =
298 GET_PROPERTY_FROM(idx, arr, Self::particle_var::nu_eff_1);
299 const auto nu_2_o =
300 GET_PROPERTY_FROM(idx, arr, Self::particle_var::nu_eff_2);
301
302 auto gen = random_pool.get_state();
303
304 GET_PROPERTY(Self::particle_var::l_cp) =
305 new_current_length + local_ac.draw(gen);
306
307 if (nu_1_o != 0)
308 {
309 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::nu1) =
311 gen, nu_1_o, nu_1_o * half, 0.F, 1.F);
312 }
313
314 if (nu_2_o != 0)
315 {
316 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::nu2) =
318 gen, nu_2_o, nu_2_o * half, 0.F, 1.F);
319 }
320
321 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::l_cp) =
322 new_current_length + local_ac.draw(gen);
323 random_pool.free_state(gen);
324
325 Uptake<Self>::division(random_pool, idx, idx2, arr, child_buffer_arr);
326 }
327
328 KOKKOS_INLINE_FUNCTION void
329 TwoMetaNb::contribution([[maybe_unused]] std::size_t idx,
330 std::size_t position,
331 double weight,
332 [[maybe_unused]] const SelfParticle& arr,
333 const MC::ContributionView& contributions)
334 {
335 auto access = contributions.access();
336 access(0, position) +=
337 weight * GET_PROPERTY(Self::particle_var::contrib_phi_s); // NOLINT
338 access(1, position) +=
339 weight * GET_PROPERTY(Self::particle_var::contrib_phi_o2); // NOLINT
340 access(2, position) +=
341 weight * GET_PROPERTY(Self::particle_var::contrib_phi_ac); // NOLINT
342 }
343
344 static_assert(HasExportProperties<TwoMetaNb>, "ee");
345
346} // namespace Models
347
348#endif //__TWOMETA_MODEL_NB_HPP__
Kokkos::Random_XorShift1024_Pool< Kokkos::DefaultExecutionSpace > pool_type
Definition prng.hpp:17
Model that can export properties.
Definition traits.hpp:159
Kokkos::Subview< KernelConcentrationType, int, decltype(Kokkos::ALL)> LocalConcentration
Definition alias.hpp:42
Kokkos::Experimental::ScatterView< double **, Kokkos::LayoutRight > ContributionView
Definition alias.hpp:31
Kokkos::View< F *[Nd]> ParticlesModel
Definition traits.hpp:34
Status
Definition alias.hpp:11
@ Division
Definition alias.hpp:13
@ Idle
Definition alias.hpp:12
constexpr T glucose
Definition utils.hpp:21
constexpr T dioxygen
Definition utils.hpp:22
Models definition.
Definition config_loader.hpp:8
KOKKOS_INLINE_FUNCTION consteval F c_linear_density(F rho, F d)
Definition utils.hpp:40
Represents a TruncatedNormal (Gaussian) probability distribution.
Definition prng_extension.hpp:263
static KOKKOS_INLINE_FUNCTION F draw_from(Kokkos::Random_XorShift1024< DeviceType > &gen, F mu, F sigma, F lower, F upper)
Definition prng_extension.hpp:287
Definition two_meta_nb.hpp:16
std::nullopt_t Config
Definition two_meta_nb.hpp:20
MODEL_CONSTANT FloatType y_os_molar
Definition two_meta_nb.hpp:64
MODEL_CONSTANT FloatType y_sa
Definition two_meta_nb.hpp:63
static KOKKOS_INLINE_FUNCTION void contribution(std::size_t idx, std::size_t position, double weight, const SelfParticle &arr, const MC::ContributionView &contributions)
Definition two_meta_nb.hpp:329
MODEL_CONSTANT FloatType k
Definition two_meta_nb.hpp:76
MODEL_CONSTANT FloatType y_sx_1
Definition two_meta_nb.hpp:60
static std::vector< std::size_t > get_number()
Definition two_meta_nb.hpp:118
MODEL_CONSTANT auto adder_dist
Definition two_meta_nb.hpp:88
std::true_type uniform_weight
Definition two_meta_nb.hpp:17
MODEL_CONSTANT FloatType y_sx_2
Definition two_meta_nb.hpp:62
static KOKKOS_INLINE_FUNCTION void division(const MC::KPRNG::pool_type &random_pool, std::size_t idx, std::size_t idx2, const SelfParticle &arr, const SelfParticle &buffer_arr)
Definition two_meta_nb.hpp:278
static KOKKOS_INLINE_FUNCTION double mass(std::size_t idx, const SelfParticle &arr)
Definition two_meta_nb.hpp:96
static std::vector< std::string_view > names()
Definition two_meta_nb.hpp:102
MC::ParticlesModel< Self::n_var, Self::FloatType > SelfParticle
Definition two_meta_nb.hpp:41
static constexpr std::string_view name
Definition two_meta_nb.hpp:40
MODEL_CONSTANT FloatType tau_ap_2
Definition two_meta_nb.hpp:80
MODEL_CONSTANT FloatType tau_1
Definition two_meta_nb.hpp:66
MODEL_CONSTANT FloatType l_min_m
Definition two_meta_nb.hpp:52
MODEL_CONSTANT FloatType l_c_m
Definition two_meta_nb.hpp:50
static KOKKOS_INLINE_FUNCTION void preinit()
Definition two_meta_nb.hpp:134
MODEL_CONSTANT FloatType d_m
Definition two_meta_nb.hpp:51
MODEL_CONSTANT FloatType nu_max_kg_s
Definition two_meta_nb.hpp:72
MODEL_CONSTANT FloatType phi_max
Definition two_meta_nb.hpp:69
MODEL_CONSTANT FloatType MolarMassO2
Definition two_meta_nb.hpp:46
MODEL_CONSTANT FloatType phi_o2_max
Definition two_meta_nb.hpp:70
MODEL_CONSTANT FloatType dl_max_ms
Definition two_meta_nb.hpp:54
MODEL_CONSTANT FloatType adder_mean
Definition two_meta_nb.hpp:87
MODEL_CONSTANT FloatType tau_2
Definition two_meta_nb.hpp:67
MODEL_CONSTANT FloatType tau_ap_1
Definition two_meta_nb.hpp:79
particle_var
Definition two_meta_nb.hpp:23
@ nu2
Definition two_meta_nb.hpp:27
@ length
Definition two_meta_nb.hpp:25
@ contrib_phi_o2
Definition two_meta_nb.hpp:33
@ COUNT
Definition two_meta_nb.hpp:36
@ phi_pts
Definition two_meta_nb.hpp:35
@ age
Definition two_meta_nb.hpp:24
@ nu1
Definition two_meta_nb.hpp:26
@ nu_eff_1
Definition two_meta_nb.hpp:29
@ contrib_phi_ac
Definition two_meta_nb.hpp:34
@ l_cp
Definition two_meta_nb.hpp:28
@ nu_eff_2
Definition two_meta_nb.hpp:30
@ contrib_phi_s
Definition two_meta_nb.hpp:32
MODEL_CONSTANT FloatType beta
Definition two_meta_nb.hpp:78
MODEL_CONSTANT FloatType tau_ap_3
Definition two_meta_nb.hpp:81
MODEL_CONSTANT FloatType MolarMassG
Definition two_meta_nb.hpp:44
float FloatType
Definition two_meta_nb.hpp:19
MODEL_CONSTANT FloatType k_o
Definition two_meta_nb.hpp:74
TwoMetaNb Self
Definition two_meta_nb.hpp:18
MODEL_CONSTANT FloatType l_max_m
Definition two_meta_nb.hpp:49
MODEL_CONSTANT auto length_c_dist
Definition two_meta_nb.hpp:83
MODEL_CONSTANT FloatType k_perm
Definition two_meta_nb.hpp:77
MODEL_CONSTANT FloatType lin_density
Definition two_meta_nb.hpp:57
static KOKKOS_INLINE_FUNCTION MC::Status update(const MC::KPRNG::pool_type &random_pool, FloatType d_t, std::size_t idx, const SelfParticle &arr, const MC::LocalConcentration &c)
Definition two_meta_nb.hpp:200
static KOKKOS_INLINE_FUNCTION void init(const MC::KPRNG::pool_type &random_pool, std::size_t idx, const SelfParticle &arr)
Definition two_meta_nb.hpp:171
static constexpr std::size_t n_var
Definition two_meta_nb.hpp:39
static KOKKOS_INLINE_FUNCTION void division(const MC::KPRNG::pool_type &random_pool, std::size_t idx, std::size_t idx2, const SelfParticle &arr, const SelfParticle &buffer_arr)
Definition uptake_dyn.hpp:219
static KOKKOS_INLINE_FUNCTION void init(const MC::KPRNG::pool_type &random_pool, std::size_t idx, const SelfParticle &arr)
Definition uptake_dyn.hpp:105
static KOKKOS_INLINE_FUNCTION FloatType uptake_step(FloatType phi_max, FloatType d_t, std::size_t idx, const SelfParticle &arr, const MC::LocalConcentration &c, FloatType *r_phi_pts=nullptr, FloatType *r_phi_perm=nullptr)
Definition uptake_dyn.hpp:171