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