Note
Go to the end to download the full example code or to run this example in your browser via JupyterLite.
MIL-P-1629’s failure mode and effects analysis (1949)#
The US military procedure MIL-P-1629, Procedures for Performing a Failure
Mode, Effects and Criticality Analysis (9 November 1949), asked designers
to go through a system part by part, list each way the part can fail,
trace the effect of each failure and classify it by its consequence for
the mission and for safety. NASA used the method on Apollo, and the
automotive industry later made it routine, ranking each mode by a risk
priority number, severity times occurrence times detection, each scored
from 1 to 10 (risk_priority_number(),
fmea_ranking()). Where failure rates are
known the military standard’s criticality number
\(C_m = \beta\alpha\lambda_p t\)
(failure_mode_criticality()) ranks
modes by expected losses instead.
import matplotlib.pyplot as plt
import numpy as np
from engineeringkit.reliability import failure_mode_criticality, fmea_ranking
An FMEA of a centrifugal pump#
(severity, occurrence, detection) for each failure mode.
modes = {
"mechanical seal leak": (6, 6, 3),
"bearing seizure": (8, 3, 5),
"impeller erosion": (5, 4, 7),
"motor winding short": (9, 2, 4),
"coupling misalignment": (4, 5, 5),
"cavitation": (5, 5, 6),
"casing crack": (10, 1, 6),
}
fmea = fmea_ranking(modes)
for name, s, o, d, rpn in zip(fmea.modes, fmea.severity, fmea.occurrence, fmea.detection, fmea.rpn):
print(f"{name:22s} S={s:2d} O={o:2d} D={d:2d} RPN={rpn:4d}")
fig, ax = fmea.plot()
fig.set_size_inches(7, 4)
fig.tight_layout()

cavitation S= 5 O= 5 D= 6 RPN= 150
impeller erosion S= 5 O= 4 D= 7 RPN= 140
bearing seizure S= 8 O= 3 D= 5 RPN= 120
mechanical seal leak S= 6 O= 6 D= 3 RPN= 108
coupling misalignment S= 4 O= 5 D= 5 RPN= 100
motor winding short S= 9 O= 2 D= 4 RPN= 72
casing crack S=10 O= 1 D= 6 RPN= 60
What the RPN hides#
The casing crack has the lowest RPN but a severity of 10. Because the scores are ordinal, a high severity is reviewed whatever its product.
modes reviewed for severity alone: ['motor winding short', 'casing crack']
Criticality numbers from failure rates#
The seal of a pump with \(\lambda_p\) = 50 failures per million hours fails by leaking (60% of failures, of which 20% stop the mission) or by sudden rupture (40%, all of which stop it); the mission is 2000 h.
leak, rupture = failure_mode_criticality(np.array([0.6, 0.4]), np.array([0.2, 1.0]), 50e-6, 2000.0)
print(f"criticality: leak {leak:.3f}, rupture {rupture:.3f} expected losses per mission")
assert fmea.modes[0] == "cavitation" and fmea.rpn[0] == 150
assert "casing crack" in critical and fmea.modes[-1] == "casing crack"
assert np.isclose(leak + rupture, 50e-6 * 2000 * (0.6 * 0.2 + 0.4))
plt.show()
criticality: leak 0.012, rupture 0.040 expected losses per mission
Total running time of the script: (0 minutes 0.165 seconds)