Difference between revisions of "Software tutorial/Integration of ODEs"
Line 28: | Line 28: | ||
|- | |- | ||
! MATLAB | ! MATLAB | ||
! Python | |||
|- | |||
| width="50%" valign="top" | | |||
In a file called '''<tt>tank.m</tt>''': | In a file called '''<tt>tank.m</tt>''': | ||
<syntaxhighlight lang="matlab"> | <syntaxhighlight lang="matlab"> | ||
Line 61: | Line 64: | ||
t_start = 0; | t_start = 0; | ||
t_final = 5.0; | t_final = 5.0; | ||
% Set the initial condition(s): | % Set the initial condition(s): | ||
Line 76: | Line 78: | ||
ylabel('Concentration of A [mol/L]') | ylabel('Concentration of A [mol/L]') | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| width="50%" valign="top" | | | width="50%" valign="top" | | ||
|} | |} |
Revision as of 15:12, 18 November 2010
In our course we have learned several ways of integrating a single equation \(\displaystyle \frac{dy(t)}{dt} = f(t, y) \) with a given initial condition \(y(t=0)=y_0\); and we have shown that a system of \(n\) first order ODE's can be integrated: \[ \displaystyle \frac{d{\bf y}(t)}{dt} = {\bf f}(t, {\bf y}) \]given a set of \(n\) initial conditions \({\bf y}(t=0) = {\bf y}_0\), i.e. \( {\bf y}_0\) is an \(n \times 1\) vector. The course notes covered Euler's method, Heun's method and Runge-Kutta methods.
However, we only coded Euler's method (because it was simple!), but not the others. These other methods have been (reliably) coded in software packages and sophisticated error correction tools built into their algorithms. You should always use these toolbox functions to integrate your differential equation models. In this section we will show how to use MATLAB and Python's built-in functions to integrate:
- a single differential equation
- a system of differential and algebraic equations.
We will only look at initial value problems (IVPs) in this tutorial.
MATLAB
MATLAB's has several ODE solvers available. You can read up more about the implementation details in this technical document.
Python
Like MATLAB, several integrators are available in Python. The integrator I will use in this tutorial is one of the most recent additions to SciPy - the VODE integrator developed at Lawrence Livermore National Laboratories in 1988. It is a good general-purpose solver for both stiff and non-stiff systems.
Example problem
The example we will work with is a common modelling reaction: a liquid-based stirred tank reactor, with (initially) constant physical properties, a second order chemical reaction where species A is converted to B according to \({\sf A} \rightarrow {\sf B} \), with reaction rate \(r = k C_{\sf A}^2\). One can find the time-dependent mass balance for this system to be:
\[ \frac{dC_{\sf A}(t)}{dt} = \frac{F(t)}{V} \bigg( C_{{\sf A},\text{in}} - C_{\sf A} \bigg) - k C_{\sf A}^2 \]
where \(C_{{\sf A},\text{in}} = 5.5\) mol/L, we will initially assume constant volume of \(V = 100\) L and constant inlet flow of \(F(t) = 5 \) L/min. The reaction rate constant is 0.24 \(\text{min}^{-1}\). We must specify an initial condition for every differential equation: we will let \( C_{\sf A}(t=0) = 3.2\) mol/L.
In the code below we will integrate the ODE from \(t_\text{start} = 0.0\) minutes up to \(t_\text{final} = 10.0\) minutes and plot the time-varying trajectory of concentration in the tank.
MATLAB | Python |
---|---|
In a file called tank.m: function dydt = tank(t, y)
% Dynamic balance for a CSTR
%
% C_A = y(1) = the concentration of A in the tank, mol/L
%
% Returns dy/dt = F/V*(C_{A,in} - C_A) - k*C_A^2
F = 20; % L/min
CA_in = 5.5; % mol/L
V = 100; % L
k = 0.24; % 1/min
% Assign some variables for convenience of notation
CA = y(1);
n = 1; % A single, first-order ODE
% The output from the ODE function must be a COLUMN vector, with n rows
dydt = zeros(n,1);
dydt(1) = F/V*(CA_in - CA) - k *CA^2;
In a separate file (any name), for example: ode_driver.m, which will "drive" the ODE solver: % Integrate the ODE
% -----------------
% Set the time range:
t_start = 0;
t_final = 5.0;
% Set the initial condition(s):
CA_t_zero = 3.2;
% Integrate the ODE(s):
[t, y] = ode45(@tank,[t_start, t_final], [CA_t_zero]);
% Plot the results:
clf;
plot(t, y)
grid('on')
xlabel('Time [minutes]')
ylabel('Concentration of A [mol/L]')
|