A hybrid digital twin for jet-engine wear
I wrote a physics model of a two-spool turbofan, calibrated it to NASA's C-MAPSS run-to-failure fleet, and used it three ways: as a digital twin that tracks compressor damage and predicts remaining useful life (RUL) with uncertainty, as a simulator that makes realistic failure data with known truth, and as a source of physics features for a machine-learning model. Everything runs on a laptop CPU with free tools.
Each flight cycle, the twin reads nine sensors (temperatures, pressures, fuel flow), estimates how much the high-pressure compressor has worn, and updates its forecast of when the engine will reach the fleet's failure level. The band is the 80% interval; it narrows as evidence builds up.

| 100 held-out test engines | RMSE, cycles (95% CI) | 80% interval covers |
|---|---|---|
| Physics only: calibrated twin, no learned model | 16.4 [13.8, 18.9] | 74% |
| ML only: gradient-boosted trees on sensor features | 13.8 [11.2, 16.3] | 80% |
| Hybrid: the same trees + twin features | 12.3 [10.0, 14.3] | 65% |
The hybrid is the most accurate. Against ML only, its gain is 1.6 RMSE with a paired-bootstrap 95% CI of [-3.9, +0.9]: suggestive, not significant. Against physics only it is clearly better (-4.2 [-5.8, -2.6]).
Real fleets rarely have many run-to-failure examples. With only 5 training engines, the twin reaches RMSE 20.9 against 25.7 for ML only. The twin needs about 10 failures to calibrate and then stops improving, because its error comes from model form, not data. ML only catches up at about 20 engines, and the hybrid is best at every size.
Test RMSE on the same 100 held-out engines. Dots are means over 5 random training subsets, vertical lines min–max; one run at 100 engines.
- Right direction for every sensor. The model predicts the sign of wear-driven drift correctly for all 9 sensors, and the size within about 15% for most. It underestimates two pressure signals, and I report that instead of tuning it away.
- Physics vs pure data. On unseen engines, the 2-parameter physics model explains 48% of the sensor variance, against 56% for a data-only PCA with the same freedom. The gap is model-form error.
- The simulator reproduces the fleet. 500 simulated engines live 206 ± 40 cycles against 206 ± 46 for the real ones (KS test p = 0.58). On simulated engines with known damage, a blind twin tracked damage to within 2% of the failure level.
- The hybrid's intervals are too narrow. They cover only 65% instead of 80%. The cause is a subtle leak in how its out-of-fold residuals are made; nested cross-validation should fix it. Until then, the honest pairing is the hybrid's point estimate with the twin's interval.
Physics model
A steady-state Brayton-cycle gas-path model: fan, two compressors, burner, two turbines, shaft power balances. Fully vectorised in numpy, so 600 health hypotheses cost one call.
Three-stage calibration
Nine design constants solved exactly from the fleet's healthy cycles; compressor-matching constants fitted from start-to-end drift; then per-cycle Gauss-Newton gas-path analysis with Laplace uncertainty.
Damage filter
Wear follows dD/dt = a + bD. A 25×25 grid of exact Kalman filters over the unknown wear rates gives a deterministic posterior and RUL quantiles, with no particle degeneracy.
ML and hybrid
scikit-learn gradient-boosted trees on causal rolling sensor features; the hybrid adds 7 twin features made out-of-fold, grouped by engine, so no engine sees its own failure. Engine-level bootstrap CIs and conformal intervals.
21 tests, type checks and a simulated-fleet smoke run in GitHub Actions, plus a Streamlit demo with a physics simulator, a replay of real test engines and a fleet generator.