Monod growth in a batch or fed-batch vessel
64-bitConcentrations of biomass, substrate and product, the volume, and their masses at each output time.
μ = μmax × S ÷ (Ks + S); dX/dt = (μ − kd) X − D X; dS/dt = −(μ ÷ Yxs + m) X + D (Sf − S); dP/dt = (α μ + β) X − D P; dV/dt = F; D = F ÷ V
64-bit throughout; the integrator is asked for rtol 1e-9 and atol 1e-12 on each of the n output intervals. S is clamped at 0 inside the rate and uptake stops when S is not above 0. Masses are concentration × volume at each output time.
/**
* Monod kinetics, with maintenance, death and product formation (Luedeking–Piret), in a batch (F = 0) or fed-batch vessel.
* par = { mumax (1/h), Ks (g/L), Yxs (g/g), m? (g/g/h), kd? (1/h), alpha? , beta? (Luedeking–Piret), X0, S0, P0?, V0, F? (L/h), Sf? (g/L), Feed after tFeed? }
* → { t[], X[], S[], P[], V[], mass: {X,S,P} } over [0, tEnd] (hours).
*/
export function fermentation(par, { tEnd, n = 200 } = {}) {
const { mumax, Ks, Yxs, m = 0, kd = 0, alpha = 0, beta = 0, F = 0, Sf = 0, tFeed = 0 } = par;
const f = (t, y) => {
const [X, S, P, V] = y, Sx = Math.max(S, 0), mu = mumax * Sx / (Ks + Sx), Fi = t >= tFeed ? F : 0, D = Fi / V;
const dX = (mu - kd) * X - D * X, dS = -(mu / Yxs + m) * X * (Sx > 0 ? 1 : 0) + D * (Sf - S), dP = (alpha * mu + beta) * X - D * P;
return [dX, dS, dP, Fi];
};
const out = { t: [0], X: [par.X0], S: [par.S0], P: [par.P0 || 0], V: [par.V0] };
let y = [par.X0, par.S0, par.P0 || 0, par.V0];
for (let i = 1; i <= n; i++) { const r = rk45(f, y, (i - 1) * tEnd / n, i * tEnd / n, { rtol: 1e-9, atol: 1e-12 }); y = r.y; out.t.push(i * tEnd / n); out.X.push(y[0]); out.S.push(y[1]); out.P.push(y[2]); out.V.push(y[3]); }
out.mass = { X: out.X.map((x, i) => x * out.V[i]), S: out.S.map((x, i) => x * out.V[i]), P: out.P.map((x, i) => x * out.V[i]) };
return out;
}