4. 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
[ ]: