ES
← Back to Portfolio
Mining Analytics September 2026

OreFlow, a Grinding and Separation Circuit Read as One Balance

In a processing plant a change made in one stage, a finer grind or a different classifier cut, moves every stage after it, and each area reports only its own part. OreFlow keeps the circuit as one balance: every stream carries the mass flow of every mineral in 63 size classes plus water, the grinding circuit is closed (an energy-specific population-balance ball mill with Plitt cyclones), separation runs through flotation banks, a gravity bleed, magnetic drums or desliming, and every unit closes within 1e-9. Twelve authored ore and plant scenarios with 96 variants; the workbench re-solves the circuit in the browser on every control change, and its optimizer and seeded uncertainty re-run there too, beside baked kinetic fits, Sobol sensitivity and five learned surrogates. 52 real ore samples and the hours of an iron-ore plant are workbench sources. Authored scenarios, not a calibrated plant.

Engine
Whiten crusher; energy-specific population-balance ball mill with Plitt hydrocyclones, underflow returned; flotation banks, gravity bleed, LIMS drums, desliming; 63 size classes per mineral plus water; every unit closed within 1e-9
Cases
12 authored cases, 8 variants each (96: six change one input, two hold the classifier cut), four circuit families: rougher (copper, zinc, nickel, other sulphide or oxide ores), gravity plus rougher (free-milling gold), magnetic (fine magnetite), deslime plus rougher (phosphate with clay slimes)
Method records
Kinetic fits; a pattern-search optimizer with a progressive barrier over recovery, grade, energy, water and reagent limits, live in the browser; seeded Latin-hypercube uncertainty, live at any seed; Sobol sensitivity (SALib); mechanism ablations; five learned surrogates scored by interpolation and by leave one case out, with an autoencoder guard; ONNX exports reproduced bit for bit on a re-run
Gates
490 Python tests, 323 frontend tests, 8 guards, the use-case page check, a case-rules test and a manuscript-claims test, a browser gate of 924 checks (3 viewports, 2 themes, 2 languages, phone and tablet) and 194 against each public host; one contract of 791 probes for validator, API and browser
Checked against
Published examples labelled as such: Moly-Cop BallSim, GMG Bond worked examples, the Laplante gravity example, the Zandrivierspoort magnetite tests
Deploy
FastAPI and uvicorn on the ML VPS (the site, read-only records, a contract-validated simulate endpoint) with a GitHub Pages mirror; version 0.07.000; MIT for authored code and content; part of the Faena hub
Architecture diagram of OreFlow, a Grinding and Separation Circuit Read as One Balance
#mineral-processing #grinding #flotation #mass-balance #population-balance #sobol #surrogates #onnx #mining #faena

Business Context

OreFlow exists to show that in a mining process a local decision has global effects, so an integral view of the circuit is required. An operating point is chosen against the limits every area owns at once, and checked again with a harder ore and a shifted classifier cut; the workbench keeps the circuit in the units every area reads, tonnes per hour of metal, megawatts, cubic metres of water and kilograms of reagent, so the grinding lead, the flotation lead and the plant manager look at the same balance. The evidence boundary is stated on the site: the cases are authored inside sourced ranges, each range naming its source or labelled as authored, and are not calibrated plants; two measured lanes, the HZDR particle dataset (RODARE 336) and 52 GeoMet locked-cycle tests (Zenodo 7051975), are kept apart from the engine and do not calibrate it; the learned lane's held-out-case scores bound transfer between authored plants, not to real ones. Applying it to a specific plant needs that plant's own metallurgical tests.

Strategic Value

The 0.05.000 release rebuilt the engine as a closed-circuit, size-by-mineral flowsheet simulator and rebuilt the product on it. The 0.06.000 release acted on an audit of its own science: the mineral grindabilities had let a soft bulk mineral override the ore's Bond work index, understating grinding energy up to 1.9 times, and now every nominal case grinds at 0.83 to 0.91 of Bond's efficiency, held by a test; checking every case against its source found seven outside the ranges their sources give, not the three the audit named, and all seven were re-authored inside them; every plausibility range now names its source, and a claims test holds the manuscript draft to the records (the previous draft fails six of its seven tests). The 0.07.000 release (2026-09-30) completed the validated plan the audit had found missing: the live optimizer and uncertainty, the classifier cut as a control, the real samples and plant hours, the soft-sensor lane, the ablations, and the Implementation and Experiments pages at their planned tabs. Its results are reported as they came out: at the soft porphyry's operating point every real sample is harder than the ore the circuit was sized for, so the mill runs at installed power and the engine sits 20.4 points below the measured tests, where the data-driven GeoMet lane is within 5.1 to 5.5 points RMSE; on the iron-ore plant, the previous hour's assay beats every model; and the learned screen cost 8.5% more engine evaluations than the same search without it. The record is measured rather than declared: 490 Python tests, 323 frontend tests, eight standard-library guards, the use-case page check, and a Playwright browser gate of 924 checks over three viewports, two themes, two languages and phone and tablet sizes, 194 more against each public host. It is the processing member of the Faena family of public mining applications and sits beside the single-operation products (ChancaDEM for crushing, ChargeCascade for the mill charge, FrothSeg for the froth) without duplicating them. The manuscript draft reports the surrogate study and is not deposited; the design acceptance by its owner is not recorded, and the site says so.

The Challenge

The grinding area answers for throughput and energy per tonne, classification for the load it sends forward, flotation for recovery and concentrate grade. The energy of a finer grind is reported by grinding; the recovery it produces is reported by flotation. The relations between those stages are documented, energy against particle size, the size split at the classifier, flotation kinetics and the mass balance that closes the circuit, but each area reads its own indicators and a decision taken in one of them shows up as somebody else's number. A workbench that wants to follow one setting through the whole plant has to carry every stream in full, size by size and mineral by mineral, close every recycle, and re-solve fast enough to be used as an instrument rather than as a report.

Our Approach

The engine carries every stream as the mass flow of every mineral in 63 size classes plus water. It solves a Whiten crusher, a closed grinding circuit (an energy-specific population-balance ball mill with Plitt hydrocyclones, the underflow returning to the mill), and separation by flotation banks, a gravity bleed, low-intensity magnetic drums or desliming, closing every unit within 1e-9. Twelve authored cases in four circuit families (rougher for copper, zinc, nickel and other sulphide or oxide ores; gravity plus rougher for free-milling gold; magnetic for fine magnetite; deslime plus rougher for phosphate with clay slimes), eight variants each (six change exactly one declared input, two hold the classifier's cut and let the grind follow). A TypeScript port of the engine runs in a Web Worker and is held to the Python engine within 1e-6 on all 96 variants, so the workbench re-solves the circuit on every control change: the flowsheet with every stream's flow and grade, the grinding and separation curves of the current state, response sweeps over any two inputs, and a focus view for one instrument at a time. The method records: kinetic fits; a pattern-search optimizer with a progressive barrier over limits set for every area at once (recovery, concentrate grade, energy, water, reagent), written line for line in Python and TypeScript so the browser re-runs it at any weight on recovered metal; a seeded Latin-hypercube uncertainty record the browser re-runs at any seed and sample count; Sobol sensitivity; mechanism ablations; and a learned lane of five surrogates scored by interpolation and by leave one case out with an autoencoder guard. Real sources sit beside the authored cases: the 52 GeoMet locked-cycle samples run on their own assays, Bond work index and a sulphur-limited normative mineralogy in the soft porphyry's circuit, next to the measured recovery, and the hours of one iron-ore plant (CC0) with a next-hour silica soft sensor. One operating contract (791 probes) serves the validator, the FastAPI simulate endpoint and the browser. The engine is checked against published examples (Moly-Cop BallSim, GMG Bond worked examples, the Laplante gravity example, the Zandrivierspoort magnetite tests), labelled as examples.

Key Performance Indicators

KPIBaselineResultImpact
One balance for the whole circuitEach area reports its own indicators; a decision in one shows up as another's numberEvery stream carried as 63 size classes per mineral plus water; the grinding circuit closed; every unit within 1e-9; a setting followed through every stage after itGrinding, classification and flotation read the same numbers
An instrument, not a reportA circuit solved offline and summarisedA TypeScript port in a Web Worker held to the Python engine within 1e-6 on all 96 variants re-solves the circuit on every control change; the optimizer and the seeded uncertainty re-run there tooBounded live what-if analysis in the browser
The boundary, statedA simulator presented as a plantAuthored cases inside sourced ranges, each range naming its source; the measured lanes (HZDR RODARE 336, GeoMet Zenodo 7051975) kept apart and not used to calibrate; held-out scores bound transfer between authored plants onlyA specific plant needs its own metallurgical tests, and the site says so

Architecture

oreflow pipeline

oreflow pipeline

Technology Stack

Python NumPy SciPy SALib scikit-learn PyTorch ONNX FastAPI TypeScript React Vite uPlot KaTeX onnxruntime-web

Application Screenshots

OreFlow, a Grinding and Separation Circuit Read as One Balance
OreFlow, a Grinding and Separation Circuit Read as One Balance