Thermal performance / Decision support

When will an exchanger
need attention?

A reproducible test of physics-guided fouling forecasts: infer resistance from plant-style measurements, project thermal duty, and expose the uncertainty before a cleaning decision.

Explore the evidence ↓Plan a pilot
7Forecast approaches compared
5Recorded random seeds
—Held-out campaign traces shown
BlindFuture observations excluded from forecasts
01

Inspect the decision horizon

Campaign forecast · one recorded seed

Choose a campaign and model. The observed prefix initializes the forecast; the forecast then uses the assumed operating conditions available at issuance. The actual future is revealed only for scoring. The displayed cleaning threshold is the configured fraction of clean duty under actual evaluation conditions, a reference for judging the forecast.

Forecast and actual heat dutySelect a campaign and model to inspect its held-out forecast.
Simulator truthForecastRecorded interval, when availableCleaning threshold, when recorded
Intervals describe the benchmark calibration procedure. They are not operational guarantees.
Show the selected trace as a data table
02

Judge the model against alternatives

Mean ± standard deviation across recorded seeds

A useful hybrid must compete with simple engineering baselines and direct machine learning on entire unseen campaigns. A low conditional timing error alone is insufficient: event detection and forecast errors matter too.

Held-out model errors, mean and standard deviation across seeds.
SplitModelOutlet RMSE · KDuty RMSE · kWCrossing precisionCrossing recallTiming MAE · days¹True crossingsn pred crossingsJoint crossingsforecast failures
NominalBlack Hybrid1.49 ± 0.0650.73 ± 4.291.00 ± 0.001.00 ± 0.005.97 ± 1.0720.00 ± 0.0020.00 ± 0.0020.00 ± 0.000.00 ± 0.00
NominalCausal Trend1.52 ± 0.0049.57 ± 0.001.00 ± 0.001.00 ± 0.004.60 ± 0.0020.00 ± 0.0020.00 ± 0.0020.00 ± 0.000.00 ± 0.00
NominalDirect Ml1.57 ± 0.0879.22 ± 2.421.00 ± 0.000.96 ± 0.0412.42 ± 0.7320.00 ± 0.0019.20 ± 0.8419.20 ± 0.840.00 ± 0.00
NominalFixed Rate1.62 ± 0.0357.46 ± 1.981.00 ± 0.001.00 ± 0.007.55 ± 1.2820.00 ± 0.0020.00 ± 0.0020.00 ± 0.000.00 ± 0.00
NominalGrey Hybrid1.44 ± 0.0148.55 ± 2.461.00 ± 0.001.00 ± 0.005.49 ± 1.2120.00 ± 0.0020.00 ± 0.0020.00 ± 0.000.00 ± 0.00
NominalPersistence5.17 ± 0.00221.33 ± 0.00—0.00 ± 0.00—20.00 ± 0.000.00 ± 0.000.00 ± 0.000.00 ± 0.00
NominalWhite Hybrid1.44 ± 0.0147.37 ± 1.431.00 ± 0.001.00 ± 0.004.30 ± 0.7020.00 ± 0.0020.00 ± 0.0020.00 ± 0.000.00 ± 0.00
ShiftBlack Hybrid2.05 ± 0.0492.72 ± 5.121.00 ± 0.001.00 ± 0.003.23 ± 0.1524.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00
ShiftCausal Trend1.70 ± 0.0049.97 ± 0.001.00 ± 0.001.00 ± 0.001.38 ± 0.0024.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00
ShiftDirect Ml5.87 ± 0.28216.28 ± 9.621.00 ± 0.001.00 ± 0.0015.15 ± 0.5824.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00
ShiftFixed Rate2.59 ± 0.26131.92 ± 12.451.00 ± 0.001.00 ± 0.005.85 ± 1.4924.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00
ShiftGrey Hybrid1.72 ± 0.1866.51 ± 7.041.00 ± 0.001.00 ± 0.002.25 ± 0.7524.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00
ShiftPersistence9.27 ± 0.00408.04 ± 0.00—0.00 ± 0.00—24.00 ± 0.000.00 ± 0.000.00 ± 0.000.00 ± 0.00
ShiftWhite Hybrid1.53 ± 0.0979.43 ± 9.451.00 ± 0.001.00 ± 0.003.17 ± 1.0724.00 ± 0.0024.00 ± 0.0024.00 ± 0.000.00 ± 0.00

¹ Timing MAE is evaluated only where a threshold crossing is observed and the model also predicts a crossing within the evaluation horizon. It must be read with crossing recall, precision, and the count of joint crossings. A campaign that never crosses is right-censored; it is not assigned an artificial event at the last day. Empty values mean the metric is undefined for that group.

03

Does more history help?

E1 · data efficiency

Training size counts independent campaigns, rather than adjacent observations from the same trajectory. This plot uses the shifted holdout split. The learning curve shows the results actually measured; it does not assume that a hybrid always wins with less data.

Learning curve against independent training campaign count.
04

Know where confidence breaks down

E4 / E5 · operating domain and sensor noise

Operating shifts are a warning signal

A validity detector measures how far operating conditions depart from training. Its value depends on both flag frequency and the errors inside and outside the flagged region. A flag is not a diagnosis of fouling.

Measurement quality is part of the model

Noise can distort resistance inversion before the learner sees a target. The noise study reruns the forecast workflow with the specified sensor perturbations. Compare it with the cleanest setting before proposing a pilot.

Validity-domain evidence
SplitDetectorflag raten flaggedn totalerror flagged Kerror inside K
NominalConvex Hull0.80 ± 0.0616.00 ± 1.2220.00 ± 0.001.42 ± 0.071.41 ± 0.33
NominalHyperrectangle0.23 ± 0.044.60 ± 0.8920.00 ± 0.001.45 ± 0.141.43 ± 0.02
NominalK-Means Distance0.19 ± 0.073.80 ± 1.4820.00 ± 0.001.38 ± 0.281.45 ± 0.07
NominalOne-Class Svm0.63 ± 0.1212.60 ± 2.3020.00 ± 0.001.49 ± 0.091.32 ± 0.17
ShiftConvex Hull1.00 ± 0.0024.00 ± 0.0024.00 ± 0.001.72 ± 0.18—
ShiftHyperrectangle0.92 ± 0.0022.00 ± 0.0024.00 ± 0.001.77 ± 0.181.10 ± 0.12
ShiftK-Means Distance0.94 ± 0.0422.60 ± 0.8924.00 ± 0.001.75 ± 0.161.00 ± 0.17
ShiftOne-Class Svm1.00 ± 0.0024.00 ± 0.0024.00 ± 0.001.72 ± 0.18—
Noise-robustness evidence
Noise MultiplierSplitModelOutlet RMSE · KDuty RMSE · kWCrossing recallTiming MAE · days¹
0.5NominalBlack Hybrid1.49 ± 0.0750.82 ± 4.401.00 ± 0.006.05 ± 1.06
0.5NominalCausal Trend1.45 ± 0.0044.19 ± 0.001.00 ± 0.003.10 ± 0.00
0.5NominalDirect Ml1.65 ± 0.1479.94 ± 5.430.93 ± 0.0312.51 ± 1.05
0.5NominalFixed Rate1.59 ± 0.0356.92 ± 2.041.00 ± 0.007.60 ± 1.34
0.5NominalGrey Hybrid1.44 ± 0.0147.98 ± 2.271.00 ± 0.005.24 ± 1.14
0.5NominalPersistence5.15 ± 0.00220.94 ± 0.000.00 ± 0.00—
0.5NominalWhite Hybrid1.43 ± 0.0147.04 ± 1.421.00 ± 0.004.24 ± 0.65
0.5ShiftBlack Hybrid2.08 ± 0.0991.81 ± 9.001.00 ± 0.003.30 ± 0.31
0.5ShiftCausal Trend1.73 ± 0.0049.47 ± 0.001.00 ± 0.001.04 ± 0.00
0.5ShiftDirect Ml5.77 ± 0.41214.63 ± 14.731.00 ± 0.0015.42 ± 0.64
0.5ShiftFixed Rate2.61 ± 0.26130.38 ± 12.681.00 ± 0.005.76 ± 1.53
0.5ShiftGrey Hybrid1.67 ± 0.1766.52 ± 6.061.00 ± 0.002.18 ± 0.62
0.5ShiftPersistence9.27 ± 0.00405.41 ± 0.000.00 ± 0.00—
0.5ShiftWhite Hybrid1.51 ± 0.0978.43 ± 9.141.00 ± 0.003.02 ± 1.02
2.5NominalBlack Hybrid1.54 ± 0.0751.95 ± 5.481.00 ± 0.006.42 ± 1.37
2.5NominalCausal Trend1.93 ± 0.0074.05 ± 0.001.00 ± 0.0011.95 ± 0.00
2.5NominalDirect Ml1.59 ± 0.0983.32 ± 3.770.94 ± 0.0212.98 ± 2.11
2.5NominalFixed Rate1.68 ± 0.0259.78 ± 1.951.00 ± 0.007.84 ± 1.18
2.5NominalGrey Hybrid1.49 ± 0.0655.15 ± 4.251.00 ± 0.008.75 ± 2.24
2.5NominalPersistence5.24 ± 0.00223.17 ± 0.000.00 ± 0.00—
2.5NominalWhite Hybrid1.47 ± 0.0149.33 ± 1.391.00 ± 0.004.50 ± 0.63
2.5ShiftBlack Hybrid2.15 ± 0.0798.72 ± 10.241.00 ± 0.003.52 ± 0.40
2.5ShiftCausal Trend1.85 ± 0.0065.94 ± 0.001.00 ± 0.003.21 ± 0.00
2.5ShiftDirect Ml5.74 ± 0.48207.11 ± 16.841.00 ± 0.0014.86 ± 0.62
2.5ShiftFixed Rate2.58 ± 0.24139.00 ± 11.631.00 ± 0.006.28 ± 1.40
2.5ShiftGrey Hybrid2.01 ± 0.2268.90 ± 10.041.00 ± 0.002.73 ± 1.27
2.5ShiftPersistence9.24 ± 0.00414.88 ± 0.000.00 ± 0.00—
2.5ShiftWhite Hybrid1.59 ± 0.0781.14 ± 9.421.00 ± 0.003.22 ± 1.07
5.0NominalBlack Hybrid1.62 ± 0.0555.53 ± 4.911.00 ± 0.006.55 ± 0.70
5.0NominalCausal Trend2.88 ± 0.00124.77 ± 0.000.80 ± 0.0014.06 ± 0.00
5.0NominalDirect Ml1.60 ± 0.1494.09 ± 3.320.94 ± 0.0514.41 ± 1.45
5.0NominalFixed Rate1.79 ± 0.0164.32 ± 1.221.00 ± 0.007.97 ± 0.73
5.0NominalGrey Hybrid1.86 ± 0.1177.21 ± 5.970.93 ± 0.0415.56 ± 2.31
5.0NominalPersistence5.33 ± 0.00225.63 ± 0.000.00 ± 0.00—
5.0NominalWhite Hybrid1.56 ± 0.0254.02 ± 0.601.00 ± 0.004.77 ± 0.12
5.0ShiftBlack Hybrid2.28 ± 0.09109.51 ± 5.911.00 ± 0.004.21 ± 0.39
5.0ShiftCausal Trend2.62 ± 0.00119.14 ± 0.000.96 ± 0.006.43 ± 0.00
5.0ShiftDirect Ml5.78 ± 0.49203.87 ± 16.451.00 ± 0.0013.88 ± 0.90
5.0ShiftFixed Rate2.59 ± 0.16149.55 ± 8.161.00 ± 0.007.08 ± 1.09
5.0ShiftGrey Hybrid1.93 ± 0.0981.90 ± 19.451.00 ± 0.004.51 ± 1.94
5.0ShiftPersistence9.25 ± 0.00427.52 ± 0.000.00 ± 0.00—
5.0ShiftWhite Hybrid1.81 ± 0.0481.34 ± 6.311.00 ± 0.002.94 ± 0.54
Interpretation rule. Coverage, error, and threshold-event detection are separate measures. Strong results on one should never substitute for the others. Distribution shift can invalidate intervals calibrated on nominal operating conditions.
05

Inspect the failures, not just the averages

Highest-error held-out trajectories · first seed

These are the largest campaign-level temperature errors across all models in the selected recorded seed. Use the campaign selector above to inspect them. Low coverage or a missed validity flag identifies a concrete limitation for the next engineering iteration.

split campaign model RMSE (K) Maximum error (K) Interval coverage Flagged share
shift C068 Persistence 13.195 19.429 0.433 1.000
shift C067 Persistence 12.263 18.453 0.533 1.000
shift C077 Persistence 12.040 19.078 0.556 1.000
shift C084 Persistence 11.110 19.502 0.622 1.000
shift C080 Direct ML 10.864 15.464 0.000 1.000
shift C073 Persistence 10.724 15.087 0.544 1.000
shift C064 Persistence 10.278 15.925 0.633 1.000
shift C084 Direct ML 9.657 14.711 0.144 1.000
shift C083 Direct ML 9.637 13.727 0.000 1.000
shift C076 Persistence 9.611 14.688 0.667 1.000
shift C070 Persistence 9.507 14.824 0.678 1.000
shift C083 Persistence 9.327 15.743 0.689 1.000
Uncertainty coverage by model and split
SplitModelinterval simultaneous coverageinterval marginal coverageinterval mean width K
NominalBlack Hybrid0.96 ± 0.041.00 ± 0.007.99 ± 0.48
NominalCausal Trend0.95 ± 0.001.00 ± 0.008.86 ± 0.00
NominalDirect Ml1.00 ± 0.001.00 ± 0.009.78 ± 1.52
NominalFixed Rate1.00 ± 0.001.00 ± 0.0010.72 ± 0.68
NominalGrey Hybrid0.95 ± 0.040.99 ± 0.0112.88 ± 2.22
NominalPersistence0.95 ± 0.000.99 ± 0.0023.97 ± 0.00
NominalWhite Hybrid1.00 ± 0.001.00 ± 0.008.26 ± 0.18
ShiftBlack Hybrid0.78 ± 0.090.94 ± 0.027.99 ± 0.48
ShiftCausal Trend0.96 ± 0.001.00 ± 0.008.86 ± 0.00
ShiftDirect Ml0.19 ± 0.100.55 ± 0.099.78 ± 1.52
ShiftFixed Rate0.80 ± 0.020.93 ± 0.0010.72 ± 0.68
ShiftGrey Hybrid1.00 ± 0.001.00 ± 0.0044.65 ± 22.16
ShiftPersistence0.21 ± 0.000.77 ± 0.0023.97 ± 0.00
ShiftWhite Hybrid0.98 ± 0.021.00 ± 0.008.26 ± 0.18

Simultaneous coverage requires the whole held-out campaign trajectory to lie inside its band; marginal coverage counts individual time points. Neither is interchangeable with coverage of a cleaning-time interval. Temperature-band width is in kelvin.

06

Turn this into a testable pilot

1–3 exchangers · proposed 4–8 week study

The first engagement is a focused retrospective study with an engineer reviewing every recommendation. Scope and acceptance criteria are agreed before looking at the holdout period.

01 / Establish usable history

Request 12–24 months of inlet/outlet temperatures, mass flows, pressure drops, geometry, fluid properties, operating changes, and cleaning dates. Audit units, synchronization, heat-balance closure, and sensor maintenance.

02 / Freeze a blind evaluation

Reserve complete cleaning campaigns for holdout. Compare against the current operating rule, persistence, a local trend, and direct ML. Score missed crossings, false alarms, lead time, duty error, and interval coverage.

03 / Make the result actionable

Deliver reproducible forecasts, an engineer-readable evidence report, and a data-quality log. Advance only if agreed error and false-alarm limits are met. Estimate economics using site-approved fuel, throughput, and cleaning assumptions.

Proposed deliverable: a ranked list of exchangers that merit review, with forecast horizons, uncertainty, operating-domain flags, and traceable supporting measurements. This benchmark does not issue autonomous cleaning instructions.
07

Reproduce and challenge the evidence

What the experiment tests

Thermal-physics inversion, causal forecast initialization, learned fouling growth, campaign holdouts, threshold-event scoring, and sensitivity to sensing and operating conditions.

What remains to be established

Transfer to actual fluids and exchanger geometry, uncertainty under real operator interventions, sensor drift, unobserved blend changes, and a measurable benefit against a site's current maintenance practice.

Inspect the full run manifest
{
  "project": "Fouling Forecast",
  "data": "Entirely synthetic; no refinery measurements",
  "data_seed": 20261105,
  "seeds": 5,
  "origin_day": 20,
  "end_day": 110,
  "horizon_days": 90,
  "threshold": 0.8,
  "split_counts": {
    "calibration": 20,
    "nominal": 20,
    "shift": 24,
    "train": 24
  },
  "learning_sizes": [
    2,
    4,
    8,
    16
  ],
  "interval_method": "8 campaign bootstrap grey fits, calibrated by maximum standardized temperature error across each calibration campaign; all other models use unscaled campaign maxima. 20 calibration campaigns, order statistic 20 of 20 for nominal 95% simultaneous trajectory coverage. Guarantees assume exchangeability and do not extend to shifted campaigns.",
  "timing_metric": "MAE only among eligible campaigns where both true and forecast crossing occur; always read alongside crossing recall/precision. Right-censored events remain NaN. Campaigns already below threshold at issue day excluded from event metrics.",
  "future_conditions": "All predictions hold last-five-observation median operating conditions fixed; future measured controls never provided.",
  "training_label": "Fouling rate estimated by inversion and smoothing of training sensors; no generator rate or true resistance enters learner. Calibration uses noise-free simulator temperature as evaluation target.",
  "version": {
    "numpy": "2.5.4",
    "scipy": "1.18.1",
    "pandas": "3.1.1",
    "scikit-learn": "1.9.1"
  },
  "python": "3.12.11",
  "runtime_seconds": 56.74,
  "source_sha256": "db8482868a5707c29f03f46626cf15bbc60c24b743eb25afea6a2ed54c8246c3",
  "runs": [
    {
      "seed": 0,
      "training_ids": [
        "C000",
        "C002",
        "C003",
        "C004",
        "C006",
        "C008",
        "C010",
        "C011",
        "C012",
        "C016",
        "C018",
        "C019",
        "C020",
        "C021",
        "C022",
        "C023"
      ],
      "calibration_ids": [
        "C024",
        "C025",
        "C026",
        "C027",
        "C028",
        "C029",
        "C030",
        "C031",
        "C032",
        "C033",
        "C034",
        "C035",
        "C036",
        "C037",
        "C038",
        "C039",
        "C040",
        "C041",
        "C042",
        "C043"
      ],
      "calibration_rank": 20,
      "calibration_scores": {
        "Persistence": 11.985043608895921,
        "Causal trend": 4.427685177221804,
        "Fixed rate": 5.132247848686006,
        "Direct ML": 4.462466969961895,
        "Black hybrid": 3.956085058290512,
        "Grey hybrid": 21.88460152746558,
        "White hybrid": 4.04607605415714
      }
    },
    {
      "seed": 1,
      "training_ids": [
        "C001",
        "C002",
        "C003",
        "C004",
        "C005",
        "C007",
        "C010",
        "C011",
        "C012",
        "C015",
        "C016",
        "C017",
        "C020",
        "C021",
        "C022",
        "C023"
      ],
      "calibration_ids": [
        "C024",
        "C025",
        "C026",
        "C027",
        "C028",
        "C029",
        "C030",
        "C031",
        "C032",
        "C033",
        "C034",
        "C035",
        "C036",
        "C037",
        "C038",
        "C039",
        "C040",
        "C041",
        "C042",
        "C043"
      ],
      "calibration_rank": 20,
      "calibration_scores": {
        "Persistence": 11.985043608895921,
        "Causal trend": 4.427685177221804,
        "Fixed rate": 5.140706651038158,
        "Direct ML": 4.669159068707245,
        "Black hybrid": 3.6626507452436954,
        "Grey hybrid": 14.349985012544911,
        "White hybrid": 4.092987051030661
      }
    },
    {
      "seed": 2,
      "training_ids": [
        "C000",
        "C002",
        "C006",
        "C007",
        "C010",
        "C011",
        "C012",
        "C013",
        "C014",
        "C015",
        "C016",
        "C018",
        "C019",
        "C020",
        "C022",
        "C023"
      ],
      "calibration_ids": [
        "C024",
        "C025",
        "C026",
        "C027",
        "C028",
        "C029",
        "C030",
        "C031",
        "C032",
        "C033",
        "C034",
        "C035",
        "C036",
        "C037",
        "C038",
        "C039",
        "C040",
        "C041",
        "C042",
        "C043"
      ],
      "calibration_rank": 20,
      "calibration_scores": {
        "Persistence": 11.985043608895921,
        "Causal trend": 4.427685177221804,
        "Fixed rate": 5.064080321867493,
        "Direct ML": 3.9820064203435663,
        "Black hybrid": 4.242948728986676,
        "Grey hybrid": 13.784499250792058,
        "White hybrid": 4.057253498633656
      }
    },
    {
      "seed": 3,
      "training_ids": [
        "C000",
        "C001",
        "C002",
        "C003",
        "C006",
        "C008",
        "C009",
        "C010",
        "C011",
        "C012",
        "C013",
        "C015",
        "C017",
        "C018",
        "C022",
        "C023"
      ],
      "calibration_ids": [
        "C024",
        "C025",
        "C026",
        "C027",
        "C028",
        "C029",
        "C030",
        "C031",
        "C032",
        "C033",
        "C034",
        "C035",
        "C036",
        "C037",
        "C038",
        "C039",
        "C040",
        "C041",
        "C042",
        "C043"
      ],
      "calibration_rank": 20,
      "calibration_scores": {
        "Persistence": 11.985043608895921,
        "Causal trend": 4.427685177221804,
        "Fixed rate": 5.794727325860322,
        "Direct ML": 5.590206933502941,
        "Black hybrid": 4.2091571361413,
        "Grey hybrid": 19.249048590277273,
        "White hybrid": 4.243004333376803
      }
    },
    {
      "seed": 4,
      "training_ids": [
        "C000",
        "C001",
        "C005",
        "C007",
        "C008",
        "C009",
        "C010",
        "C011",
        "C013",
        "C015",
        "C016",
        "C017",
        "C018",
        "C019",
        "C020",
        "C022"
      ],
      "calibration_ids": [
        "C024",
        "C025",
        "C026",
        "C027",
        "C028",
        "C029",
        "C030",
        "C031",
        "C032",
        "C033",
        "C034",
        "C035",
        "C036",
        "C037",
        "C038",
        "C039",
        "C040",
        "C041",
        "C042",
        "C043"
      ],
      "calibration_rank": 20,
      "calibration_scores": {
        "Persistence": 11.985043608895921,
        "Causal trend": 4.427685177221804,
        "Fixed rate": 5.656132469501813,
        "Direct ML": 5.757936372945039,
        "Black hybrid": 3.9041593133903802,
        "Grey hybrid": 14.146681951910846,
        "White hybrid": 4.209430874849943
      }
    }
  ]
}
Static campaign figure for exportIllustrative held-out campaign: actual and blind forecast duty.