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:

\[F = \frac{V_{f} - V_{0}}{t_{f} - t_{0}} \]

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