12. Fed Batch Bioreactor

This model represents the fed batch bioreactor in section 2.4.9 of Seborg et al.

Nr Symbol Name Units
1 \(\mu_\text{max}\) Maximum specific growth rate 1/hr
2 \(K_s\) Monod constant g/L
3 \(Y_{X/S}\) Cell yield coefficient 1
4 \(Y_{P/S}\) Product yield coefficient 1
5 \(X\) Cell mass concentration g/L
6 \(S\) Substrate mass concentration g/L
7 \(V\) Volume L
8 \(P\) Substrate mass concentration g/L
9 \(F\) Feed flow rate L/hr
10 \(S_f\) Substrate mass concentration g/L
11 \(\mu\) Specific growth rate 1/hr
12 \(r_g\) Cell growth rate g /( L hr)
13 \(r_p\) Product growth rate g /( L hr)

Model equations:

Nr Equation Inputs Outputs Parameters
1
\[r_g = \mu X\]
\(r\), \(\mu\), \(X\)
2
\[\mu = \mu_{max} \frac{S}{K_S + S}\]
\(S\) \(\mu_\text{max}\), \(K_s\)
3
\[r_p = Y_{P/X}r_G\]
\(r_p\) \(Y_{P/X}\)
4
\[\frac{d(XV)}{dt} = Vr_g\]
\(V\)
5
\[\frac{d(PV)}{dt} = Vr_p\]
\(P\)
6
\[\frac{d(SV)}{dt} = FS_f - Vr\]
\(F\), \(S_f\)
\(Y_{X/S}\)
7
\[\frac{dV}{dt} = F\]
Number 7 2 7 4

Parameters

[1]:
mu_max = 0.2  # Maximum growth rate
K_s = 1.0  # Monod constant
Y_xs = 0.5 # Cell yield coefficient
Y_px = 0.2  # Product yield coefficient

States

[2]:
X = 0.05  # Concentration of the cells
S = 10   # Concentration of the substrate
P = 0   # Concentration of the product
V = 1   # Reactor volume

x0 = [X, S, P, V]  # State vector

Inputs

[3]:
F = 0.05  # Feed rate
S_f = 10  # Concentration of substrate in feed
[4]:
def dxdt(t, x):
    [X, S, P, V] = x

    mu = mu_max * S / (K_s + S)
    rg = mu * X
    rp = Y_px * rg
    dVdt = F
    dXdt = 1/V*(V * rg - dVdt*X)
    dPdt = 1/V*(V * rp - dVdt*P)
    dSdt = 1/V*(F * S_f - 1 / Y_xs * V * rg - dVdt*S)

    return [dXdt, dSdt, dPdt, dVdt]
[5]:
import scipy.integrate
import numpy
[6]:
import matplotlib.pyplot as plt
%matplotlib inline
[7]:
tspan = [0, 30]
[8]:
tsmooth = numpy.linspace(0, 30)
[9]:
Fs = [0.05, 0.02]
[10]:
results = []
[11]:
for F in Fs:
    out = scipy.integrate.solve_ivp(dxdt, tspan, x0, t_eval=tsmooth)
    results.append(out)
[12]:
names = ['X', 'S', 'P', 'V']
units = {'X': 'g/L', 'S': 'g/L', 'P': 'g/L', 'V': 'L'}
[13]:
ax = {}

fig, [[ax['X'], ax['P']], [ax['S'], ax['V']]] = plt.subplots(2, 2)

for F, out in zip(Fs, results):
    var = {name: y for name, y in zip(names, out.y)}
    for name in names:
        ax[name].plot(out.t, var[name])
        ax[name].set_ylabel(f'{name} ({units[name]})')
        ax[name].set_xlabel('Time (hr)')
plt.tight_layout()
../../_images/1_Dynamics_2_Time_domain_simulation_Fed_batch_bioreactor_18_0.png
[ ]: