CoolFace
Apppublic

lugasraka/combustiontwin

sourceHugging Facemitupdated 28d agoView on Hugging Face
0likes
App README

CombustionTwin

A prototype digital twin and prescriptive setpoint optimizer for waste-to-energy reciprocating-grate combustion. It simulates plant telemetry, trains a PyTorch surrogate of the combustion process, and uses that surrogate to recommend primary air, secondary air, and grate speed setpoints.

[image]

Live demo

The studio runs on Hugging Face Spaces: https://huggingface.co/spaces/lugasraka/combustiontwin

It runs on ZeroGPU hardware, but all inference is CPU-class, so visitors consume no GPU quota.

How it works

  1. 1.Synthetic SCADA simulator (src/data/physics_simulator.py) generates 1-minute telemetry for a 4-zone grate line, including latent waste LHV and moisture, actuator settings, and flue-gas composition.
  2. 2.PyTorch models (src/models/) define a temporal-attention virtual calorimeter and a physics-informed combustion surrogate.
  3. 3.Prescriptive optimizer (src/optimization/prescriptive_engine.py) solves for setpoints with SciPy SLSQP. Each candidate setpoint is evaluated by rolling the surrogate forward over a 15-step horizon, tracking the steam target while the furnace stays above the legal temperature limit.
  4. 4.Gradio studio (src/app/gradio_app.py) presents all of it in four tabs: live digital twin, model diagnostics, prescriptive sandbox, and MLOps drift monitoring.
mermaid
flowchart LR
	SCADA["GrateSimulator<br/>1-minute synthetic SCADA"]
	FRAME["SCADA DataFrame<br/>telemetry + actuators + latent labels"]
	SCADA --> FRAME

	subgraph TRAIN["Optional training pipeline"]
		CAL_DATA["CalorimeterDataset<br/>15-minute window x 12 features"]
		CAL["VirtualCalorimeterLSTM<br/>LHV + moisture estimate"]
		SUR_DATA["SurrogateDataset<br/>state 8 + control 6"]
		SUR["CombustionDynamicsSurrogate<br/>settled response: 5 outputs"]
		ART["artifacts/<br/>model weights + scalers"]
		FRAME --> CAL_DATA --> CAL
		FRAME --> SUR_DATA --> SUR --> ART
	end

	subgraph RUN["Runtime: Gradio studio"]
		INPUT["Scenario inputs<br/>feedstock, feed rate, steam target"]
		OPT["PrescriptiveOptimizer<br/>SciPy SLSQP, 15-step rollout"]
		ENGINE{"Surrogate artifacts<br/>available?"}
		NN["PyTorch surrogate"]
		FALLBACK["Analytical surrogate<br/>fallback"]
		RESULT["Dispatch recommendation<br/>primary air, secondary air, grate speed"]
		INPUT --> OPT --> ENGINE
		ENGINE -->|yes| NN
		ENGINE -->|no| FALLBACK
		NN --> RESULT
		FALLBACK --> RESULT
	end

	ART -. loaded at startup .-> ENGINE
	FRAME -. live telemetry .-> RUN
	CAL -. optional diagnostic only .-> RESULT

Trained weights ship in artifacts/ (deterministic, seed 42). If they are missing, the app falls back to an analytical surrogate so it always launches.

Project layout

configs/                     # plant thresholds and model hyperparameters
data/raw, data/processed/    # generated synthetic data
src/data/                    # simulator and dataset loaders
src/models/                  # virtual calorimeter, combustion surrogate, training
src/optimization/            # prescriptive optimizer
src/app/                     # Gradio studio and plotting helpers
artifacts/                   # trained weights and scalers
tests/                       # unit tests
run_demo.py                  # app entrypoint

Quickstart

Requires Python 3.11 or newer (built and tested on 3.13).

pip install -r requirements.txt "gradio==6.25.0"
python run_demo.py             # open http://localhost:7860
pytest                         # 45 tests
python -m src.models.train     # optional: regenerate artifacts/

Gradio is absent from requirements.txt on purpose: Hugging Face Spaces install it according to the Space's sdk_version, and listing it again breaks their dependency resolution. Pin your local version to match the Space runtime.

Design notes and limitations

  • The synthetic data favors a readable demo over plant fidelity: actuators were calibrated so the optimizer shows visible control authority.
  • The 850 °C furnace minimum is a legal floor, not a comfort margin. It was softened from an 875 °C design value so low-LHV feedstock (which only reaches about 872 °C) stays feasible. The optimizer enforces it as a hard constraint.
  • The surrogate runs in float32, so its outputs carry roughly 1e-3 of numerical noise. The optimizer sets its finite-difference step above that noise floor.
  • The virtual calorimeter is trained and, when artifacts are present, wired into the Prescriptive Sandbox via Auto-estimate LHV (checkbox) — inferred LHV/moisture from the live 15-min window is shown against the true latent value; falls back to manual selection when artifacts are missing.
  • The sandbox now shows a before→after delta table, 15-step horizon convergence, and a €/h projected margin (steam, fan, NOx) using plant.economics from configs/config.yaml; the diagnostics tab shows control-authority sensitivities and a p_air × grate 2D contour (Steam/Temp/O₂) sampling the surrogate grid 31×21, and the MLOps drift monitor uses true synthetic residuals when the NN twin is active.
  • Field-level data contracts (window, state, control, response shapes), the equilibrium equations used for training, and the full optimizer objective are documented in `methodology.md`. The original design narrative lives in CombustionTwin_PyTorch_Gradio_Implementation_Plan.md.