# Import modules
import numpy as np
import matplotlib.pyplot as plt
37 Mixing problems
Mixing problems in the context of a tank containing a solute, are a classic example used to demonstrate principles in differential equations. These problems typically involve a tank filled with a liquid into which a solute (like a salt or chemical) is introduced, either continuously or at specific intervals. The challenge is to determine the concentration of the solute in the tank over time, considering factors such as the rate of solute addition, the volume of the liquid in the tank, and the mixing or outflow rates. These scenarios are not only academically interesting but also have practical applications in industries like agronomy and environmental engineering.
Example 1: Tank level and salt concentration
A 1500 gallon tank initially contains 600 gallons of water with 5 lbs of salt dissolved in it. Water enters the tank at a rate of 9 gal/hr and the water entering the tank has a salt concentration of \frac{1}{5}(1 + cos(t)) lbs/gal. If a well-mixed solution leaves the tank at a rate of 6 gal/hr:
how long does it take for the tank to overflow?
how much salt (total amount in lbs) is in the entire tank when it overflows?
Assume each iteration is equivalent to one hour
We will break the problem into two steps. The first step consists of focusing on the tank volume and leaving the calculation of the salt concentration aside. Trying to solve both questions at the same time can make this problem more difficult than it actual is. A good way of thinking about this problem is by making an analogy with the balance of a checking account (tank level), where we have credits (inflow rate, salary) and debits (outflow, expenses).
Step 1: Find time it takes to fill the tank
# Initial parameters
= 1500 # gallons
tank_capacity = 600 # initial tank_level in gallons
tank_level = 9 # gal/hr
inflow_rate = 6 # gal/hr outflow_rate
# Step 1: Compute tank volume and determine when the tank is full
= 0
counter_hours while tank_level < tank_capacity:
= tank_level + inflow_rate - outflow_rate
tank_level += 1
counter_hours
print('Hours:', counter_hours)
print('Tank level:',tank_level)
Hours: 300
Tank level: 1500
Step 2: Add the calculation of the amount of salt
Now that we understand the problem in simple terms and we were able to implement it in Python, is time to add the computation of salt concentration at each time step. In this step is important to realize that concentration is amount of salt per unit volume of water, in this case gallons of water. Following the same reasoning of the previous step, we now need to calculate the balance of salt taking into account initial salt content, inflow, and outflow. So, to solve the problem we need:
- the inflow rate of water with salt
- the salt concentration of the inflow rate
- the outflow rate of water with salt
- the salt concentration of the outflow rate (we need to calculate this)
From the statement we have the first 3 pieces of information, but we lack the last one. Since concetration is mass of salt per unit volume of water, we just need to divide the total amount of salt over the current volume of water in the tank. So at the beginning we have 5 lbs/600 gallons = 0.0083 lbs/gal, which will be the salt concentration of the outflow during the first hour. Becasue the amount of water and salt in the tank changes every hour, we need to include this computation in each iteration to update the salt concentration of the outflow.
# Initial parameters
= 0
t = np.ones(period)*np.nan # Pre-allocate array with NaNs
tank_level = np.ones(period)*np.nan # Pre-allocate array with NaNs
salt_mass 0] = 600 # gallons
tank_level[0] = 5 # lbs
salt_mass[= 1500 # gallons
tank_capacity = 9 # gal/hr
inflow_rate = 6 # gal/hr
outflow_rate
# Compute tank volume and salt mass at time t until tank is full
while tank_level[t] < tank_capacity:
# Add one hour
+= 1
t
# The salt concentration will be computed using the tank level of the previous hour
= 1/5*(1+np.cos(t)) * inflow_rate # lbs/gal ranges between 0 and 0.4
salt_inflow = salt_mass[t-1]/tank_level[t-1] * outflow_rate
salt_outflow = salt_mass[t-1] + salt_inflow - salt_outflow
salt_mass[t]
# Now we can update the tank level
= tank_level[t-1] + inflow_rate - outflow_rate # volume of the tank
tank_level[t]
print(t, 'hours')
print(np.round(salt_mass[t]),'lbs of salt')
300 hours
280.0 lbs of salt
# Create figures
=(4,12))
plt.figure(figsize
3,1,1)
plt.subplot(range(period),tank_level)
plt.plot('Hours')
plt.xlabel('Tank level (gallons)')
plt.ylabel(
3,1,2)
plt.subplot(range(period),salt_mass)
plt.plot('Hours')
plt.xlabel('Salt mass in the tank (lbs)')
plt.ylabel(
3,1,3)
plt.subplot(# Plot every 5 values to clearly see the curve in the figure
range(0,period,5), 1/5*(1+np.cos(range(0, period,5))))
plt.plot('Hours')
plt.xlabel('Inflow sal concentration (lbs/gal)')
plt.ylabel( plt.show()
Example 2: Excess of herbicide problem
A farmer is preparing to control weeds in a field crop using a sprayer with a tank containing 100 liters of fresh water. The recommended herbice concentration to control the weeds without affecting the crop is 2%, which means that the farmer would need to add 2 liters of herbice to the tank. However, due to an error while measuring the herbicide, the farmer adds 3 liters of herbicide instead of 2 liters, which will certainly kill the weeds, but may also damage the crop and contaminate the soil with unnecesary product. To fix the problem and avoid disposing the entire tank, the farmer decides to open the outflow valve to let some herbicide solution out of the tank at a rate of 3 liters per minute, while at the same time, adding fresh water from the top of the tank at a rate of 3 liters per minute. Assume that the tank has a stirrer that keeps the solution well-mixed (i.e. the herbicide concentration at any given time is homogenous across the tank).
Indicate the time in minutes at which the herbicide concentration in the tank is restored at 2% (0.02 liters of herbicede per liter of fresh water). In other words, you need to find the time at which the farmer needs to close the outflow valve.
# Numerical Solution
= 100 # Liters
tank_level = 3 # Liters
chemical_volume = chemical_volume/tank_level # Liter of chemical per Liter of water
chemical_concentration = 3 # Liters per minute
inflow_rate = 3 # Liters per minute
outflow_rate = 0.02 # Liter of chemical per Liter of water
recommended_concentration = 0.1 # Time of each iteration in minutes
dt = 0 # Time tracker in minutes
counter
while chemical_concentration > recommended_concentration:
= tank_level + inflow_rate*dt - outflow_rate*dt
tank_level = 0
chemical_inflow = chemical_volume/tank_level*outflow_rate*dt
chemical_outflow = chemical_volume + chemical_inflow - chemical_outflow
chemical_volume = chemical_volume/tank_level
chemical_concentration += dt
counter
print('Solution:',round(counter,1),'minutes')
Solution: 13.5 minutes
References
The examples in this notebook were adapted from problems and exercises in Morris. Tenenbaum and Pollard, H., 1963. Ordinary differential equations: an elementary textbook for students of mathematics, engineering, and the sciences. Dover Publications.