12.3. Measuring Flowrate Example#
12.3.1. Learning Objectives#
After studying this notebook, completing the activities, engaging in class, and reading the book, you should be able to:
Apply error propagation formulas to predict uncertainty in calculations using experimental data
Use error propagation to solve practical examples concerning uncertainty
import numpy as np
import matplotlib.pyplot as plt
Please see the handout linked here.
12.3.2. Experimental Setup#
Imagine you want to measure the flow rate of water out of a faucet, but your flowmeter is broken. Quick on your feet, you devise a simple experiment using a graduate cylinder and wrist watch. The average flow rate is:
where \(V_{0}\) is the volume in the cylinder at time \(t_{0}\). You measure \(V_{f}\) and \(t_{f}\) after some time has elapsed.
12.3.3. Error Propagation#
Your graduated cylinder only measures to the nearest 0.1 mL and holds a maximum of 50 mL. Your analog wristwatch has a seconds hand. Based on this, you reason that \(σ_{V}\) = 0.1 mL (same for both volume measurements), \(σ_{t}\) = 1 s (same for both time measurements), and \(σ_{V,t}\) = 0 (i.e., the measurement errors are NOT correlated). Although you could conduct many experiments to estimate \(σ_{V}\) , \(σ_{t}\) , and \(σ_{V,t}\), you think it is wise to approximate the error level in F after taking only a few measurements. Here are the data for your first trial:
\(V_{0}\) |
\(t_{0}\) |
\(V_{f}\) |
\(t_{f}\) |
---|---|---|---|
5.3 mL |
1:01:04 |
49.2 mL |
1:01:56 |
Note
Home Activity (Video) : Complete the calculation on the handout on paper. We recommend trying this before watching the video. Then compare your answer to the code below.
12.3.4. Approach 1: Division Rule#
import math
## Given data
Vf = 49.2
V0 = 5.3
t0 = 4
tf = 56
## Calculate differences
dV = Vf - V0
dt = tf - t0
## Specified assumed/estimated uncertainties
sV = 0.1 # units: mL
st = 1.0 # units: sec
## Calculate flowrate estimate
F = dV / dt
print("F = ",round(F,2)," mL/s")
F = 0.84 mL/s
## Apply the division rule
sF = F*math.sqrt(2*(sV/dV)**2 + 2*(st/dt)**2)
print("Uncertainty in F: sigmaF = ",round(sF,10)," mL/s")
Uncertainty in F: sigmaF = 0.0231205612 mL/s
12.3.5. Approach 2: Differentiable Function Rule#
# define function to calculate f
f = lambda x : (x[1] - x[0])/(x[3] - x[2])
x0 = [V0,Vf,t0,tf]
F0 = f(x0)
print("F =",round(F0,2),"mL/s")
F = 0.84 mL/s
# use finite difference to build gradient
import numpy as np
deltaF = np.zeros(4)
xc = x0.copy()
eps = 1E-6
for i in range(len(deltaF)):
# perturb element i
xc[i] += eps
# apply forward finite different formula
deltaF[i] = (f(xc) - F0)/eps
# reset
xc[i] = x0[i]
print("deltaF =",deltaF)
deltaF = [-0.01923077 0.01923077 0.01623521 -0.01623521]
Sig = np.zeros((4,4))
Sig[0,0] = sV**2
Sig[1,1] = sV**2
Sig[2,2] = st**2
Sig[3,3] = st**2
print("Covariance matrix of measurement errors:\n")
print(Sig)
Covariance matrix of measurement errors:
[[0.01 0. 0. 0. ]
[0. 0.01 0. 0. ]
[0. 0. 1. 0. ]
[0. 0. 0. 1. ]]
# apply error propagation formula
sigmaF = math.sqrt(deltaF.dot(Sig.dot(deltaF)))
print("Uncertainty in F: sigmaF = ",round(sigmaF,10)," mL/s")
Uncertainty in F: sigmaF = 0.0231205611 mL/s