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
97
98 KOKKOS_INLINE_FUNCTION static double mass(std::size_t idx,
99 const SelfParticle& arr)
100 {
101 return GET_PROPERTY(Self::particle_var::length) * lin_density;
102 }
103
104 static std::vector<std::string_view> names()
105 {
106 return {"age",
107 "length",
108 "nu1",
109 "nu2",
110 "nu_eff_1",
111 "nu_eff_2",
112 "a_p1",
113 "a_p2",
114 "a_p3",
115 "phi_o2",
116 "phi_g",
117 "phi_pts"};
118 }
119
120 static std::vector<std::size_t> get_number()
121 {
122 return {INDEX_FROM_ENUM(particle_var::age),
123 INDEX_FROM_ENUM(particle_var::length),
124 INDEX_FROM_ENUM(particle_var::nu1),
125 INDEX_FROM_ENUM(particle_var::nu2),
126 INDEX_FROM_ENUM(particle_var::nu_eff_1),
127 INDEX_FROM_ENUM(particle_var::nu_eff_2),
128 INDEX_FROM_ENUM(Uptakeparticle_var::ap_1),
129 INDEX_FROM_ENUM(Uptakeparticle_var::ap_2),
130 INDEX_FROM_ENUM(Uptakeparticle_var::ap_3),
131 INDEX_FROM_ENUM(particle_var::contrib_phi_o2),
132 INDEX_FROM_ENUM(particle_var::contrib_phi_s),
133 INDEX_FROM_ENUM(particle_var::phi_pts)};
134 }
135
136 static KOKKOS_INLINE_FUNCTION void preinit()
137 {
138 Kokkos::printf("[Model]: PRENINIT:BEGIN\r\n");
139 // Kokkos::printf("[Model]: phi_max:%.12f\r\n", phi_pts_max * 1e12);
140 // Kokkos::printf("[Model]: PRENINIT:END\r\n");
141 }
142
143 KOKKOS_INLINE_FUNCTION static void init(const MC::pool_type& random_pool,
144 std::size_t idx,
145 const SelfParticle& arr);
146
147 KOKKOS_INLINE_FUNCTION static MC::Status
148 update(const MC::pool_type& random_pool,
149 FloatType d_t,
150 std::size_t idx,
151 const SelfParticle& arr,
152 const MC::LocalConcentration& c);
153
154 KOKKOS_INLINE_FUNCTION static void
155 division(const MC::pool_type& random_pool,
156 std::size_t idx,
157 std::size_t idx2,
158 const SelfParticle& arr,
159 const SelfParticle& buffer_arr);
160
161 KOKKOS_INLINE_FUNCTION static void
162 contribution(std::size_t idx,
163 std::size_t position,
164 double weight,
165 const SelfParticle& arr,
166 const MC::ContributionView& contributions);
167 };
168
169 CHECK_MODEL(TwoMetaNb)
170
171 KOKKOS_INLINE_FUNCTION void
172 TwoMetaNb::init([[maybe_unused]] const MC::pool_type& random_pool,
173 std::size_t idx,
174 const SelfParticle& arr)
175 {
176
177 // auto& v = init_uptake_cst;
178 constexpr auto local_ac = adder_dist;
179
180 constexpr auto length_dist = MC::Distributions::TruncatedNormal<FloatType>(
181 l_c_m / 2, l_c_m / 5., l_min_m, l_max_m);
182
183 constexpr auto mu_nu_dist = nu_max_kg_s * 0.1;
184 constexpr auto nu_1_initial_dist =
186 mu_nu_dist, mu_nu_dist / 7., 0., static_cast<double>(nu_max_kg_s));
187
188 auto gen = random_pool.get_state();
189 auto l = length_dist.draw(gen);
190
191 GET_PROPERTY(Self::particle_var::length) = l;
192 GET_PROPERTY(Self::particle_var::l_cp) = l + local_ac.draw(gen);
193 GET_PROPERTY(particle_var::nu1) = nu_1_initial_dist.draw(gen);
194 random_pool.free_state(gen);
195 GET_PROPERTY(particle_var::contrib_phi_s) = 0;
196
197 Uptake<Self>::init(random_pool, idx, arr);
198 }
199
200 KOKKOS_INLINE_FUNCTION MC::Status
201 TwoMetaNb::update([[maybe_unused]] const MC::pool_type& random_pool,
202 FloatType d_t,
203 std::size_t idx,
204 const SelfParticle& arr,
205 const MC::LocalConcentration& concentrations)
206 {
207 const auto phi_s =
209 d_t,
210 idx,
211 arr,
212 concentrations,
213 &GET_PROPERTY(Self::particle_var::phi_pts));
214
215 const auto o = Kokkos::max(static_cast<FloatType>(concentrations(1)), 0.F);
216
217 const auto phi_o2 = (phi_o2_max)*o / (o + k_o); // gO2/s
218
219 const auto nu_1_star =
221 Kokkos::min(phi_s / MolarMassG,
222 phi_o2 / MolarMassO2 / y_os_molar); // gX/s
223
224 const auto s_1_star = (1.F / y_sx_1 * nu_1_star);
225
226 const auto phi_s_residual_1_star = Kokkos::max(phi_s - s_1_star, 0.F);
227 KOKKOS_ASSERT(phi_s_residual_1_star >= 0.F);
228
229 const auto nu_2_star = y_sx_2 * phi_s_residual_1_star; // gX/s
230
231 auto& nu_eff_1 = GET_PROPERTY(Self::particle_var::nu_eff_1);
232 auto& nu_eff_2 = GET_PROPERTY(Self::particle_var::nu_eff_2);
233 auto& nu_1 = GET_PROPERTY(Self::particle_var::nu1);
234 auto& nu_2 = GET_PROPERTY(Self::particle_var::nu2);
235
236 nu_eff_1 = Kokkos::min(nu_1_star, nu_1); // gX/s
237
238 const auto s_1 = (1.F / y_sx_1 * nu_eff_1);
239 const auto phi_s_residual_1 = Kokkos::max(phi_s - s_1, 0.F);
240
241 nu_eff_2 = Kokkos::min(y_sx_2 * phi_s_residual_1,
242 nu_2); // gX/s
243
244 const auto sum_nu = (nu_eff_1 + nu_eff_2);
245
246 const auto s_growth = s_1 + (1 / y_sx_2 * nu_eff_2);
247
248 const auto s_overflow = phi_s - s_growth;
249
250 KOKKOS_ASSERT(nu_eff_1 >= 0.F);
251 KOKKOS_ASSERT(nu_eff_2 >= 0.F);
252
253 // CONTRIBS
254 GET_PROPERTY(Self::particle_var::contrib_phi_s) = -phi_s;
256 -1.F *
258 0.F * nu_eff_2);
259
261 nu_eff_2 / y_sx_2 * y_sa + (s_overflow > 0. ? y_sa * (s_overflow) : 0);
262
263 // ODE
264 nu_1 += d_t * ((nu_1_star - nu_1) / tau_1);
265
266 nu_2 += d_t * ((nu_2_star - nu_2) / tau_2);
267
268 GET_PROPERTY(Self::particle_var::length) += d_t * (sum_nu / lin_density);
269
270 GET_PROPERTY(Self::particle_var::age) += d_t;
271
272 return (GET_PROPERTY(Self::particle_var::length) >
273 GET_PROPERTY(Self::particle_var::l_cp))
276 }
277
278 KOKKOS_INLINE_FUNCTION void
280 std::size_t idx,
281 std::size_t idx2,
282 const SelfParticle& arr,
283 const SelfParticle& child_buffer_arr)
284 {
285 constexpr FloatType half = 0.5;
286 constexpr auto local_ac = adder_dist;
287 const FloatType new_current_length =
288 GET_PROPERTY(particle_var::length) / static_cast<FloatType>(2.);
289
290 GET_PROPERTY(Self::particle_var::length) = new_current_length;
291 GET_PROPERTY(Self::particle_var::age) = 0;
292
293 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::length) =
294 new_current_length;
295
296 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::age) = 0;
297
298 const auto nu_1_o =
299 GET_PROPERTY_FROM(idx, arr, Self::particle_var::nu_eff_1);
300 const auto nu_2_o =
301 GET_PROPERTY_FROM(idx, arr, Self::particle_var::nu_eff_2);
302
303 auto gen = random_pool.get_state();
304
305 GET_PROPERTY(Self::particle_var::l_cp) =
306 new_current_length + local_ac.draw(gen);
307
308 if (nu_1_o != 0)
309 {
310 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::nu1) =
312 gen, nu_1_o, nu_1_o * half, 0.F, 1.F);
313 }
314
315 if (nu_2_o != 0)
316 {
317 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::nu2) =
319 gen, nu_2_o, nu_2_o * half, 0.F, 1.F);
320 }
321
322 GET_PROPERTY_FROM(idx2, child_buffer_arr, Self::particle_var::l_cp) =
323 new_current_length + local_ac.draw(gen);
324 random_pool.free_state(gen);
325
326 Uptake<Self>::division(random_pool, idx, idx2, arr, child_buffer_arr);
327 }
328
330 {
331 const int begin = INDEX_FROM_ENUM(Self::particle_var::contrib_phi_s);
332 const int end = INDEX_FROM_ENUM(Self::particle_var::contrib_phi_ac);
333 assert(begin < end);
334 return {.begin = begin, .end = end};
335 }
336 // KOKKOS_INLINE_FUNCTION void
337 // TwoMetaNb::contribution([[maybe_unused]] std::size_t idx,
338 // std::size_t position,
339 // double weight,
340 // [[maybe_unused]] const SelfParticle& arr,
341 // const MC::ContributionView& contributions)
342 // {
343 // auto access = contributions.access();
344 // access(0, position) +=
345 // weight * GET_PROPERTY(Self::particle_var::contrib_phi_s); // NOLINT
346 // access(1, position) +=
347 // weight * GET_PROPERTY(Self::particle_var::contrib_phi_o2); // NOLINT
348 // access(2, position) +=
349 // weight * GET_PROPERTY(Self::particle_var::contrib_phi_ac); // NOLINT
350 // }
351
352 static_assert(HasExportProperties<TwoMetaNb>, "ee");
353
354} // namespace Models
355
356#endif //__TWOMETA_MODEL_NB_HPP__
Model that can export properties.
Definition traits.hpp:165
Status
Definition alias.hpp:57
@ Division
Definition alias.hpp:59
@ Idle
Definition alias.hpp:58
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:38
decltype(Kokkos::Experimental::create_scatter_view(kernelContribution())) ContributionView
Definition alias.hpp:87
Kokkos::Subview< KernelConcentrationType, int, decltype(Kokkos::ALL)> LocalConcentration
Definition alias.hpp:95
Kokkos::View< F *[Nd], Kokkos::LayoutRight > ParticlesModel
Definition alias.hpp:18
constexpr T glucose
Definition utils.hpp:28
constexpr T dioxygen
Definition utils.hpp:29
Models definition.
Definition config_loader.hpp:9
KOKKOS_INLINE_FUNCTION consteval F c_linear_density(F rho, F d)
Definition utils.hpp:47
Definition alias.hpp:65
Represents a TruncatedNormal (Gaussian) probability distribution.
Definition prng_extension.hpp:338
static KOKKOS_INLINE_FUNCTION F draw_from(Kokkos::Random_XorShift1024< DeviceType > &gen, F mu, F sigma, F lower, F upper)
Definition prng_extension.hpp:364
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
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:120
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 double mass(std::size_t idx, const SelfParticle &arr)
Definition two_meta_nb.hpp:98
static std::vector< std::string_view > names()
Definition two_meta_nb.hpp:104
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
static KOKKOS_INLINE_FUNCTION MC::Status update(const MC::pool_type &random_pool, FloatType d_t, std::size_t idx, const SelfParticle &arr, const MC::LocalConcentration &c)
Definition two_meta_nb.hpp:201
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 division(const MC::pool_type &random_pool, std::size_t idx, std::size_t idx2, const SelfParticle &arr, const SelfParticle &buffer_arr)
Definition two_meta_nb.hpp:279
static KOKKOS_INLINE_FUNCTION void preinit()
Definition two_meta_nb.hpp:136
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
static KOKKOS_INLINE_FUNCTION void init(const MC::pool_type &random_pool, std::size_t idx, const SelfParticle &arr)
Definition two_meta_nb.hpp:172
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:34
@ COUNT
Definition two_meta_nb.hpp:36
@ phi_pts
Definition two_meta_nb.hpp:32
@ 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:35
@ 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:33
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
static KOKKOS_INLINE_FUNCTION void contribution(std::size_t idx, std::size_t position, double weight, const SelfParticle &arr, const MC::ContributionView &contributions)
MODEL_CONSTANT FloatType lin_density
Definition two_meta_nb.hpp:57
static MC::ContribIndexBounds get_bounds()
Definition two_meta_nb.hpp:329
static constexpr std::size_t n_var
Definition two_meta_nb.hpp:39
static KOKKOS_INLINE_FUNCTION void init(const MC::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
static KOKKOS_INLINE_FUNCTION void division(const MC::pool_type &random_pool, std::size_t idx, std::size_t idx2, const SelfParticle &arr, const SelfParticle &buffer_arr)
Definition uptake_dyn.hpp:219