BioCMAMC-ST
old_model_ecoli.hpp
1// #ifndef __BIO_MODEL_UPTAKE_ACETATE_HPP__
2// #define __BIO_MODEL_UPTAKE_ACETATE_HPP__
3
4// #include "mc/prng/prng.hpp"
5// #include <Kokkos_Core.hpp>
6
7// #include <mc/particles/particle_model.hpp>
8
9// #include <models/utils.hpp>
10// #include <numbers>
11
12// namespace implEcoli
13// {
14
15// #define MONOD_RATIO(__c1__, __x1__, __k1__) ((__c1__) * (__x1__) / ((__x1__)
16// + (__k1__)))
17
18// #define _INDICES(__name__) static_cast<std::size_t>(Indices::__name__)
19
20// struct Yields
21// {
22
23// static constexpr double Y_EG = 12.05; // mol_E/mol_G
24// static constexpr double Y_XG = 1.15; // mol_X/mol_G
25// static constexpr double m = 250; // µmol_G/g_X.h
26// static constexpr double Y_OG = 6.; // mol_O/mol_G
27// static constexpr double Yo_EG = 20.; // mol_E/mol_G
28// static constexpr double Yf_EG = 3.; // mol_E/mol_G
29// static constexpr double Y_AG = 1.5; // mol_A/mol_G (modified for CO2
30// production)
31// // static constexpr double Y_CO2G_over = 2.; // mol_CO2/mol_G (overflow
32// metabolism) not used
33
34// static constexpr double Y_EA = 12.05 / 3.; // mol_E/mol_A
35// static constexpr double Y_XA = 0.4; // mol_X/mol_A
36// static constexpr double Y_OA = 2.; // mol_O/mol_A
37// static constexpr double Yo_EA = 4.67; // mol_E/mol_A
38// static constexpr double x_s = 1.15; // 2.;
39
40// static constexpr double nu_s_x = Models::MolarMass::glucose /
41// Models::MolarMass::X *
42// (Yields::Y_EG + Yields::Yo_EG) /
43// (Yields::Y_XG * Yields::Yo_EG);
44// };
45
46// // All in seconds
47// struct Tau
48// {
49// static constexpr double new_permease = 40.;
50// static constexpr double tau_rm_perm = 200.;
51// static constexpr double pts = 20.;
52// static constexpr double Au = 40.;
53// static constexpr double Ad = 5.;
54// };
55
56// constexpr double l_1 = 4e-6;
57// constexpr double l_0 = 3e-6;
58// constexpr double d_m = l_0 / 5.;
59// constexpr double minimal_length = d_m * 1.4;
60// constexpr double factor = 1000. * 3.14 * d_m * d_m / 4.;
61// static_assert(l_0 < l_1, "Length");
62
63// consteval double f_num_max()
64// {
65// return l_0 * std::numbers::ln2 / 3600.; // NOLINT
66// }
67
68// consteval double f_phi_pts_max(double nu_m)
69// {
70// return nu_m * Yields::x_s * factor;
71// }
72
73// constexpr double nu_max = f_num_max(); // m/s
74
75// constexpr double phi_pts_max = f_phi_pts_max(nu_max);
76// constexpr double phi_o2_max = 15.6 / 3600; // mol0/gx/s
77// constexpr double phi_a_max = phi_pts_max / 3.; // mola/kgx/s
78// constexpr double k_pts = 1e-3;
79// constexpr double kppermease = 1e-2;
80// constexpr double phi_permease_specific = phi_pts_max / 40.;
81
82// constexpr double psi_o_meta = 20e-3 / 3600 * 32e-3; // 20mmmol O2 /h;
83// constexpr double tau_metabolism = 3600;
84
85// constexpr double NPermease_max = 200;
86// constexpr double NPermease_init = 1.;
87
88// KOKKOS_INLINE_FUNCTION double phi_pts(double a_pts, double S)
89// {
90// return a_pts * MONOD_RATIO(phi_pts_max, S, k_pts);
91// }
92
93// KOKKOS_INLINE_FUNCTION double phi_permease(double n_permease, double
94// a_permease, double S)
95// {
96// return a_permease * MONOD_RATIO(n_permease * phi_permease_specific, S,
97// kppermease);
98// }
99// // static_assert(NPermease_max * phi_permease_specific == 5. * phi_pts_max,
100// "pts/perm");
101
102// } // namespace implEcoli
103
104// namespace Models
105// {
106
107// struct Ecoli
108// {
109
110// using PhiUptakes = struct Contribs
111// {
112// double glucose;
113// double acetate;
114// double oxygen;
115// };
116
117// struct Rates
118// {
119// double glucose;
120// double acetate;
121// double oxygen;
122// double carbon_dioxide;
123// double nu;
124// };
125
126// static constexpr std::size_t n_meta = 5;
127
128// enum class Indices : std::size_t
129// {
130// NU = 4,
131// GLUCOSE = 0,
132// O2 = 1,
133// Ac = 2,
134// CO2 = 3
135// };
136
137// double length;
138// double nu;
139// double a_pts;
140// double a_permease;
141// double n_permease;
142// Rates rates;
143// PhiUptakes phi_uptakes;
144
145// KOKKOS_FUNCTION void init(MC::ParticleDataHolder& p, MC::KPRNG _rng)
146// {
147
148// using namespace implEcoli;
149// constexpr double local_l = minimal_length;
150// auto generator = _rng.random_pool.get_state();
151
152// this->length =
153// Kokkos::max(local_l, Kokkos::max(generator.normal(l_0 / 1.5, l_0
154// / 1.5 / 5.), 0.));
155// this->a_permease = Kokkos::max(generator.normal(1e-3, 1e-4), 0.);
156// this->a_pts = Kokkos::min(1., Kokkos::max(generator.normal(0.8, 0.1),
157// 0.)); this->n_permease =
158// Kokkos::max(generator.normal(NPermease_init / 2., NPermease_init
159// / 5.), 0.);
160
161// this->nu =
162// nu_max; // Kokkos::max(generator.normal(nu_max / 2., nu_max / 2.
163// / 5.), 0.) / length;
164// _rng.random_pool.free_state(generator);
165// }
166
167// KOKKOS_FUNCTION void metabolism()
168// {
169// using namespace ::implEcoli;
170// // yield n for mode i, yields in mol/mol
171// // E: ATP/G:glucose/O:Oxygen/A:Acetate
172// constexpr double y1_b = (Yields::Y_EG + Yields::Yo_EG) / Yields::Yo_EG;
173// // None constexpr double y2_b =
174// (Yields::Y_EG + Yields::Yo_EG) /
175// (Yields::Y_EG * Yields::Y_OG); // G/O //To modify divide by YO_EG
176// not Y_Eg
177// constexpr double y1_c = (Yields::Y_EG + Yields::Yf_EG) / Yields::Yf_EG;
178// // None constexpr double y1_e = (Yields::Y_EA + Yields::Yo_EA) /
179// Yields::Yo_EA; // None constexpr double y2_e =
180// (Yields::Y_EA + Yields::Yo_EA) / (Yields::Yo_EA * Yields::Y_OA); //
181// A/O
182// constexpr double yield_mol_S_O =
183// 1.; // Number of mol of S from mole of O for mode D conversion
184
185// // Yield for specie for specifc mode: id oxygen mode b => y_o2_b
186// constexpr double y_o2_b = (Yields::Y_EG * Yields::Y_OG) / (Yields::Y_EG
187// + Yields::Yo_EG); constexpr double y_o2_e = (Yields::Y_EA *
188// Yields::Y_OA) / (Yields::Y_EA + Yields::Yo_EA); constexpr double y_ac_c
189// = (Yields::Y_AG * Yields::Y_EG) / (Yields::Y_EG + Yields::Yf_EG);
190// constexpr double y_x_b =
191// Yields::Y_XG * Yields::Yo_EG / (Yields::Y_EG + Yields::Yo_EG); //
192// Y_xg /y1_b
193// constexpr double y_x_c = Yields::Y_XG * Yields::Yf_EG / (Yields::Y_EG +
194// Yields::Yf_EG); constexpr double y_x_e = Yields::Y_XA * Yields::Yo_EA /
195// (Yields::Y_EA + Yields::Yo_EA);
196
197// constexpr double y_phi_o2_residual =
198// (Yields::Y_EG * Yields::Y_OG) / (Yields::Y_EG + Yields::Yo_EG); //
199// y2_bthe same
200
201// // Incoming for uptake mecanism
202// const auto [phi_s_in, phi_a_in, phi_o2_in] = phi_uptakes; // kg/s
203// const double current_mass = mass();
204
205// // Incomin in molee y2_b = (Yields::Y_EG + Yields::Yo_EG) /
206// (Yields::Y_EG * Yields::Y_OG); //
207// // G/O
208// const double phi_s_in_mol = phi_s_in / (current_mass *
209// MolarMass::glucose); // mol/s const double phi_a_in_mol = phi_a_in /
210// (current_mass * MolarMass::acetate); const double phi_o2_in_mol =
211// phi_o2_in;
212
213// // Maximum growth on oxidative (best yield)
214// const double r1_max = nu / MolarMass::X / Yields::x_s /
215// MolarMass::glucose; // molS/s
216// // Oxydative growth
217
218// const double phi_mode_b =
219// min_var(y1_b * r1_max, phi_s_in_mol, y2_b * phi_o2_in_mol); //
220// molS/s
221
222// double phi_s_residual = phi_s_in_mol - phi_mode_b; // molS/s
223
224// const double phi_o2_residual = phi_o2_in_mol - (y_phi_o2_residual *
225// phi_mode_b); // molO2/s
226
227// const double nu_residual =
228// ((Yields::Y_EG + Yields::Yo_EG) / Yields::Yo_EG * r1_max) -
229// phi_mode_b; // molS/s
230
231// const double phi_mode_c = min_var(y1_c * nu_residual, phi_s_residual);
232// // molS/s
233
234// phi_s_residual = phi_s_residual - phi_mode_c; // molS/s
235
236// const double phi_mode_d = min_var(phi_s_residual, yield_mol_S_O *
237// phi_o2_residual); // molS/s
238
239// const double phi_mode_e = min_var(y1_e * nu_residual, phi_a_in_mol,
240// y2_e * phi_o2_residual);
241
242// rates.glucose = -phi_s_in;
243// rates.oxygen = -current_mass * MolarMass::dioxygen *
244// (y_o2_b * phi_mode_b + y_o2_e * phi_mode_e +
245// phi_mode_d);
246
247// rates.acetate = current_mass * MolarMass::acetate *
248// (y_ac_c * phi_mode_c + Yields::Y_AG * phi_mode_d -
249// phi_mode_e);
250
251// rates.carbon_dioxide = -current_mass * MolarMass::co2 * (rates.oxygen /
252// MolarMass::dioxygen);
253
254// rates.nu = MolarMass::X * (y_x_b * phi_mode_b + y_x_c * phi_mode_c +
255// y_x_e * phi_mode_e);
256// }
257
258// KOKKOS_FUNCTION double uptake(const LocalConcentrationView&
259// concentration)
260// {
261// using namespace implEcoli;
262// const double s = Kokkos::max(0., concentration(_INDICES(GLUCOSE)));
263// const double phi_s_pts = phi_pts(a_pts, s);
264// const double gamma_PTS_S = phi_s_pts / phi_pts_max;
265// // const double micro_mixing = 0.3;
266
267// phi_uptakes.glucose = phi_s_pts + phi_permease(n_permease, a_permease,
268// s); phi_uptakes.acetate = phi_a_max * concentration(_INDICES(Ac)) / 1;
269// // 1 / micro_mixing * concentration(_INDICES(Ac)) / 1000.;
270
271// phi_uptakes.oxygen = phi_o2_max; //* concentration(_INDICES(O2)) /
272// 9e-3;
273// // 1 / micro_mixing *
274// concentration(_INDICES(O2)) / 1000.;
275// return gamma_PTS_S;
276// }
277
278// KOKKOS_FUNCTION void update(double d_t,
279// MC::ParticleDataHolder& p,
280// const LocalConcentrationView& concentration,
281// MC::KPRNG _rng)
282// {
283// using namespace implEcoli;
284// const double s = Kokkos::max(0., concentration(0));
285// const double gamma_PTS_S = uptake(concentration);
286// const double nu_p = phi_uptakes.glucose / mass() / (Yields::nu_s_x);
287
288// metabolism();
289// this->length += d_t * length * rates.nu;
290// this->nu += d_t * (1.0 / tau_metabolism) * (nu_p - this->nu);
291// this->a_pts += d_t * 1.0 / Tau::pts * (MONOD_RATIO(1., s, k_pts) -
292// this->a_pts); this->a_permease +=
293// d_t * (((1.0 / Tau::Au) * gamma_PTS_S + (1.0 / Tau::Ad) * (1.0 -
294// gamma_PTS_S)) *
295// (1.0 - gamma_PTS_S - a_permease));
296
297// this->n_permease += d_t *
298// (MONOD_RATIO(1. / Tau::new_permease, k_pts, s) +
299// MONOD_RATIO(1. / Tau::tau_rm_perm, s, k_pts)) *
300// (MONOD_RATIO(NPermease_max, k_pts, s) -
301// n_permease);
302
303// Models::update_division_status(
304// p.status, d_t, GammaDivision::threshold_linear(length, l_0, l_1),
305// _rng.random_pool);
306// }
307
308// KOKKOS_FUNCTION Ecoli division(MC::ParticleDataHolder& p, MC::KPRNG _rng)
309// {
310// using namespace implEcoli;
311// const double original_length = this->length;
312// const double original_n_permease = this->n_permease;
313// this->length = original_length / 2.;
314// this->n_permease = original_n_permease / 2;
315
316// auto child = *this;
317// // const bool mask = a_pts > a_permease;
318// // const double max_perm = mask ? a_pts : 1;
319// // const double max_pts = mask ? 1 : a_permease;
320
321// {
322// // auto generator = _rng.random_pool.get_state();
323// // child.a_pts =
324// // Kokkos::min(max_pts, Kokkos::max(generator.normal(this->a_pts,
325// this->a_pts / 2.),
326// // 0.));
327
328// // child.a_permease = Kokkos::min(
329// // max_perm, Kokkos::max(generator.normal(this->a_permease,
330// this->a_permease / 2.),
331// // 0.));
332
333// auto generator = _rng.random_pool.get_state();
334// child.a_pts =
335// Kokkos::min(1., Kokkos::max(generator.normal(this->a_pts,
336// this->a_pts / 2.), 0.));
337
338// child.a_permease = Kokkos::min(
339// 1., Kokkos::max(generator.normal(this->a_permease,
340// this->a_permease / 2.), 0.));
341
342// child.nu = Kokkos::max(generator.normal(this->nu, this->nu / 3.),
343// 0.); _rng.random_pool.free_state(generator);
344// }
345
346// return child;
347// }
348
349// KOKKOS_FUNCTION void contribution(MC::ParticleDataHolder& p,
350// const ContributionView& contribution)
351// {
352// using namespace implEcoli;
353// auto access_contribs = contribution.access();
354// access_contribs(_INDICES(GLUCOSE), p.current_container) +=
355// rates.glucose * p.weight;
356// // access_contribs(_INDICES(Ac), p.current_container) += rates.acetate
357// * p.weight;
358// // access_contribs(_INDICES(O2), p.current_container) += rates.oxygen *
359// p.weight;
360// // access_contribs(_INDICES(CO2), p.current_container) +=
361// rates.carbon_dioxide * p.weight;
362// }
363
364// [[nodiscard]] KOKKOS_FUNCTION double mass() const noexcept
365// {
366// using namespace implEcoli;
367// return implEcoli::factor * length;
368// }
369
370// template <class Archive> void serialize(Archive& ar)
371// {
372// ar(length, nu, a_pts, a_permease);
373// }
374
375// static std::vector<std::string> names()
376// {
377// return {"mass", "length", "nu_eff", "nu", "a_permease", "a_pts"};
378// }
379
380// KOKKOS_INLINE_FUNCTION static consteval std::size_t get_number()
381// {
382// return 6;
383// }
384
385// KOKKOS_INLINE_FUNCTION void fill_properties(SubViewtype full) const
386// {
387// full(0) = mass();
388// full(1) = this->length;
389// full(2) = this->rates.nu;
390// full(3) = this->nu;
391// full(4) = this->a_permease;
392// full(5) = this->a_pts;
393// }
394// };
395
396// } // namespace Models
397
398// #endif