by Jeffrey Kantor (jeff at nd.edu). The latest version of this notebook is available at https://github.com/jckantor/CBE30338.

In the example we study the problem of constructing nonlinear process model for the liquid level in a gravity drained tank.

Torricelli's law states the velocity of an incompressible liquid stream exiting a liquid tank at level $h$ below the surface is

$$v = \sqrt{2gh}$$

This is the same velocity as an object dropped from a height $h$. The derivation is straightforward. From Bernoulli's principle,

$$\frac{v^2}{2} + gh + \frac{P}{\rho} = \text{constant}$$

Applying this principle, compare a drop of water just below the surface of the water at distance $h$ above the exit, to a drop of water exiting the tank

$$gh + \frac{P_{atm}}{\rho} = \frac{v^2}{2} + \frac{P_{atm}}{\rho}$$

$$\implies v^2 = 2gh$$ $$\implies v = \sqrt{2gh}$$

Torricelli's law is an approximation that doesn't account for the effects of fluid viscosity, the specific flow geometry near the exit, or other flow non-idealities. Nevertheless it is a useful first approximation for flow from a tank.

For a tank with constant cross-sectional area, such as a cylindrical or rectangular tank, the liquid height is described by a differential equation

$$A\frac{dh}{dt} = q_{in}(t) - q_{out}(t)$$

where $q_{out}$ is a function of liquid height. Torricelli's law tells the outlet flow from the tank is proportional to square root of the liquid height

$$ q_{out}(h) = C_v\sqrt{h} $$

Dividing by area we obtain a nonlinear ordinary differential equation

$$ \frac{dh}{dt} = - \frac{C_V}{A}\sqrt{h} + \frac{1}{A}q_{in}(t) $$

in our standard form where the LHS derivative appears with a constant coefficient of 1.

The first step in any Python application is to initialize graphics display (if you will be creating graphic output), and import any needed libraries.

The `%matplotlib inline`

is a command telling the Jupyter notebook to display any graphics inside this notebook.

We then import a standard graphics library (`matplotlib.pyplot`

) that will be referred to with the prefix `plt`

, a standard numerical library `numpy`

that will be referred to with the prefix `np`

, and the function `odeint`

from the `scipy.integrate`

library.

In [0]:

```
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
```

Provide values for all relevant parameters. Use comments to describe the parameters and units.

In [0]:

```
Cv = 0.1 # Outlet valve constant [cubic meters/min/meter^1/2]
A = 1.0 # Tank area [meter^2]
```

In [0]:

```
# inlet flow rate in cubic meters/min
def qin(t):
return 0.15
def deriv(h,t):
return qin(t)/A - Cv*np.sqrt(h)/A
```

In [0]:

```
IC = [0.0]
t = np.linspace(0,200,101)
h = odeint(deriv,IC,t)
```

In [6]:

```
plt.plot(t,h)
plt.xlabel('minutes')
plt.ylabel('meters')
plt.title('Gravity-Drained Tank')
plt.legend(['Liquid Level']);
```

Rarely does a simulation provide you with the information you seek on the first try. You will almost certainly need to revise parameter values, choose different time grids, and add visualization features to obtain the most informative results.