Fill up the tank - Challenge 2: Varying the time step
Task
Try to run the code with different values of the time step
. How do you expect the approximate solution will change? Try with the values
, while keeping the other parameters fixed.
The figure shows the solution (water level in the tank) obtained using different values of the time step
.

Figure 1: Water level in the tank for the considered values of
.
When
gets smaller, the graphs approach the analytic solution. For a large value of
our approximation wildly oscillates up and down, showing a completely different behaviour from the real solution! Choosing
small enough is thus very important to get reliable and accurate results.
We recall that we obtained our approximation by substituting the time derivative
with a finite ratio:
This approximation is justified by the definition of derivative:
So, as
becomes smaller, the ratio becomes a better approximation of the derivative and we expect that our approximation gets closer to the true solution.
To experiment with different values of
, we use a for loop. Then, we save the simulated data in a list and plot them to compare the results. The full Python code for the solution is the following:
import matplotlib.pyplot as plt # import package for plot
# Physical parameters
Q_in = 1.0 # inflow rate
A_t = 1.0 # tank cross-sectional area (m^2)
A_out = 0.1 # outlet area (m^2)
g = 9.81 # gravity
h0 = 1.0 # initial water level
# Simulation time parameters
T = 100.0 # total simulation time
# outflow rate Q_out
def Q_out(h):
return A_out * (2 * g * h) ** 0.5
plt.figure(figsize=(10, 5))
# loop over different values for the time step
for dt in [0.01, 0.1, 1, 5, 10, 20]:
N = int(T / dt) # number of time steps
# lists to store the solution
times = [0.0] * (N + 1)
h = [0.0] * (N + 1)
h[0] = h0
for i in range(N):
dh = dt * (Q_in - Q_out(h[i]))
h[i + 1] = h[i] + dh
times[i + 1] = (i + 1) * dt
plt.plot(times, h, label="dt = " + str(dt))
plt.xlabel("Time (s)")
plt.ylabel("Water Level (m)")
plt.title("Water Level Over Time for Different dt")
plt.legend()
plt.grid()
plt.show()
To experiment with different values of
, we use a for loop. Then, we can compare the results by reporting the graphs in the same figure. The full Matlab code for the solution is the following:
% Function to define the inflow rate function
Q_in = @(t) 1;
% Function to calculate the outflow rate based on the water level and outlet area
Q_out = @(outlet_area, water_level) sqrt(2 * 9.81 * max(water_level, 0)) * outlet_area;
A_out = 0.1; % Outlet area (m^2)
A_t = 1.0; % Tank cross-sectional area (m^2)
h0 = 1.0; % Initial water level
% Simulation time parameters
T = 100; % Total simulation time (seconds)
% Create figure for plotting
figure();
grid on;
hold on;
% Loop over different time step sizes
for dt = [0.01, 0.1, 1, 5, 10, 20]
N = round(T / dt); % Number of time steps
% Create arrays to store data for plotting
times = zeros(1, N + 1);
h = zeros(1, N + 1);
h(1) = h0;
t = 0;
% Simulate the water level over time
for i = 1:N
t = t + dt;
h(i + 1) = h(i) + (Q_in(t) - Q_out(A_out, h(i))) * dt;
times(i + 1) = t;
end
plot(times, h, '-');
end
legend('dt = 0.01', 'dt = 0.1', 'dt = 1', 'dt = 5', 'dt = 10', 'dt = 20');

