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()

[ ]: