Gravity Drained Tank

by Jeffrey Kantor (jeff at The latest version of this notebook is available at


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

Torricelli's law

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.

Mass Balance for Tank with Constant Cross-Sectional Area

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.

Step-by-Step Approach to Nonlinear Simulation

Step 1. Initialize Jupyter and Python

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 [1]:
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint

Step 2. Define parameters

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

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

Step 3. Write Functions for the RHS of the Differential Equations

In [3]:
# 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

Step 4. Choose an Initial Condition, a Time Grid, and Integrate the Differential Equation

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

Step 5. Visualize and Analyze Results

In [5]:

plt.title('Gravity-Drained Tank')
plt.legend(['Liquid Level'])

Step 6. Adjust and Repeat as Needed

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.

In [ ]: