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. *
100// phi_pts_max, "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) /
173// Yields::Yo_EG;
174// // None constexpr double y2_b =
175// (Yields::Y_EG + Yields::Yo_EG) /
176// (Yields::Y_EG * Yields::Y_OG); // G/O //To modify divide by YO_EG
177// not Y_Eg
178// constexpr double y1_c = (Yields::Y_EG + Yields::Yf_EG) /
179// Yields::Yf_EG;
180// // None constexpr double y1_e = (Yields::Y_EA + Yields::Yo_EA) /
181// Yields::Yo_EA; // None constexpr double y2_e =
182// (Yields::Y_EA + Yields::Yo_EA) / (Yields::Yo_EA * Yields::Y_OA);
183// // A/O
184// constexpr double yield_mol_S_O =
185// 1.; // Number of mol of S from mole of O for mode D conversion
186
187// // Yield for specie for specifc mode: id oxygen mode b => y_o2_b
188// constexpr double y_o2_b = (Yields::Y_EG * Yields::Y_OG) /
189// (Yields::Y_EG
190// + Yields::Yo_EG); constexpr double y_o2_e = (Yields::Y_EA *
191// Yields::Y_OA) / (Yields::Y_EA + Yields::Yo_EA); constexpr double
192// y_ac_c = (Yields::Y_AG * Yields::Y_EG) / (Yields::Y_EG +
193// Yields::Yf_EG); constexpr double y_x_b =
194// Yields::Y_XG * Yields::Yo_EG / (Yields::Y_EG + Yields::Yo_EG); //
195// Y_xg /y1_b
196// constexpr double y_x_c = Yields::Y_XG * Yields::Yf_EG / (Yields::Y_EG
197// + Yields::Yf_EG); constexpr double y_x_e = Yields::Y_XA *
198// Yields::Yo_EA / (Yields::Y_EA + Yields::Yo_EA);
199
200// constexpr double y_phi_o2_residual =
201// (Yields::Y_EG * Yields::Y_OG) / (Yields::Y_EG + Yields::Yo_EG); //
202// y2_bthe same
203
204// // Incoming for uptake mecanism
205// const auto [phi_s_in, phi_a_in, phi_o2_in] = phi_uptakes; // kg/s
206// const double current_mass = mass();
207
208// // Incomin in molee y2_b = (Yields::Y_EG + Yields::Yo_EG) /
209// (Yields::Y_EG * Yields::Y_OG); //
210// // G/O
211// const double phi_s_in_mol = phi_s_in / (current_mass *
212// MolarMass::glucose); // mol/s const double phi_a_in_mol = phi_a_in /
213// (current_mass * MolarMass::acetate); const double phi_o2_in_mol =
214// phi_o2_in;
215
216// // Maximum growth on oxidative (best yield)
217// const double r1_max = nu / MolarMass::X / Yields::x_s /
218// MolarMass::glucose; // molS/s
219// // Oxydative growth
220
221// const double phi_mode_b =
222// min_var(y1_b * r1_max, phi_s_in_mol, y2_b * phi_o2_in_mol); //
223// molS/s
224
225// double phi_s_residual = phi_s_in_mol - phi_mode_b; // molS/s
226
227// const double phi_o2_residual = phi_o2_in_mol - (y_phi_o2_residual *
228// phi_mode_b); // molO2/s
229
230// const double nu_residual =
231// ((Yields::Y_EG + Yields::Yo_EG) / Yields::Yo_EG * r1_max) -
232// phi_mode_b; // molS/s
233
234// const double phi_mode_c = min_var(y1_c * nu_residual, phi_s_residual);
235// // molS/s
236
237// phi_s_residual = phi_s_residual - phi_mode_c; // molS/s
238
239// const double phi_mode_d = min_var(phi_s_residual, yield_mol_S_O *
240// phi_o2_residual); // molS/s
241
242// const double phi_mode_e = min_var(y1_e * nu_residual, phi_a_in_mol,
243// y2_e * phi_o2_residual);
244
245// rates.glucose = -phi_s_in;
246// rates.oxygen = -current_mass * MolarMass::dioxygen *
247// (y_o2_b * phi_mode_b + y_o2_e * phi_mode_e +
248// phi_mode_d);
249
250// rates.acetate = current_mass * MolarMass::acetate *
251// (y_ac_c * phi_mode_c + Yields::Y_AG * phi_mode_d -
252// phi_mode_e);
253
254// rates.carbon_dioxide = -current_mass * MolarMass::co2 * (rates.oxygen
255// / MolarMass::dioxygen);
256
257// rates.nu = MolarMass::X * (y_x_b * phi_mode_b + y_x_c * phi_mode_c +
258// y_x_e * phi_mode_e);
259// }
260
261// KOKKOS_FUNCTION double uptake(const LocalConcentrationView&
262// concentration)
263// {
264// using namespace implEcoli;
265// const double s = Kokkos::max(0., concentration(_INDICES(GLUCOSE)));
266// const double phi_s_pts = phi_pts(a_pts, s);
267// const double gamma_PTS_S = phi_s_pts / phi_pts_max;
268// // const double micro_mixing = 0.3;
269
270// phi_uptakes.glucose = phi_s_pts + phi_permease(n_permease, a_permease,
271// s); phi_uptakes.acetate = phi_a_max * concentration(_INDICES(Ac)) / 1;
272// // 1 / micro_mixing * concentration(_INDICES(Ac)) / 1000.;
273
274// phi_uptakes.oxygen = phi_o2_max; //* concentration(_INDICES(O2)) /
275// 9e-3;
276// // 1 / micro_mixing *
277// concentration(_INDICES(O2)) / 1000.;
278// return gamma_PTS_S;
279// }
280
281// KOKKOS_FUNCTION void update(double d_t,
282// MC::ParticleDataHolder& p,
283// const LocalConcentrationView& concentration,
284// MC::KPRNG _rng)
285// {
286// using namespace implEcoli;
287// const double s = Kokkos::max(0., concentration(0));
288// const double gamma_PTS_S = uptake(concentration);
289// const double nu_p = phi_uptakes.glucose / mass() / (Yields::nu_s_x);
290
291// metabolism();
292// this->length += d_t * length * rates.nu;
293// this->nu += d_t * (1.0 / tau_metabolism) * (nu_p - this->nu);
294// this->a_pts += d_t * 1.0 / Tau::pts * (MONOD_RATIO(1., s, k_pts) -
295// this->a_pts); this->a_permease +=
296// d_t * (((1.0 / Tau::Au) * gamma_PTS_S + (1.0 / Tau::Ad) * (1.0 -
297// gamma_PTS_S)) *
298// (1.0 - gamma_PTS_S - a_permease));
299
300// this->n_permease += d_t *
301// (MONOD_RATIO(1. / Tau::new_permease, k_pts, s) +
302// MONOD_RATIO(1. / Tau::tau_rm_perm, s, k_pts)) *
303// (MONOD_RATIO(NPermease_max, k_pts, s) -
304// n_permease);
305
306// Models::update_division_status(
307// p.status, d_t, GammaDivision::threshold_linear(length, l_0, l_1),
308// _rng.random_pool);
309// }
310
311// KOKKOS_FUNCTION Ecoli division(MC::ParticleDataHolder& p, MC::KPRNG
312// _rng)
313// {
314// using namespace implEcoli;
315// const double original_length = this->length;
316// const double original_n_permease = this->n_permease;
317// this->length = original_length / 2.;
318// this->n_permease = original_n_permease / 2;
319
320// auto child = *this;
321// // const bool mask = a_pts > a_permease;
322// // const double max_perm = mask ? a_pts : 1;
323// // const double max_pts = mask ? 1 : a_permease;
324
325// {
326// // auto generator = _rng.random_pool.get_state();
327// // child.a_pts =
328// // Kokkos::min(max_pts,
329// Kokkos::max(generator.normal(this->a_pts, this->a_pts / 2.),
330// // 0.));
331
332// // child.a_permease = Kokkos::min(
333// // max_perm, Kokkos::max(generator.normal(this->a_permease,
334// this->a_permease / 2.),
335// // 0.));
336
337// auto generator = _rng.random_pool.get_state();
338// child.a_pts =
339// Kokkos::min(1., Kokkos::max(generator.normal(this->a_pts,
340// this->a_pts / 2.), 0.));
341
342// child.a_permease = Kokkos::min(
343// 1., Kokkos::max(generator.normal(this->a_permease,
344// this->a_permease / 2.), 0.));
345
346// child.nu = Kokkos::max(generator.normal(this->nu, this->nu / 3.),
347// 0.); _rng.random_pool.free_state(generator);
348// }
349
350// return child;
351// }
352
353// KOKKOS_FUNCTION void contribution(MC::ParticleDataHolder& p,
354// const ContributionView& contribution)
355// {
356// using namespace implEcoli;
357// auto access_contribs = contribution.access();
358// access_contribs(_INDICES(GLUCOSE), p.current_container) +=
359// rates.glucose * p.weight;
360// // access_contribs(_INDICES(Ac), p.current_container) += rates.acetate
361// * p.weight;
362// // access_contribs(_INDICES(O2), p.current_container) += rates.oxygen
363// * p.weight;
364// // access_contribs(_INDICES(CO2), p.current_container) +=
365// rates.carbon_dioxide * p.weight;
366// }
367
368// [[nodiscard]] KOKKOS_FUNCTION double mass() const noexcept
369// {
370// using namespace implEcoli;
371// return implEcoli::factor * length;
372// }
373
374// template <class Archive> void serialize(Archive& ar)
375// {
376// ar(length, nu, a_pts, a_permease);
377// }
378
379// static std::vector<std::string> names()
380// {
381// return {"mass", "length", "nu_eff", "nu", "a_permease", "a_pts"};
382// }
383
384// KOKKOS_INLINE_FUNCTION static consteval std::size_t get_number()
385// {
386// return 6;
387// }
388
389// KOKKOS_INLINE_FUNCTION void fill_properties(SubViewtype full) const
390// {
391// full(0) = mass();
392// full(1) = this->length;
393// full(2) = this->rates.nu;
394// full(3) = this->nu;
395// full(4) = this->a_permease;
396// full(5) = this->a_pts;
397// }
398// };
399
400// } // namespace Models
401
402// #endif