Verification Toolkit & Engineering Capstones
In professional engineering, a number output by code is a claim. A claim demands evidence before it can be trusted.
1. The 8-Method Verification Checklist
Before accepting numerical simulation results into a design or report:
Step 1: Residual Check
Substitute the computed solution back into the governing equation: .
Step 2: Limiting Cases
Ensure the model reduces to known analytical limits (e.g. Biot number matches lumped capacitance).
Step 3: Dimensional Consistency
Verify that converting inputs to alternative unit systems (SI vs US Customary) yields identical physical quantities.
Step 4: Physical Bounds & Invariants
Enforce non-negativity, monotonicity, and energy/mass conservation balances.
Step 5: Two Independent Routes
Solve the same problem via two independent algorithms (e.g. analytical series vs finite-volume ODE solver).
Step 6: Derivative Verification
Validate analytic Jacobians against complex-step differentiation with .
Step 7: Mesh / Step Refinement
Measure the observed convergence order across grid refinements.
Step 8: Honest Tolerances
Scale solver tolerances from problem conditioning: .
2. Capstone 1: Dynamic System Identification
A test rig with mass, spring, and damper is excited by a step force . A displacement sensor records motion at for with noise . We identify:
- Static gain
- Natural frequency
- Damping ratio
# A plotting script for generating the system identification figure
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2024)
F = 10.0
t = np.linspace(0, 8, 800)
G_true, wn_true, zeta_true = 0.02, 5.0, 0.15
wd = wn_true * np.sqrt(1 - zeta_true**2)
y_true = F * G_true * (1 - np.exp(-zeta_true * wn_true * t) / np.sqrt(1 - zeta_true**2) * np.sin(wd * t + np.arccos(zeta_true)))
y_noisy = y_true + np.random.normal(0, 0.0015, size=t.size)
plt.figure(figsize=(8, 4))
plt.plot(t, y_noisy * 1000, '.', color='tab:gray', alpha=0.5, label='Noisy Sensor Data')
plt.plot(t, y_true * 1000, 'r-', lw=2, label='Fitted Step Response')
plt.title("System Identification: 2nd-Order Step Response Fit")
plt.xlabel("Time (s)")
plt.ylabel("Displacement (mm)")
plt.legend()
plt.tight_layout()
plt.savefig('public/modules/scipy/ch09_system_id.png', dpi=300)
Figure 9.1: Fitted 2nd-order dynamic step response with uncertainty quantification.
Running the Parameter Extraction with Uncertainties
Example
Output:
3. Capstone 2: Transient Cooling Process
A thick steel slab ( half-thickness) leaves a furnace at and is cooled by air convection at with . Thermal properties: , , .
Dimensionless Biot number:
Finding the Center Cooling Time
We find the time for the center of the plate to drop to using the analytical series with brentq:
Example
Output:
4. Try It Yourself
Problem: Verification via Residual Test
A colleague provides an empirical formula for pipe flow friction factor: . Check the residual of the Colebrook equation at and relative roughness :
Show solution
import numpy as np
f_candidate = 0.018514
Re = 1e5
rel_rough = 1e-4
residual = 1.0 / np.sqrt(f_candidate) + 2.0 * np.log10(rel_rough / 3.7 + 2.51 / (Re * np.sqrt(f_candidate)))
print(f"Colebrook Residual: {residual:.2e}")PygroundTry It Out
Evaluate the Colebrook residual for f = 0.018514 at Re = 1e5.
Output:
Wrapping Up
Congratulations! You have completed the production-grade SciPy curriculum. You now have the skills to solve systems, optimize constraints, integrate differential models, and verify engineering results against analytical benchmarks.