Method
MFC (served by the API) — calibrated material table
Two MFC models are in use. The lab MFC tiles use mfc-butler-volmer-monod-v2; /api/ml/predict, the MCP server and the chat assistant use Enhanced_MFC_Experimental. For the same design they can differ. Whether to unify them is an open decision for the maintainers. mfc-butler-volmer-monod-v2
What it predicts
Areal power density, coulombic efficiency, cell voltage and current density for an MFC as served by /api/ml/predict, the MCP server and the chat assistant. An empirical lookup over anode and cathode materials, not an electrochemical model.
Governing relations
Each relation is transcribed from the implementation. Where the code cites no source, the source line says so.
Areal power (mW/m²) Source: Hand-calibrated material table, cathode-enhancement and synergy multipliers in enhanced-performance-models.ts; the file cites no source (calibration note 2026-07).
Symbol Meaning Unit areal power density, clamped to the MFC range mW/m² per-material base power from the hand-calibrated table; the catalog peak power for a material with no entry mW/m² anode × cathode synergy multiplier from a pair table; 1.0 for a pair not listed 1 temperature and pH factors below 1 Worked example
These inputs, passed to the predictor, return the output below. A test re-runs the example on every change, so this number is the one the code produces.
input value unit anode carbon-felt material cathode pt-c material temperatureC 25 °C ph 7 pH Output · powerOutput = 3,172 mW/m², within ±0.1 %
By hand · Carbon felt 2600 and Pt/C 3800 mW/m² base power: 2600 × min(1 + 0.3 × 3800/2600, 2) = 2600 + 1140 = 3740. Synergy 1.1 gives 4114. f_T = exp(−|25 − 30| / 20) = exp(−0.25) = 0.7788; pH_opt = (7.2 + 7.0)/2 = 7.1, so f_pH = exp(−0.01) = 0.9900. P = 4114 × 0.7788 × 0.9900 = 3172 mW/m², inside [50, 30000].
Reproduce · Pinned by libs/shared/ml/src/__tests__/served-mfc-registry.test.ts. Run it from the repository root:
pnpm exec jest -c libs/shared/electrochemistry/jest.config.js served-mfc-registry.test.ts -t "powerOutput"
Temperature factor Source: Exponential decay in enhanced-performance-models.ts (calculateTemperatureFactor); no source cited.
Symbol Meaning Unit operating temperature °C the MFC profile’s optimum temperature °C pH factor Source: Gaussian factor in enhanced-performance-models.ts (calculatePHFactor); no source cited.
Symbol Meaning Unit operating pH pH mean of the anode and cathode table optima; 7.0 for a material with no entry pH Coulombic efficiency (%) Source: Base CE 65.2 % ("average from experimental data") and Gaussian factors in enhanced-performance-models.ts (predictCoulombicEfficiency); no source cited.
Symbol Meaning Unit coulombic efficiency, clamped to [10, 95] % catalog conductivity of the anode; above 2,000 S/m it no longer limits CE S/m operating temperature °C operating pH pH Cell voltage heuristic (V) Source: Heuristic in serverless-predictor.ts ("typical MFC: 0.2–0.8 V"); no source cited.
Symbol Meaning Unit cell voltage, a heuristic of power, not a polarisation solve V areal power density from the first relation mW/m² Current density (mA/m²) Source: Definition of electrical power, P = j·V.
Symbol Meaning Unit current density mA/m² areal power density mW/m² cell voltage heuristic V
Assumptions and constants
- P_anode and P_cathode are per-material base powers from a hand-calibrated table. Calibration note (2026-07): they are the TYPICAL areal power a cell on that material reaches, rescaled from record values (one 636 W/m² novel-electrode paper) to the literature-typical 0.1–2 W/m² band; the material ordering and the temperature, pH and synergy multipliers were kept.
- s(anode, cathode) is a synergy multiplier from a small pair table; a pair not listed is 1.0.
- A catalog material with no table entry uses the catalog peak power density as its base power, pH optimum 7.0 and a paper count of 1.
- σ_anode is the catalog conductivity in S/m.
- Power confidence = min(0.95, (papers_anode + papers_cathode) / 30 + 0.5) from the table paper counts; CE confidence is the anode table reliability (0.7 for a material with no entry); voltage and current carry a fixed 0.9.
Corrections applied
None stated in the source.
The predictor’s source file declares nothing in this section, so nothing is hidden here. Add it to the registry entry to show it.
Not modelled
- No electrode kinetics: power does not depend on overpotential, substrate, COD, HRT or geometry.
- The anode surface area is accepted but unused (area factor 1.0).
- Voltage and current are a heuristic of power, not a polarisation solve.
- The table carries a per-material temperatureCoeff that no calculation reads; temperature acts only through f_T.
Literature anchors in the source
None stated in the source.
The predictor’s source file declares nothing in this section, so nothing is hidden here. Add it to the registry entry to show it.
Implementation
libs/shared/ml/src/enhanced-performance-models.ts
Interval the predictor ships
none — The predictor ships no band of its own. Served through /api/ml/predict, power, current, coulombic efficiency and COD removal get the benchmark out-of-fold band below, or no interval when no benchmark cell is large enough. Voltage gets no interval. How served intervals are built
Calibrated material table
The base powers and pH optima the served number is computed from, as the code holds them.
Anodes
| material | base powermW/m² | pH optimum | papers | reliability |
|---|---|---|---|---|
| copper-cathode | 2800 | 7 | 5 | 0.85 |
| carbon-felt | 2600 | 7.2 | 12 | 0.95 |
| graphite-plate | 1700 | 7 | 8 | 0.9 |
| carbon-cloth | 1500 | 7.1 | 15 | 0.9 |
| cnt-mat | 4200 | 7 | 6 | 0.8 |
| nickel-foam | 1300 | 6.8 | 3 | 0.85 |
Cathodes
| material | base powermW/m² | pH optimum | papers | reliability |
|---|---|---|---|---|
| pt-c | 3800 | 7 | 18 | 0.95 |
| fe-n-c | 2400 | 7.2 | 8 | 0.8 |
| copper-cathode | 2000 | 7 | 4 | 0.85 |
| plain-carbon | 1200 | 7.1 | 10 | 0.9 |
| activated-carbon | 1600 | 7.5 | 7 | 0.85 |
Calibration artifacts used when served
- Benchmark out-of-fold residual quantiles: bes-benchmark-v1 · gkf5 · generated 2026-09-09
- Split-conformal calibration: split-conformal · generated 2026-05-21
- Hierarchical-priors v2 trust snapshot: populated · generated 2026-05-16
Benchmark cells for this predictor’s systems
Each row is a stratum with n ≥ 30 residuals at nominal level 90%. Coverage is the cross-validated share of held-out points inside the band.
| target | stratum | n | papers | coverageCV |
|---|---|---|---|---|
| cod_removal | MFC | 602 | 172 | 88.5% |
| cod_removal | MFC|bioremediation | 46 | 8 | 56.5% |
| cod_removal | MFC|power_generation | 134 | 41 | 88.8% |
| cod_removal | MFC|unknown | 53 | 8 | 85.7% |
| cod_removal | MFC|wastewater_treatment | 360 | 113 | 87.8% |
| coulombic_efficiency | MFC | 301 | 97 | 89.7% |
| coulombic_efficiency | MFC|power_generation | 107 | 31 | 86.9% |
| coulombic_efficiency | MFC|unknown | 30 | 10 | 73.7% |
| coulombic_efficiency | MFC|wastewater_treatment | 135 | 48 | 77.0% |
| current_density_areal | MFC | 496 | 134 | 89.3% |
| current_density_areal | MFC|power_generation | 208 | 54 | 88.0% |
| current_density_areal | MFC|unknown | 49 | 14 | 83.7% |
| current_density_areal | MFC|wastewater_treatment | 201 | 57 | 85.6% |
| power_density_areal | MFC | 871 | 245 | 88.9% |
| power_density_areal | MFC|bioremediation | 49 | 9 | 69.4% |
| power_density_areal | MFC|power_generation | 343 | 114 | 89.5% |
| power_density_areal | MFC|unknown | 106 | 24 | 85.8% |
| power_density_areal | MFC|wastewater_treatment | 350 | 91 | 85.4% |
Prior trust by served parameter
The state the lab badge shows for each served parameter and system, from the v2 priors fit.
| parameter | system | state | papers | prior |
|---|---|---|---|---|
| power_density_areal | MFC | curated | 275 | weakly_informative |
| current_density_areal | MFC | curated | 150 | weakly_informative |
| coulombic_efficiency | MFC | curated | 96 | literature |
| cod_removal | MFC | calibrated | 183 | weakly_informative |
Scientific-rigor gates
pnpm verify:science runs these rules over the committed priors and validation artifacts in pre-commit. Known violations are baselined per rule and slug; a new one blocks the commit. Baseline from hierarchical-priors-v2.json@2026-10-26T00:10:47.721880+00:00.
| rule | baselined |
|---|---|
| gate-honestyNo parameter may pass a rounded-threshold gate read while converged=false | 1 |
| support-containmentBounded quantities must have ci95 inside physical support, width <= range | 3 |
| magnitude-sanityNo ci95 bound may exceed the plausibility ceiling (1.0e+6) | 0 |
| slug-uniquenessNo two slugs may share a spelling-independent identity; scale must agree | 2 |
| secondary-source-purityNo fitted prior may carry a REVIEW (secondary-source) stratum | 0 |
| artifact-pairingEach fit must have its own coverage evidence; the served fit must have some | 0 |
| coverage-sharpnessAny coverage figure must ship its interval width alongside | 0 |
| interval-calibrationHeld-out interval coverage per parameter may not newly degrade | 128 |
| effects-gap-completenesseffects.json is schema 2.0; every non-high effect has a gap per archetype; no gap is "high" | 0 |