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