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