EcoSym

Parameter Reference

A consolidated reference for every rate constant, half-saturation, stoichiometric ratio, tolerance threshold, and calibrated coefficient used in the EcoSym simulator.

For each parameter the table gives one of:

  • a literature citation (verbatim author-year string, taken from the rationale comment next to the parameter in the source code), or
  • a category citation ("Redfield ratio", "universal phytoplankton anchor", "ASM2d default", "wastewater nitrifier literature range"), or
  • a relative-to-species rationale ("2× greens because diatoms are Zn-hungrier"), or
  • an explicit "no direct source" along with how the value was derived — hand-tuned for a calibration target, estimated by analogy to a similar species, or carried forward from an earlier version of the model.

Long rationale comments in the code have been compressed to roughly one sentence per row. The authoritative explanation for any number is the inline comment next to the parameter in the corresponding species/*.py or processes/*.py file — this page is an index, not a replacement.

Per-section symbol glossaries spell out the local conventions. Across the doc, subscripted forms like Q_N,max or K_NH4 read as in the literature with commas replacing the conventional subscript for plain-text readability; ratios like "Fe:C" are mol/mol. Where a parameter has no canonical literature symbol — internal calibration knobs like "Nocturnal feeding fraction", "Feces → suspended fraction", "Dispersal fraction" — the row uses a short English label instead.

How this page is kept in sync with the code

This doc is intentionally not auto-generated. It is filled in by hand after reading each species/*.py and processes/*.py file. The trade-off is that auto-generation would lose the literature attribution that lives in comments, and the rationale string for every "hand-tuned" value would have to be machine-readable, which is far more invasive than necessary.

When a parameter is added, removed, or changed in species/ or processes/, the relevant row in this page should be added / removed / updated as part of the same change. This is called out in the project CLAUDE.md. The convention is: if a code change touches a numeric parameter and you can describe why the new value is what it is, update this page; the explanation belongs next to the number, not buried in a commit message.

Contents

  • Producers — green algae, diatoms, cyanobacteria
  • Macrophytes — floating, submerged, rooted
  • Consumers — rotifers, daphnia, copepods, ostracods, ciliates, nanoflagellates, amphipods, snails, shrimp, hydra; the invertebrate roster (35 species) is GENERATED, with per-species numbers in parameter_reference_generated_inverts.md
  • Fish — the shared health ODE, bioenergetic condition, and external feed; the roster (982 species) is GENERATED, with per-species numbers in parameter_reference_generated_fish.md. The section also covers botanicals, the second external organic input
  • Microbes — nitrifiers, heterotrophs, sediment anaerobes (denitrifier, DNRA, Fe-reducer, sulfate reducer, methanogen), fungi
  • Biogeochemical & Physical Processes — soil/sediment chemistry, water-column redox, gas exchange, allelopathy decay, biofilm maturity, bioturbation
  • Surfaces — filtration & forced convection — mass transfer, gas exchange, mechanical capture, filter cleaning
  • Cycling stage — the starting inoculum — how a tank was started, and what each method is worth

Producers

Producers — green algae, diatoms, and cyanobacteria — share a common kinetic skeleton: light- and temperature-modulated photosynthesis, Monod uptake on dissolved nutrients, Droop-style internal storage of N and P, trace-metal Liebig gates, and stress/lethal envelopes on temperature, pH, and salinity. The conventions below recur across every producer table; subsequent species sections only spell out the rationale, not the formalism.

Producer symbol glossary

Symbol Meaning
P_max Maximum specific photosynthetic rate at T_ref, saturating light, no nutrient limitation. Equivalent to μ_max in most texts.
I_K Light half-saturation irradiance for photosynthesis (µmol photons m⁻² s⁻¹)
K_X Monod half-saturation for substrate X (CO₂, HCO₃⁻, NH₄⁺, NO₃⁻, PO₄, DSi, trace metals, allelochemicals)
V_X,max Maximum cellular uptake rate of X per unit cellular C (luxury-uptake ceiling)
Q_X,min / Q_X,max Minimum and maximum cellular X:C quota (Droop internal-store kinetics)
Fe:C, Mo:C, ..., C:N, N:P, Si:N Cellular stoichiometric ratios (mol/mol)
Sc/o RuBisCO CO₂-vs-O₂ specificity factor (dimensionless)
PQ Photosynthetic quotient — mol O₂ evolved per mol C fixed
CCM efficiency Fraction of inorganic C drawn from HCO₃⁻ via the carbon-concentrating mechanism, vs free CO₂
Q10 Multiplicative rate increase per 10 °C; subscripted by process (photo, resp, mort, uptake)
T_opt Thermal optimum for photosynthesis (°C)
T_stress (low / high) Onset of thermal stress; mortality begins ramping (°C)
T_lethal (low / high) Acute thermal lethal threshold (°C)
T_lethal,photo Temperature above which photosynthesis ceases (°C)
S_opt, σ_S Salinity optimum and Gaussian tolerance breadth (PSU)
R_maint Maintenance respiration rate (mol O₂ per mol cellular C per hour)
m_base Baseline (non-stress) mortality rate (per hour)
m_X,max Maximum mortality rate from stressor X (thermal, pH, salinity, viral, hypoxia) per hour
DOC excretion fraction Fraction of fixed C excreted as labile DOM (Fogg 1983 healthy-cell range 5–30%)
Allelo release fraction Fraction of net production released as polyphenol or cyanotoxin allelochemical
Mat self-shading coefficient Beer-Lambert attenuation through dense filamentous biomass (m² per mol biomass C)

Notation: subscripted forms (Q_N,max, K_NH4) read as in the literature, with commas replacing the conventional subscript for plain-text readability. Ratios like "Fe:C" are mol/mol. Where a parameter has no canonical literature symbol — EcoSym-internal calibration knobs like NO₃-uptake dark/light preference, biofilm detachment multiplier, or lysis-product routing fractions — the row uses a short English label.


Shared producer base

Anchors universal to every photoautotroph in the model — concrete species override individual rows where they are known to deviate from the anchor.

Trace metal:C anchors

Symbol Value Units Source / Rationale
Fe:C 2.0e-5 mol Fe / mol C Quigg et al. 2003 — universal detritus anchor for eukaryotic phytoplankton
Mo:C 1.0e-8 mol Mo / mol C Catalytic anchor; three orders below Fe — one atom per nitrate reductase / nitrogenase α₂β₂ core
Zn:C 4.0e-7 mol Zn / mol C Quigg 2003, Sunda & Huntsman 1995 — universal anchor (~0.4 µmol/mol); carbonic anhydrase
Cu:C 5.0e-8 mol Cu / mol C Quigg 2003, Sunda & Huntsman 1995 — plastocyanin / cyt c oxidase anchor
K:C 2.5e-2 mol K / mol C Sterner & Elser 2002, Karley & White 2009 — dominant intracellular cation
Ni:C 1.0e-7 mol Ni / mol C Quigg 2003, Sunda & Huntsman 1995 — urease cofactor anchor
Co:C 5.0e-9 mol Co / mol C Quigg 2003, Sunda & Huntsman 1995 — vitamin B12 anchor (rarest tracked trace metal)
B:C 5.0e-6 mol B / mol C Reynolds 2006, Bowen 1979 — structural cell-wall / frustule / heterocyst-envelope B
S:C 5.0e-3 mol S / mol C Sterner & Elser 2002, Redfield-extended — protein / glutathione / Fe-S clusters

Trace-metal Monod half-saturations

Symbol Value Units Source / Rationale
K_Fe 1.0e-8 mol/L Half-sat for Fe uptake (~0.5–1 µg/L for most algae)
K_Mo (NO₃ reductase) 2.0e-9 mol/L Cole 1976; Howarth & Cole 1985 — 1–5 nM Mo for nitrate reductase
K_Zn (carbonic anhydrase) 1.0e-8 mol/L Sunda & Huntsman 1992, 1995 — ~10 nM CA-activity half-sat
K_K 5.0e-6 mol/L Healey 1973; Reynolds 2006 — middle of 1–20 µM range

Droop internal stores

Symbol Value Units Source / Rationale
Q_P,min 0.005 mol P / mol C Reynolds 2006; Sterner & Elser 2002 — 50% of Redfield structural P (cell-division floor)
Q_P,max 0.030 mol P / mol C Reynolds 2006; Sterner & Elser 2002 — 3× structural (polyphosphate-saturated)
V_P,max 0.02 mol P / (mol C · h) Healey 1973, Reynolds 2006 — mid-range for greens
K_PO4 (uptake) 5.0e-8 mol/L Tight half-sat — transporters saturate against scarce P
Q_N,min 0.02 mol N / mol C Reynolds 2006; Sterner & Elser 2002 — generic green phytoplankton
Q_N,max 0.15 mol N / mol C Reynolds 2006; Sterner & Elser 2002 — generic greens (diatom / cyano subclasses raise)
V_N,max 0.05 mol N / (mol C · h) Healey 1973, Goldman & McCarthy 1978, Falkowski & Raven 2007 — mid-range for greens
Q10 (uptake) 2.0 Eppley 1972 — transporter Q10 for V_N,max / V_P,max
k_catab (storage) 0.001 /h Reynolds 2006 (polyphosphate t½ ~weeks); Allen 1984 / Mackerras 1990 (cyanophycin t½ ~days)
C_g (luxury viability gate) 1.0e-9 mol C Numerical conditioning, not biology. Multiplies luxury uptake by C²/(C_g²+C²) so a functionally-dead cell pool loses its biomass-independent luxury Jacobian mode (LSODA die-off stiffness; see internal_docs/planning/performance.md 2026-06-12). ~1000× below any viable biomass / seed inoculum, so live cells are bit-identical and only extinct pools are quenched. Mass-conserving (scales both sides of the flux).

Carbon kinetics

Symbol Value Units Source / Rationale
K_HCO3 1.0e-3 mol/L Mercado et al. 2003; Allen & Spence 1981; Madsen & Sand-Jensen 1991 — eukaryotic HCO₃⁻ transporter Km
CCM max conc factor 10.0 × ambient CO₂ CCM photorespiration relief. A bicarbonate user concentrates CO₂ at RuBisCO above bulk diffusive CO₂; photorespiration's O₂/CO₂ competition reads this elevated level (Producer._ccm_effective_co2), not bare CO₂. The effective level is the CO₂ that would, by diffusion alone, give the realized CO2_facK_CO2·CO2_fac/(1−CO2_fac) — which by construction equals ambient CO₂ exactly for a non-bicarbonate plant (so the relief is self-targeting to CCM use and inert otherwise), capped at this factor. Raven 1991; Maberly & Madsen 2002; Maberly 1996 — aquatic CCM internal:external CO₂ ratios ~3–40×; 10× conservative mid-range.

Thermal & physiological defaults

Symbol Value Units Source / Rationale
T_opt 25.0 °C Default; subclasses MUST override
T_lethal,photo 40.0 °C Default temperature at which photosynthesis ceases
DOC excretion fraction 0.05 fraction Fogg 1983 — 5–30% of fixed C excreted, routed to labile DOM
DOC excretion ceiling 0.30 fraction Backstop on the total excreted fraction, applied at all three excretion sites. Top of Fogg's (1983) 5–30% range, set deliberately above every shipped value (highest: benthic cyanobacteria 0.22) so it can never silently override a calibrated parameter. Exists because the floating-canopy space limit once routed up to 100% of net photosynthesis here — see labile DOM accumulation. For context: benthic producers exude ~10% of daily fixed C (Haas et al. 2011); seagrass/macroalgal recalcitrant exudate is 4–8% of annual NPP (Watanabe et al. 2026)

Mat / filament structure, allelopathy, viral lysis, death routing (defaults; subclasses override)

Symbol Value Units Source / Rationale
Mat self-shading coefficient 0.0 m² / mol C Disabled by default (unicellular); filamentous subclasses override
Allelo release fraction 0.0 fraction Default off; subclasses (macrophytes for polyphenol, cyano for cyanotoxin) override
Allelochemical pool polyphenol Pool selector (no-op when release fraction = 0)
m_viral,max 0.0 /h Default off; Suttle 2007, Brussaard 2004 — subclasses opt in
K_viral (host density) 1.0e-5 mol C / L Default half-sat for density-dependent encounter
Surface death → suspended 0.10 fraction Surface-attached mortality routing default

Planktonic green algae

The default freshwater unicellular green alga — fast-growing, mid-range nutrient affinity, sensitive to chloroviruses.

Growth & light

Symbol Value Units Source / Rationale
P_max 0.08 /h Griffiths & Harrison 2009 — ~1.9/day, midrange of literature 1.0–2.0/day
I_K 40.0 µmol m⁻² s⁻¹ Low — adaptation to turbid / shaded freshwater

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 7e-6 mol/L High CO2 affinity (lowered from 15e-6). Freshwater green microalgae are efficient inorganic-carbon users (CCM + low CO2 compensation point) — green-water blooms develop readily in low-tech, no-CO2 tanks, proving they are NOT carbon-starved at air-equilibrium CO2 (~14 µM). At 15 µM a modelled bloom sat only ~48% carbon-saturated (diffusion term) and could decline at ambient yet bloom under injection — backwards, and it made CO2 injection a perverse algae boost (greens out-responded every easy plant). At 7 µM the ambient diffusion term is ~0.67 (~0.85 total with HCO3) so greens bloom at ambient and gain only modestly from injection. Raven et al. 2012; Giordano et al. 2005 — microalgal CCM gives low-µM effective affinity.
CCM efficiency 0.25 fraction Giordano et al. 2005 — moderate CCM capability
K_HCO3 1.0e-3 mol/L Mercado et al. 2003 — moderate-affinity transport (sits at base default)
Sc/o 80.0 Spreitzer & Salvucci 2002 — green algae moderate CCM range
PQ 1.0 mol O₂ / mol C Photosynthetic quotient

N & P uptake

Symbol Value Units Source / Rationale
K_N (total) 4e-5 mol/L Total N half-sat for growth limitation
K_NH4 2e-5 mol/L NH₄⁺ half-sat (preferred N source)
K_NO3 8e-5 mol/L NO₃⁻ half-sat (requires reduction)
NO₃ preference (dark) 0.1 fraction Light-dependent NO₃ source preference (low in dark)
NO₃ preference (light) 0.5 fraction Light-dependent NO₃ source preference (high in light)

Stoichiometry

Symbol Value Units Source / Rationale
C:N 6.6 mol / mol Redfield-like structural C:N
N:P 16.0 mol / mol Redfield

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0012 /h Hand-tuned maintenance respiration
K_O2 (respiration) 1.25e-5 mol/L ~0.4 mg/L O₂; high affinity (algae K_m 0.16–0.64 mg/L)

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_polyphenol 1.2e-4 mol C / L ≈2.9 mg GAE/L. Nakai et al. 2000 72 h EC50s vs Microcystis (pyrogallic 0.65, gallic 1.0, ellagic 5.1, catechin 5.5 mg/L); greens sit ~3× above the cyano value because the inhibition is selective for cyanobacteria (Ridge et al. 1999; Laue et al. 2014). Rebased 2026-08-02 from 4.0e-6 ("field-effective" macrophyte-exudate signature) — the tracer is reported in gallic-acid equivalents, a pure-compound unit, so keying K 20× below the pure-compound EC50 double-counted the bioactive-fraction correction. Bergeron et al. 2025 found in-lake polyphenols 30–35 000× below inhibitory levels
K_cyanotoxin 2.0e-5 mol C / L Sukenik et al. 2002 — PSII inhibition at ~0.4 mg MC-LR/L

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 24.0 °C Goldman 1977; Reynolds 1984; Butterwick 2005; Lurling & Van Donk 2000; tuned 3 °C below cyano T_opt per Paerl & Huisman 2008
T_lethal,photo 38.0 °C Hand-tuned upper photosynthesis limit
T_ref 25.0 °C Engine reference temperature
Q10,photo 2.0 Standard
Q10,resp 2.2 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 10.0 / 35.0 °C Mayo 1997; Converti et al. 2009
T_lethal (low / high) 0.0 / 42.0 °C Freezing / hand-tuned upper
m_thermal,max 0.03 /h ~70%/day at lethal temperatures

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.0 Mayo 1997; Rachlin & Grosso 1991
pH lethal (low / high) 4.5 / 10.5 Mayo 1997; Rachlin & Grosso 1991
m_pH,max 0.03 /h ~70%/day at lethal pH

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 2.0 PSU Kirst 1990 — freshwater
σ_S 8.0 PSU Gaussian tolerance breadth
S_stress (low / high) 0.0 / 10.0 PSU No low-salinity stress; upper threshold
S_lethal (low / high) 0.0 / 25.0 PSU Freshwater fine; lethal high
m_salinity,max 0.15 /h Salinity mortality cap
Osmoregulation cost 0.003 per PSU deviation Respiratory cost multiplier

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.05 / 24 /h ~5%/day baseline
m_total,max 0.50 /h Cap on summed mortality
Death → suspended fraction 0.3 fraction 30% lysis products suspended, 70% aggregates settled
DOC excretion fraction 0.05 fraction Fogg 1983

Viral lysis

Symbol Value Units Source / Rationale
m_viral,max 0.012 /h Brussaard 2004, Van Etten et al. 2002 — chloroviruses 5–25%/day
K_viral (host density) 1.0e-5 mol C / L Standard host density half-sat

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Dispersal fraction 0.25 fraction Unicellular algae disperse readily
Settlement rate 0.001 /h Minimal active attachment (passive sedimentation)
Detachment multiplier 3.0 Easily dislodged; no holdfast
Surface death → suspended 0.20 fraction Biofilm mostly settles (80/20 settled/suspended)

Benthic green algae

Periphyton-forming greens — small cells embedded in an EPS biofilm matrix on hard substrates. (Only divergences from planktonic green algae are shown.)

Growth & light

Symbol Value Units Source / Rationale
P_max 0.065 /h Biggs 1996, Stevenson 1996 — periphyton range 0.05–0.09/h; just above diatom 0.05
I_K 25.0 µmol m⁻² s⁻¹ Biggs 1996, Hill 1996 — shade-tolerant biofilm interior
Body size 0.001 cm Fractal surface-area scaling for ~10 µm cells

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 12e-6 mol/L Lower for small efficient cells
CCM efficiency 0.30 fraction Giordano et al. 2005, Raven et al. 2012
K_HCO3 0.8e-3 mol/L Higher affinity than planktonic greens — diffusion-boundary-layer benefit

N uptake

Symbol Value Units Source / Rationale
K_N (total) 3e-5 mol/L High affinity (small cells)
K_NH4 1.5e-5 mol/L High affinity
K_NO3 6e-5 mol/L High affinity

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0015 /h Higher maintenance (small cells)
osmo_cost_per_PSU_deviation 0.003 × per PSU Osmoregulation cost multiplier required by the shared Producer maintenance kernel (PROD-1 collapse). Matches planktonic green / diatom; the former benthic fork computed maintenance inline without an osmoregulation term.

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_polyphenol 1.8e-4 mol C / L ≈4.4 mg GAE/L. ~1.5× higher than planktonic baseline (biofilm boundary protection); the ratio is unchanged, the baseline was rebased onto the Nakai EC50 band 2026-08-02. Least-sensitive class, near the ellagic-acid / catechin end (5.1 / 5.5 mg/L)
K_cyanotoxin 3.0e-5 mol C / L ~1.5× higher than planktonic baseline

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 22.0 °C Broad cool-temperate optimum for epilithic green community
T_lethal,photo 40.0 °C Hand-tuned
T_stress (low / high) 8.0 / 32.0 °C Typical freshwater periphyton
T_lethal (high) 40.0 °C Typical freshwater periphyton

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 Typical freshwater green algae
pH lethal (low / high) 5.0 / 10.0 Typical freshwater green algae
m_pH,max 0.025 /h Slightly lower than planktonic greens

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 1.0 PSU Freshwater
σ_S 6.0 PSU Narrower than planktonic
S_stress (high) 8.0 PSU Freshwater
S_lethal (high) 20.0 PSU Freshwater
m_salinity,max 0.12 /h Slightly lower than planktonic

Mortality & death routing

Symbol Value Units Source / Rationale
Death → suspended fraction 0.50 fraction Small planktonic cells fragment easily (applies to the planktonic pool; surface pools use the base surface_death_suspended_frac = 0.10)
DOC excretion fraction 0.12 fraction Fogg 1983, Hoagland et al. 1993 — elevated due to EPS biofilm matrix

PROD-1 (2026-05-31): benthic green now runs the shared Producer.flux() pipeline. The former death_to_DOM_frac = 0.20 (biofilm-lysis-to-DOM split) was removed — the base routes all mortality to detritus (its only DOM mortality path is viral lysis, which this species does not have). DON/DOP are now excreted alongside DOC. See the PROD-1 session-log entry in internal_docs/planning/tech_debt.md for the full list of adopted base conventions and the measured Walstad delta.

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Dispersal fraction 0.15 fraction Biggs 1996, Hoagland et al. 1982 — biofilm formers disperse less
Settlement rate 0.008 /h Hoagland et al. 1982, Biggs 1996 — ~19%/day; 2× diatom (EPS-mediated fast adhesion)
Detachment multiplier 0.7 Retentive (matches Cladophora; vs planktonic 3.0, diatom 1.5). Mature EPS-bound green periphyton resists continuous background erosion; in still water, biomass loss is dominated by autogenic senescence (mortality / biofilm-maturity decay) + grazing, not a steady ~15%/day sloughing bleed (Biggs 1996; Stevenson 1996; Choi & Morgenroth 2013). The former 2.0 over-bled the attached biofilm so it could not self-sustain on its own light-limited surface growth, leaving the species reliant on an artifactual water-column bloom.
Water-column dispersal photo fraction (DISPERSAL_PHOTO_FRAC) 0.15 fraction Productivity of suspended dispersal cells as a fraction of the attached community's, applied to the planktonic pool only. An epilithic alga's water-column pool is a transient dispersal/loss compartment, not a growth habitat (the mirror image of true phytoplankton, for which suspension is the growth habitat) — drifting propagules lack the biofilm microenvironment and are "at most strongly attenuated" photosynthetically (Stevenson 1996; Hoagland et al. 1982; Cox et al. 2020 — suspended benthic cells are active but transient, not a self-sustaining bloom). Combined with the surface-space gate in _extra_photo_factor, keeps the dispersal pool a small transient instead of an unbounded bloom that mislabels benthic algae as green water.

Biofilm shelter (see species/access.py::surface_protection)

Symbol Value Units Source / Rationale
biofilm_predation_protection 0.40 fraction M=1 EPS-shelter ceiling — filamentous green periphyton-formers (Cladophora, Oedogonium) build EPS-bound mats with cells partially embedded (Stevenson et al. 1996 Algal Ecology; Hoagland et al. 1993). Slightly lower than HB's 0.50 because outermost mat surface is always exposed. Same coefficient gates grazing access and the species' base + viral self-mortality.
geometric_predation_shield_scale 0.40 M=0 cold-start floor multiplier on substrate roughness — filament tangles settle into crevices
basal_refuge_frac 0.15 fraction Maturity-scaled ungrazeable basal crust as a fraction of surface carrying capacity — the tightly-adnate, EPS-embedded understory no metazoan grazer removes. Grazing acts only on biomass above M·basal_refuge_frac·carrying_capacity via a smooth Hill-2 gate, so a mature filamentous-green mat settles to a thin persistent floor instead of being grazed to extinction (Steinman 1996 — adnate/prostrate growth forms as grazer refuge; Feminella & Hawkins 1995). Highest of the surface algae — filamentous greens build the thickest EPS-cemented mat with the most-embedded basal cells (parallels the 0.40 biofilm_predation_protection rationale, here as an absolute biomass floor rather than a rate multiplier). Consumer-independent; composes with biofilm_graze_penetration. See species/consumer_removal.py::_collect_surface_algae_data.

Diatom base

Shared diatom physiology — silica frustule, tight Fe affinity, large vacuolar luxury N and P stores, weaker CCM than greens, cold-adapted.

Growth defaults

Symbol Value Units Source / Rationale
Q10,photo 1.8 Slightly lower than greens (cold-adapted)
Q10,resp 2.2 Standard
Q10,mort 1.5 Standard
T_ref 25.0 °C Engine reference

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 15e-6 mol/L Standard freshwater algae
CCM efficiency 0.15 fraction Lower CCM than greens — relies more on CO₂
K_HCO3 1.2e-3 mol/L Burkhardt et al. 2001, Tortell 2000 — high end of eukaryotic range
Sc/o 60.0 Lower than greens (weaker CCM)
PQ 1.0 mol O₂ / mol C

N & P uptake (diatom-typical high-affinity, fast V_max)

Symbol Value Units Source / Rationale
K_N (total) 2e-5 mol/L High affinity total N
K_NH4 2e-5 mol/L
K_NO3 8e-5 mol/L
NO₃ preference (dark / light) 0.1 / 0.5 fraction Standard producer source preference
Q_P,max 0.050 mol P / mol C Sicko-Goad 1986, Powell et al. 2009 — diatoms accumulate polyphosphate higher than greens
V_P,max 0.030 mol P / (mol C · h) Diatoms drain water-column PO₄ aggressively in pulse events
Q_N,max 0.12 mol N / mol C Lomas & Glibert 1999, Kamp et al. 2011; CAEDYM table — vacuolar NO₃ reservoir
V_N,max 0.07 mol N / (mol C · h) High — diatoms drain NO₃ aggressively when pulsed

Stoichiometry

Symbol Value Units Source / Rationale
C:N 6.6 mol / mol Redfield
N:P 16.0 mol / mol Redfield
Si:N 1.0 mol Si / mol N Brzezinski 1985 — ~2 g Si per g N

Trace-metal:C overrides (diatom-specific deviations from universal anchor)

Symbol Value Units Source / Rationale
Fe:C 5.0e-6 mol Fe / mol C Sunda & Huntsman 1995, Quigg et al. 2003 — diatoms Fe-frugal (frustule reduces demand)
Mo:C 2.0e-9 mol Mo / mol C Quigg 2003 — Mo:C ≈ 1–3 nmol/mol (Mo-frugal)
Zn:C 8.0e-7 mol Zn / mol C Morel et al. 1994, Sunda & Huntsman 1995 — Zn-hungry (CCM/CA dependent), ~2× anchor
Cu:C 3.0e-8 mol Cu / mol C Annett et al. 2008, Peers & Price 2006 — Cu-frugal (cyt c₆ substitute)
K:C 2.0e-2 mol K / mol C Quigg 2003 — slightly below anchor (frustule silica dilutes K demand)
B:C 1.5e-5 mol B / mol C Loucaides 2008, Martin-Jézéquel 2017 — B-rich (frustule construction), ~3× anchor

Trace-metal Monod overrides

Symbol Value Units Source / Rationale
K_Fe 8.0e-9 mol/L Tighter than base — sub-nM Fe adaptation
K_Mo (NO₃ reductase) 1.0e-9 mol/L High-affinity NO₃ reductase ~1 nM (Mo-poor offshore regimes)
K_Zn (carbonic anhydrase) 3.0e-8 mol/L Morel et al. 2002, Lane & Morel 2000 — ~30 nM, heavier CCM commitment

Respiration

Symbol Value Units Source / Rationale
R_maint 0.001 /h Hand-tuned
K_O2 (respiration) 1.25e-5 mol/L ~0.4 mg/L O₂

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_polyphenol 8.0e-5 mol C / L ≈1.9 mg GAE/L. Gross 2003 — tannins inhibit silica-deposition vesicles, so the most sensitive eukaryote (tighter than greens) but still ~2× above cyano. Rebased onto the Nakai EC50 band 2026-08-02
K_cyanotoxin 1.5e-5 mol C / L Microcystin disrupts PP1/PP2A in eukaryotic algae (~0.3 mg MC-LR/L half-suppression)

Thermal envelope

Symbol Value Units Source / Rationale
T_lethal,photo 35.0 °C Less heat-tolerant than greens
T_stress (low) 5.0 °C Cold-adapted shared trait
T_lethal (low) 0.0 °C Cold-adapted
m_thermal,max 0.03 /h Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.0 Similar to greens
pH lethal (low / high) 4.5 / 10.5 Similar to greens
m_pH,max 0.03 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Strictly freshwater
σ_S 5.0 PSU Narrow tolerance
S_stress (high) 5.0 PSU Strictly freshwater
S_lethal (high) 15.0 PSU Strictly freshwater
m_salinity,max 0.15 /h Standard
Osmoregulation cost 0.003 per PSU deviation Standard

Mortality & death routing

Symbol Value Units Source / Rationale
m_total,max 0.50 /h Mortality cap
Death → suspended fraction 0.3 fraction Standard

Viral lysis

Symbol Value Units Source / Rationale
m_viral,max 0.012 /h Tomaru et al. 2015 — diatom-virus rates 5–25%/day (silica frustule no protection)
K_viral (host density) 1.0e-5 mol C / L Standard density half-sat

Biofilm shelter (see species/access.py::surface_protection)

Symbol Value Units Source / Rationale
biofilm_predation_protection 0.20 fraction M=1 EPS-shelter ceiling — silica frustule offers some structural defence but diatoms are biofilm occupants, not mat-builders (Marker 1976; Hoagland et al. 1982). Lower than benthic green algae's 0.40. Same coefficient gates grazing access and base + viral self-mortality.
geometric_predation_shield_scale 0.30 M=0 cold-start floor multiplier on substrate roughness — frustules settle into micro-crevices. Note: this exceeds the M=1 cap (0.20), so on rough substrate (gravel roughness 0.70 → geo 0.21; porous ceramic 0.95 → geo 0.285) the geometric floor is above the EPS cap. surface_protection clamps the M-slope to max(cap − geo, 0) so a maturing biofilm never reduces diatom shelter — protection holds flat at the geometric floor there instead of interpolating downward. Diatoms remain the least-sheltered algal guild; their adnate grazer-resistance is carried by the separate basal_refuge_frac floor.

Centric diatoms — divergent only

Planktonic r-strategists — cold-water spring bloomers with boom-bust dynamics. (Only divergences from Diatom base are shown.)

Growth & light

Symbol Value Units Source / Rationale
P_max 0.085 /h Fast bloom growth (~2.0/day)
I_K 30.0 µmol m⁻² s⁻¹ Less shade-tolerant than pennate

Si uptake

Symbol Value Units Source / Rationale
K_DSi 3e-6 mol/L Weaker Si affinity than pennate (~0.084 mg Si/L)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 16.0 °C Cold-water spring bloomer
T_stress (high) 24.0 °C Spring / cold-water community
T_lethal (high) 32.0 °C Spring / cold-water community

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.06 / 24 /h Boom-bust dynamics
DOC excretion fraction 0.05 fraction Low mucilage
Surface death → suspended 0.40 fraction Debris easily resuspends

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Settlement rate 0.002 /h Weak mucilage adhesion, easy resuspension
Detachment multiplier 2.5 Easy resuspension
Dispersal fraction 0.30 fraction Spreads readily between surfaces

Grazing refuge

Symbol Value Units Source / Rationale
basal_refuge_frac 0.06 fraction Maturity-scaled ungrazeable basal crust as a fraction of surface carrying capacity (see benthic green algae for the mechanism). Smallest of the surface algae — centrics are mostly loosely-attached / settling forms with weak mucilage adhesion, so the adnate residual grazers cannot strip is small — half the pennate crust (Steinman 1996; Feminella & Hawkins 1995 on adnate vs loosely-attached growth-form grazer resistance).

Pennate diatoms — divergent only

Benthic K-strategists — shade-tolerant biofilm interior with aggressive mucilage adhesion and high Si affinity. (Only divergences from Diatom base are shown.)

Growth & light

Symbol Value Units Source / Rationale
P_max 0.045 /h Slow K-strategist (~1.1/day)
I_K 12.0 µmol m⁻² s⁻¹ Shade-tolerant biofilm interior

Si uptake

Symbol Value Units Source / Rationale
K_DSi 1.5e-6 mol/L High Si affinity (~0.042 mg Si/L)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 22.0 °C Temperate biofilm
T_stress (high) 30.0 °C Temperate biofilm
T_lethal (high) 38.0 °C Temperate biofilm

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.03 / 24 /h Persistent communities
DOC excretion fraction 0.08 fraction Heavy mucilage for biofilm scaffold
Surface death → suspended 0.10 fraction Debris stays in place

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Settlement rate 0.008 /h Aggressive mucilage attachment
Detachment multiplier 1.0 Strong adhesion
Dispersal fraction 0.10 fraction Stay local

Grazing refuge

Symbol Value Units Source / Rationale
basal_refuge_frac 0.12 fraction Maturity-scaled ungrazeable basal crust as a fraction of surface carrying capacity (see benthic green algae for the mechanism). Adnate pennates (Cocconeis, Achnanthes) are the classic grazer-resistant understory — prostrate, raphe-adhered flat to the substrate, the growth form grazing selects for (Steinman 1996; Feminella & Hawkins 1995). Between benthic green (0.15) and centric (0.06): a thinner mat and lighter EPS than filamentous greens, but far tighter substrate contact than settling centrics.

Cyanobacteria base

Shared cyanobacterial physiology — carboxysome CCM, cyanophycin luxury-N storage, N₂-fixation machinery, asymmetric high-pH tolerance, and dedicated cyanophage virus mortality.

Growth defaults

Symbol Value Units Source / Rationale
Q10,photo 2.0 Standard
Q10,resp 2.0 Standard
Q10,mort 1.5 Standard
T_ref 25.0 °C Engine reference

Carbon kinetics (high-affinity CCM)

Symbol Value Units Source / Rationale
K_CO2 8e-6 mol/L Strong carboxysome CCM — low half-sat survives high-pH CO₂ depletion
CCM efficiency 0.60 fraction Giordano et al. 2005 — strong CCM via carboxysomes
K_HCO3 0.2e-3 mol/L Price 2011, Mangan & Brenner 2014 — BCT1 / SbtA / BicA highest HCO₃⁻ affinity of any phototroph
Sc/o 120.0 Higher — carboxysome concentrates CO₂ for RuBisCO
PQ 1.0 mol O₂ / mol C

N & P uptake

Symbol Value Units Source / Rationale
K_N (total) 4e-5 mol/L Same as green algae
K_NH4 2e-5 mol/L
K_NO3 8e-5 mol/L
NO₃ preference (dark / light) 0.1 / 0.5 fraction Standard producer source preference
Q_P,max 0.040 mol P / mol C Stewart & Alexander 1971, Healey 1973, Sicko-Goad 1986 — cyano polyphosphate well-studied
V_P,max 0.025 mol P / (mol C · h) CCM-coupled fast P uptake, slightly elevated vs greens
Q_N,max 0.18 mol N / mol C Simon 1971, Allen 1984; AED2 / CAEDYM tables — cyanophycin granules (largest luxury-N reservoir)
V_N,max 0.04 mol N / (mol C · h) Goldman & McCarthy 1978 — slow uptake of benthic-mat / oligotrophic forms (base default; planktonic bloom-former overrides upward)
Q_N repression K (nifH) 0.07 mol N / mol C Allen 1984, Muro-Pastor & Hess 2012 — nifH repression Hill² K

N₂ fixation kinetics

Symbol Value Units Source / Rationale
I_K (nif) 15.0 µmol m⁻² s⁻¹ Staal et al. 2002 — nitrogenase light half-sat
nif energy cost fraction 0.25 fraction Postgate 1982 — ~16 ATP + 8 e⁻ per N₂ at max ~25% of cellular energy
K_Fe (nif) 5.0e-8 mol/L Kustka et al. 2003 — nitrogenase Fe half-sat ~0.5 µg/L (FeMo-cofactor, ~10× generic Fe demand)
K_Mo (nif) 2.0e-9 mol/L Howarth & Cole 1985 — Mo-gate on nitrogenase ~2 nM

Stoichiometry

Symbol Value Units Source / Rationale
C:N 7.5 mol / mol Sheaths and storage polymers raise C per N
N:P 16.0 mol / mol Redfield

Trace-metal:C overrides (cyano-specific deviations from universal anchor)

Symbol Value Units Source / Rationale
Fe:C 4.0e-5 mol Fe / mol C Kustka et al. 2003, Berman-Frank et al. 2001 — 2–5× eukaryotic algae (PSI Fe-S + nitrogenase)
Mo:C 5.0e-9 mol Mo / mol C Quigg 2003, Howarth & Cole 1985 — Mo-rich (FeMo-cofactor of nitrogenase), ~5× anchor
Zn:C 3.0e-7 mol Zn / mol C Yee & Morel 1996, Xu et al. 2008 — Zn-frugal (Co / Cd-substituted CA), slightly below anchor
Cu:C 1.0e-7 mol Cu / mol C Peers & Price 2006, Duckworth et al. 2009 — Cu-rich (obligate plastocyanin), ~2× anchor
K:C 3.0e-2 mol K / mol C Sterner & Elser 2002 — slightly above anchor (Na/K antiport for high-pH habitat)
Ni:C 3.0e-7 mol Ni / mol C Tuit et al. 2004, Ho et al. 2003 — Ni-rich (HupSL hydrogenase + urease), ~3× anchor
Co:C 3.0e-8 mol Co / mol C Saito & Moffett 2002 — Co-rich (B12 synthesis + Co-substituted CA), ~6× anchor
B:C 2.0e-5 mol B / mol C Mateo et al. 1986, Bonilla 1990 — B-rich (heterocyst-envelope glycolipids), ~4× anchor
S:C 7.0e-3 mol S / mol C Cunningham & Capone 1992, Stal 2009 — S-rich (nitrogenase Fe-S clusters), ~1.4× anchor

Trace-metal Monod overrides

Symbol Value Units Source / Rationale
K_Mo (NO₃ reductase) 2.0e-9 mol/L Same scale as other phytoplankton
K_Zn (carbonic anhydrase) 5.0e-9 mol/L Cyano CA is Co / Cd-swappable; below producer default — tolerates low-Zn water
K_K 3.0e-6 mol/L Tighter than producer default — Na/K antiport gives kinetic edge at low ambient K

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.005 fraction Rohrlack 1999, Sivonen & Jones 1999, Schatz 2007, Burford 2014 — places dissolved MC in µg/L envelope
Allelochemical pool cyanotoxin Routes to cyanotoxin pool
K_polyphenol 4.0e-5 mol C / L ≈0.97 mg GAE/L — sits on the gallic-acid 72 h EC50 vs Microcystis (1.0 mg/L, Nakai et al. 2000). Value unchanged, rank inverted 2026-08-02: cyanobacteria are now the MOST polyphenol-sensitive class, not the least. The polyphenol-allelopathy literature is a cyanobacterial-control literature and the effect is repeatedly reported as cyano-specific with eukaryotic algae spared — which is what makes barley straw and leaf litter usable pond treatments (Ridge et al. 1999; Laue et al. 2014)

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0015 /h Higher than diatoms — thick walls
K_O2 (respiration) 1.25e-5 mol/L ~0.4 mg/L O₂

Thermal envelope (warm-adapted)

Symbol Value Units Source / Rationale
T_lethal,photo 40.0 °C Warm-adapted
T_stress (high) 36.0 °C Warm-adapted
T_lethal (low / high) 0.0 / 42.0 °C Cold lethal / warm-adapted upper
m_thermal,max 0.03 /h Standard

pH envelope (asymmetric high-pH tolerance)

Symbol Value Units Source / Rationale
pH stress (low) 5.5 Asymmetric — high-pH side tolerates further
pH lethal (low) 4.5
pH lethal (high) 12.0 Very high tolerance (carboxysomes function at high pH)
m_pH,max 0.03 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 2.0 PSU Freshwater
σ_S 8.0 PSU Similar to greens
S_stress (high) 10.0 PSU Freshwater
S_lethal (high) 20.0 PSU Freshwater
m_salinity,max 0.15 /h Standard
Osmoregulation cost 0.003 per PSU deviation Standard

Mortality & death routing

Symbol Value Units Source / Rationale
m_total,max 0.50 /h Mortality cap
Death → suspended fraction 0.2 fraction Dense sheaths → more settled debris

Viral lysis

Symbol Value Units Source / Rationale
m_viral,max 0.025 /h Suttle 2007, Brussaard 2004 — cyanophages strongest virus mortality (60%/day at saturation)
K_viral (host density) 5.0e-6 mol C / L Tighter than greens — phage encounter at lower densities

Planktonic cyanobacteria — divergent only

Bloom-forming r-strategists — surface-scum / high-light adapted with heterocystous N₂ fixation. (Only divergences from Cyanobacteria base are shown.)

Growth & light

Symbol Value Units Source / Rationale
P_max 0.065 /h Bloom r-strategist (~1.6/day)
I_K 35.0 µmol m⁻² s⁻¹ Surface-scum / high-light adapted

N & N₂ fixation

Symbol Value Units Source / Rationale
V_N,max 0.065 mol N / (mol C · h) Simon 1971, Allen 1984 (cyanophycin N-sink) — bloom-formers (Aphanizomenon, Dolichospermum) assimilate DIN + fixed N into storage at least as fast as co-occurring greens; overrides the slow base 0.04. Asymmetric lever for the low-N:P cyano advantage — lets the fixer retain its private N rather than leaking it to the faster green via recycling; silent at high N:P where DIN saturates both competitors (Schindler 1977, Smith 1983)
N₂ fix rate max 5.0e-3 /h Howarth et al. 1988, Carpenter 1983 — heterocystous forms sustain ~5–15% biomass N/day on N₂ in low-DIN summer lakes. Raised from 3.5e-3 so the realised rate (after the light × nifH-repression × O₂ × Fe × Mo co-limitation product, ~0.1–0.2 in a real tank) lands at the bottom of that field range (~3%/day de-repressed) rather than ~5× below it. Fully repressed at high N:P
K_O2 (nif) 1.0e-3 mol/L Fay 1992, Wolk et al. 1994 — heterocystous bloom-formers carry the dedicated O₂-excluding heterocyst envelope (strongest nitrogenase O₂-protection of any cyano), so they are less bulk-O₂-inhibited than non-heterocystous benthic mats. Raised from 5.0e-4 (~80% of max fixation at 8 mg O₂/L) — corrects the previously-backwards benthic > planktonic ordering

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 27.0 °C Paerl & Huisman 2008 — cyano T_opt 28–32 °C; tuned to maintain warm-water advantage vs greens (24 °C)
T_stress (low) 14.0 °C Less cold-tolerant than benthic mats

pH envelope

Symbol Value Units Source / Rationale
pH stress (high) 10.5 Bloom species drive high-pH eutrophic lakes

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.03 / 24 /h Tuned to preserve boom-bust character (~3%/day) — higher than benthic 2.5%/day
DOC excretion fraction 0.10 fraction Moderate EPS (colonies, mucilage)
Surface death → suspended 0.40 fraction Debris resuspends readily

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Settlement rate 0.002 /h Weak attachment, easy resuspension
Detachment multiplier 2.5 Easy resuspension
Dispersal fraction 0.25 fraction Spreads readily through water column

Benthic cyanobacteria — divergent only

Mat-forming K-strategists (Phormidium / Oscillatoria) with non-heterocystous N₂ fixation in the mat-interior microaerobic gradient. (Only divergences from Cyanobacteria base are shown.)

Growth & light

Symbol Value Units Source / Rationale
P_max 0.030 /h Slow K-strategist (~0.72/day)
I_K 12.0 µmol m⁻² s⁻¹ Shade-adapted mat interior

N₂ fixation

Symbol Value Units Source / Rationale
N₂ fix rate max 2.0e-3 /h Paerl & Bebout 1988 — non-heterocystous mats ~5% biomass N/day at peak (mat-interior microaerobic)
K_O2 (nif) 1.0e-3 mol/L Paerl & Bebout 1988; tuned higher than planktonic (mat-interior O₂ gradient decouples from bulk)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 26.0 °C Hudon et al. 2014, Quiblier et al. 2013 — Phormidium / Oscillatoria mats most vigorous 24–28 °C
T_stress (low) 10.0 °C More cold-tolerant than planktonic

pH envelope

Symbol Value Units Source / Rationale
pH stress (high) 9.5 Mats less alkaliphile than bloom species

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.025 / 24 /h Persistent mats (~2.5%/day)
DOC excretion fraction 0.22 fraction Heavy EPS scaffold + grazing deterrent
Surface death → suspended 0.05 fraction Debris stays in place as settled detritus

Dispersal & surface attachment

Symbol Value Units Source / Rationale
Settlement rate 0.012 /h Aggressive EPS adhesion, cohesive mats
Detachment multiplier 0.8 Strong adhesion
Dispersal fraction 0.05 fraction Mats stay local

Biofilm shelter (see species/access.py::surface_protection)

Symbol Value Units Source / Rationale
biofilm_predation_protection 0.60 fraction M=1 EPS-shelter ceiling — mature Phormidium / Oscillatoria / Lyngbya mats develop thick mucilaginous sheaths with well-documented grazing resistance (Dodds 2002 Freshwater Ecology ch. 12; Stevenson et al. 1996). Highest algal shelter in the model — sits between HB (0.50) and nitrifier (0.90). Same coefficient gates grazing access and base + viral self-mortality.
geometric_predation_shield_scale 0.50 M=0 cold-start floor multiplier on substrate roughness — sheath cohesion helps mats anchor in pits/crevices early

Macrophytes

Macrophytes — floating, submerged, and rooted vascular plants — share the producer kinetic skeleton but add multi-compartment structure (shoot / root / frond / stem), dual-source uptake (water-column leaves + pore-water roots), aerenchyma-mediated rhizosphere oxygen / CO₂ exchange, and (for rooted plants) phloem translocation between compartments. The conventions below extend the Producer glossary; species sections only spell out divergences.

Macrophyte symbol glossary

Symbol Meaning
P_max, I_K, K_X, V_X,max, Q_X,min/max, Q10, T_opt, R_maint, m_X Same as Producer glossary
Q_N,max / V_N,max (water) / V_N,max (root) Cellular quota ceiling and parallel water- vs root-uptake rates (mol N per mol C per h)
K_NH4 (water) / K_NH4 (pore) Leaf vs root NH₄ Monod half-sats (root system I is sub-µM affinity)
K_K (water) / K_K (pore) Leaf vs root K Monod half-sats
f_water / f_root Acquisition split for N and P uptake (sum to 1.0) — pore-dominated in Walstad-style rooted plants
f_root,CO2 Fraction of photosynthetic C drawn from pore CO₂ via aerenchyma. Kept low/zero: the tracked rooted plants are leafy elodeids (Cryptocoryne 0.0, Vallisneria 0.15), which make little use of sediment CO2 (Madsen & Sand-Jensen 1991) — the isoetid sediment-carbon strategy is a different physiology not in the roster. Carbon comes from the leaves/water column; roots supply mineral nutrients (f_root). Sensitivity: it's a concentration blend (1−f)·water + f·pore, and pore CO₂ is emergent at ~3–180 µM (≫ ~14 µM ambient water), so even a small f_root,CO2 saturates the plant — treat it as near-binary, not a smooth dial (do not assume the old "~7 mM pore" figure).
f_root,O2 release Fraction of GPP exuded as radial oxygen loss into rhizosphere
k_translocate First-order phloem-borne mobilisation of N+P stored pools between root and shoot (rooted only)
α_root Below-ground C allocation fraction
k_frond,atten / k_stem,atten / k_shoot,atten / k_canopy,atten Beer-Lambert light attenuation coefficients (m² per mol C for fronds/canopy, L per mol C per m for stems/shoots)
SLA (canopy) Specific leaf area (m² per mol C) for canopy light interception
SLA_cm2_per_mg_C Specific leaf area for epiphytic biofilm carrying capacity on macrophyte_leaf_surface — multiplied by current leaf C (mg) and (for floating species) by (1 − aerial_C_fraction) to sum into the aggregated dynamic surface area. Per-grazer access on this surface is set in interactions.yaml (not codegen) and anchored to feeding-mode literature — see docs/environment/surfaces.md for the per-grazer table
max cover fraction Areal cap on water-surface coverage by floating species
kLa block at full cover Fractional suppression of air-water gas exchange under a mature floating mat
Competitive displacement First-order suppression of a sub-dominant floating species by a dominant one
Aerial C fraction Fraction of frond surface above the water line (stomata-bearing in floating C3 plants)
Dark respiration factor LEDR — light-enhanced dark respiration ratio (Heskel 2013; Atkin & Tjoelker 2003)
Allelo release fraction Fraction of net production released as polyphenol allelochemical (Hilt & Gross 2008)

Floating macrophyte base

Generic floating-plant kinetic skeleton — sets defaults for fronds resting on the water surface with aerial stomata, water-column nutrient uptake, and a mat-coverage cap.

Trace-metal:C overrides

Symbol Value Units Source / Rationale
K:C 5.0e-2 mol K / mol C Macrophyte K:C anchor (vacuolar luxury K); ~2× universal anchor
B:C 5.0e-5 mol B / mol C Marschner 1995 — vascular cell-wall pectin (RG-II) B crosslinking, ~10× detritus anchor
K_K (growth) 1.0e-5 mol/L ~0.4 mg K/L; matches K_K_water leaf scale

Canopy & light

Symbol Value Units Source / Rationale
P_max 0.010 /h ~0.24/day generic floating-macrophyte rate; subclasses override
I_K 40.0 µmol m⁻² s⁻¹ No direct source — floating-plant range
k_frond,atten 4.6 m² / mol C = 2.3 × SLA; one full areal layer blocks ~90% PAR (shared floater ratio)
SLA 2.0 m² / mol C Geometric monolayer footprint; drives areal-cover metric (render + trim trigger)
Max cover fraction 1.0 fraction Default disables spatial cap (Beer-Lambert only); subclasses override
Space limit → gross fixation space_fac = max(0, 1 − (τ/τ_max)³) multiplies gross photosynthesis. A plant out of room to put new tissue downregulates assimilation rather than fixing at full rate and dumping the surplus: with frond production (duckweed's main sugar sink) shut off, sucrose and starch accumulate and feedback-inhibit photosynthesis. Measured as reduced photosynthetic yield at high frond density at matched shading, so it is a density signal, not self-shading (which Beer-Lambert already covers). Landolt & Kandeler 1987; Paul & Foyer 2001 J. Exp. Bot. 52:1383; Vermaat & Hanif 1998 Water Res. 32:2569. Changed Aug 2026 — it previously scaled growth only and routed the blocked carbon to labile DOM, which meant a mat at carrying capacity (the normal long-run state) excreted up to 100% of net photosynthesis as DOC indefinitely. Equilibrium is self-correcting and needs no floor: fixation falls below respiration, biomass declines, cover drops, fixation resumes
Uses total cover for space True bool Combined cover for large-frond species (Salvinia)
Competitive displacement 0.0 /h Disabled by default; set on dominant species
Competition threshold 0.5 cover frac Activation threshold for displacement
kLa block at full cover 0.85 fraction At full cover, kLa drops to 15% of open-water value (literature mid-range)

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 8e-6 mol/L Low half-sat (surface CO₂ access)
CCM efficiency 0.15 fraction Modest C3-plant HCO₃⁻ use
K_HCO3 2.0e-3 mol/L Maberly & Madsen 2002 — floating C3 plants are weak HCO₃⁻ users
Sc/o 80.0 Standard C3 RuBisCO
Internal air-CO₂ 1.0e-5 mol/L Ci/Ca ≈ 0.7 of atmospheric 400 ppm at 23 °C dissolved-phase equivalent
Aerial C fraction 0.85 fraction Salvinia-style hairs lift fronds; stomata on aerial side dominate
PQ 1.0 mol O₂ / mol C Standard photosynthesis stoichiometry
DOC excretion fraction 0.05 fraction Generic algal/macrophyte DOC excretion fraction

Stoichiometry

Symbol Value Units Source / Rationale
C:N 10.0 mol / mol N-rich non-lignified frond tissue
C:N (max under N starvation) 22.0 mol / mol Maximum C:N under N starvation
N:P 14.0 mol / mol Near-Redfield for fast growers

N & P uptake

Symbol Value Units Source / Rationale
V_N,max (water) 1.5e-3 mol N / (mol C · h) Epstein & Hagen 1952; Cedergreen & Madsen 2002 (Lemna)
V_P,max (water) 1.0e-4 mol P / (mol C · h) Macrophyte literature high-affinity scale
K_N (water) 4e-6 mol/L ~0.056 mg N/L; high-affinity NH4 (root system I analogue)
K_NO3 (water) 1.5e-5 mol/L Lower NO3 affinity vs. NH4
K_P (water) 3e-7 mol/L ~0.009 mg P/L; high P affinity
NO₃ preference (dark / light) 0.1 / 0.4 fraction Standard producer source preference
K_N (total, helper) 8e-6 mol/L Producer helper half-sat
K_NH4 (helper) 4e-6 mol/L Producer helper half-sat
K_NO3 (helper) 1.5e-5 mol/L Producer helper half-sat
K_PO4 (helper) 3e-7 mol/L Producer helper half-sat
Min photo N factor 0.10 fraction Floor on photo-N factor

Droop internal stores

Symbol Value Units Source / Rationale
Q_P,min 0.005 mol P / mol C Gerloff 1966 critical tissue P at ~40% C DW
Q_P,max 0.030 mol P / mol C Lemna 2.8% DW upper P (Skillicorn 1993; Cedergreen & Madsen 2002)
Q_N,min 0.005 mol N / mol C ~0.25 × Q_N,max (Droop curve shape preserved)
Q_N,max 0.020 mol N / mol C Skillicorn 1993; Cedergreen & Madsen 2002; Landolt 1986; Sale & Wetzel 1983
V_P,max (luxury) 5.0e-4 mol P / (mol C · h) Paterson et al. 2020 ~10× baseline luxury rate (mid-range default)
V_N,max (luxury) 3.0e-3 mol N / (mol C · h) Generic luxury-N rate, mid-range default
K_PO4 (luxury uptake) 1.0e-7 mol/L Paterson et al. 2020 high-affinity Pi transporter
K_NH4 (luxury uptake) 4.0e-6 mol/L Source-preference half-sat (mirrors K_N water)
K_NO3 (luxury uptake) 1.5e-5 mol/L Source-preference half-sat
Q10 (uptake) 2.0 Eppley 1972 transporter scaling
k_catab (storage) 0.001 /h Slow stored-pool hydrolysis under starvation
k_N homeostasis 0.01 /h ~3-day timescale; allows diurnal drift, corrects long-term

Respiration

Symbol Value Units Source / Rationale
R_maint 1.5e-3 /h ~0.15%/h base maintenance
K_O2 (respiration) 1.0e-5 mol/L O2 half-sat for respiration
Osmoregulation cost 0.002 per PSU deviation Osmoregulation respiratory load multiplier
Dark respiration factor 0.70 fraction Heskel et al. 2013 LEDR; Atkin & Tjoelker 2003

Mortality & death routing

Symbol Value Units Source / Rationale
Frond mortality 1.25e-4 /h ~0.3%/day baseline senescence
Crowding self-thinning multiplier 1.0 Calibrated, not cited. Baseline senescence is scaled by 1 + mult·(1 − space_fac), so a mat at full cover sheds fronds at up to 2× the baseline rate — the "browns off from underneath" a keeper sees when overtopped fronds are shaded out and sink. Exactly inert below the cover cap and on all submerged species (base default 0.0). Self-thinning in dense stands is well established qualitatively (Westoby 1984, Adv. Ecol. Res. 14:167) but no rate constant exists for a Lemnaceae/Salvinia mat. Without it a space-limited mat produces no detritus at all
O2 stress threshold 1.5 mg/L O2 below this → mortality ×2
m_total,max 0.30 /h Cap on combined mortality
Death → suspended fraction 0.10 fraction 10% suspended / 90% settled (fronds sink)
Surface death → suspended 0.10 fraction Mirror of death-to-suspended

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 26.0 °C Generic floating-plant optimum
T_lethal,photo 42.0 °C Generic upper photosynthesis lethal
T_ref T_REF_C (25) °C Standard biology reference temperature
Q10,photo 2.0 Standard
Q10,resp 2.2 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 12.0 / 35.0 °C Stress onset
T_lethal (low / high) 3.0 / 42.0 °C Lethal thresholds
m_thermal,max 0.02 /h Max thermal mortality

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.5 Stress thresholds
pH lethal (low / high) 4.5 / 11.0 Lethal thresholds
m_pH,max 0.015 /h Max pH-driven mortality

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater optimum
σ_S 4.0 PSU Tolerance width
S_stress (low / high) 0.0 / 5.0 PSU Stress thresholds
S_lethal (low / high) 0.0 / 10.0 PSU Lethal thresholds
m_salinity,max 0.10 /h Max salinity-driven mortality

Salvinia — divergent only

Free-floating water fern with hydrophobic-haired fronds that lift the leaf above the water line; sub-dominant in competition with Lemna. (Only divergences from the Floating macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
k_frond,atten 3.0 m² / mol C = 2.3 × SLA(1.3); near-opaque hairy fronds block ~90% PAR per layer
SLA 1.3 m² / mol C Geometric: ~1 cm frond, 1.33e-4 mol C per frond
Max cover fraction 0.90 fraction Single-layer mat. Set by this species' own optics, not chosen independently: the areal footprint is (SLA/k)·τ_max, so 0.90 → τ_max 2.303 → footprint exactly 1.0. At 0.95 (τ_max 2.996) the footprint computes 1.30 and is clipped, i.e. the mat goes on accumulating after the surface is full and pins the gas-exchange block at its floor. Lowered from 0.95, Aug 2026. Note (Aug 2026): the "throttles growth but not fixation, excess C excreted as DOM" behaviour this row used to describe is gone — the space limit now gates gross fixation, so a space-limited mat simply fixes less. See the floating-macrophyte base rows below and labile DOM accumulation
kLa block at full cover 0.70 fraction Janes 1998; Mitchell & Tur 1975 — Salvinia mats more porous than Lemna
P_max 3.0e-2 /h ~7–10 day doubling under 10h photoperiod (Lemon & Posluszny 2000; Walstad 1999)
I_K 30.0 µmol m⁻² s⁻¹ Floating plants near-saturate at low I

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 6e-6 mol/L Low half-sat; surface atmospheric CO₂ access
CCM efficiency 0.15 fraction C3 fern; primarily dissolved CO₂
K_HCO3 2.5e-3 mol/L Madsen & Sand-Jensen 1991 — C3 ferns lack strong CCM
Aerial C fraction 0.90 fraction Hydrophobic hairs lift fronds; stomata on aerial side
SLA_cm2_per_mg_C 2.0 cm² / mg C Rhizoid-dominated; scaled by (1 − aerial_C_fraction) = 0.10 ⇒ ~0.2 cm² effective per mg frond C. Recalibrated from V1=5 (May 2026) in lockstep with rooted/submerged SLA reductions

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.0002 fraction Smith et al. 1991 — floating plants invest little in allelochemistry; sub-hornwort

Stoichiometry

Symbol Value Units Source / Rationale
C:N 10.0 mol / mol N-rich fast-growing tissue
C:N (max under N starvation) 20.0 mol / mol Maximum C:N under N starvation
N:P 14.0 mol / mol Near-Redfield

N & P uptake

Symbol Value Units Source / Rationale
V_N,max (water) 1.5e-3 mol N / (mol C · h) Dense root-hair-like absorptive tissue
K_N (water) 4e-6 mol/L ~0.056 mg N/L; high-affinity NH4
K_NO3 (water) 1.2e-5 mol/L Lower NO3 affinity vs. NH4
K_P (water) 2.5e-7 mol/L High P affinity
Q_P,max 0.025 mol P / mol C Smaller P reservoir than Lemna (calibration knob for competition)
Q_N,min 0.004 mol N / mol C Sale & Wetzel 1983; Cary & Weerts 1984 — Salvinia C:N 12–25
Q_N,max 0.015 mol N / mol C Sale & Wetzel 1983; Cary & Weerts 1984 — replete tissue near C:N 12
V_P,max (luxury) 3.0e-4 mol P / (mol C · h) Slower than Lemna (sub-dominant in competition)
V_N,max (luxury) 2.0e-3 mol N / (mol C · h) Sub-Lemna luxury N rate
K_PO4 (luxury uptake) 1.5e-7 mol/L Looser than Lemna (drives competitive outcome)

Respiration

Symbol Value Units Source / Rationale
R_maint 1.0e-3 /h 3.3% of P_max; preserves ratio used in floating base

Mortality & death routing

Symbol Value Units Source / Rationale
Frond mortality 1.25e-4 /h ~0.3%/day baseline (hardy in aquarium)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 24.0 °C Calibrated for 22–26 °C aquarium range
T_lethal,photo 40.0 °C Warm-water lethal
T_stress (low / high) 13.0 / 34.0 °C Cold-intolerant lower; upper stress
T_lethal (low / high) 4.0 / 40.0 °C Killed by frost; upper mirror
Q10,photo 2.2 Slightly elevated vs base
Q10,resp 2.2 Mirror

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.5 S. natans naturally pH 5–9
pH lethal (low / high) 4.5 / 11.0

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Strictly freshwater
σ_S 3.0 PSU Narrower than base
S_stress (low / high) 0.0 / 4.0 PSU No marine tolerance
S_lethal (low / high) 0.0 / 8.0 PSU

Duckweed / Lemna minor — divergent only

Tiny fast-growing angiosperm that displaces Salvinia by aggressive light pre-emption and tighter nutrient affinity. (Only divergences from the Floating macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
k_frond,atten 8.7 m² / mol C = 2.3 × SLA(3.8); one full Lemna layer blocks ~90% PAR
SLA 3.8 m² / mol C Geometric: ~2 mm diameter frond, 0.5 mg fresh each
Max cover fraction 0.90 fraction Single-layer dense mat
Uses total cover for space False bool Lemna grows in gaps of larger competitor mats
kLa block at full cover 0.92 fraction Pokorný & Rejmánková 1983; Morris & Barker 1977 — Lemna nearly true lid
Competitive displacement 0.015 /h Calibrated for 60–90 d Salvinia decline under Lemna dominance (aquarist observation)
Competition threshold 0.45 cover frac Activation at 45% total cover
P_max 4.5e-2 /h 2–3 day doubling at 16h photoperiod (Hillman 1961; Landolt 1986; Skillicorn 1993)
I_K 25.0 µmol m⁻² s⁻¹ Thin fronds (~0.3 mm) saturate at low I

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 5e-6 mol/L Low half-sat; surface atmospheric CO₂ access
CCM efficiency 0.25 fraction Angiosperm; greater HCO₃ use than Salvinia (C3 fern)
K_HCO3 1.5e-3 mol/L Angiosperm with modest CCM (intermediate)
Aerial C fraction 0.80 fraction Thin fronds lie flat; some submerged surface
SLA_cm2_per_mg_C 1.0 cm² / mg C Single short rhizoid; ~30 cm²/g dry. Scaled by (1 − aerial_C_fraction) = 0.20 ⇒ ~0.2 cm² effective per mg frond C. Recalibrated from V1=2 (May 2026) in lockstep with rooted/submerged SLA reductions

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.0002 fraction Mussatto et al. 2017 — low but detectable Lemnaceae phenolic exudation

Stoichiometry

Symbol Value Units Source / Rationale
C:N 8.0 mol / mol Skillicorn 1993; Landolt 1986 — C:N 7–10 N-replete
C:N (max under N starvation) 18.0 mol / mol Maximum C:N under N starvation
N:P 14.0 mol / mol Near-Redfield

N & P uptake

Symbol Value Units Source / Rationale
V_N,max (water) 2.0e-3 mol N / (mol C · h) Dense rootlet absorptive tissue
K_N (water) 3e-6 mol/L Cedergreen & Madsen 2002 — Lemna direct measurement, higher affinity than Salvinia
K_NO3 (water) 1.0e-5 mol/L Mirror low-K
K_P (water) 2.0e-7 mol/L High P affinity
K_N (total, helper) 6e-6 mol/L Matches water uptake parameters
K_NH4 (helper) 3e-6 mol/L Matches water uptake parameters
K_NO3 (helper) 1.0e-5 mol/L Matches water uptake parameters
K_PO4 (helper) 2e-7 mol/L Matches water uptake parameters
Q_P,max 0.030 mol P / mol C Paterson 2020 + Skillicorn 1993 polyphosphate uncoupling, P% DW 0.03–2.8%
Q_N,min 0.010 mol N / mol C Set so total C:N floor ≈ 6 (documented Lemna minimum)
Q_N,max 0.040 mol N / mol C Skillicorn 1993; Cedergreen & Madsen 2002 — total C:N ~6–7 max-N
V_P,max (luxury) 6.0e-4 mol P / (mol C · h) Faster than Salvinia luxury kernel
V_N,max (luxury) 4.0e-3 mol N / (mol C · h) Faster luxury N than Salvinia
K_PO4 (luxury uptake) 8.0e-8 mol/L Tighter than Salvinia (high-affinity transporter)
K_NH4 (luxury uptake) 3.0e-6 mol/L Matches K_N water
K_NO3 (luxury uptake) 1.0e-5 mol/L Matches K_NO3 water

Respiration

Symbol Value Units Source / Rationale
R_maint 1.5e-3 /h 3.3% of P_max; preserves ratio

Mortality & death routing

Symbol Value Units Source / Rationale
Frond mortality 1.5e-4 /h ~0.36%/day; tiny fragile fronds turn over slightly faster

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 25.0 °C Generic warm temperate optimum
T_lethal,photo 40.0 °C Upper lethal photo
T_stress (low / high) 10.0 / 33.0 °C Cold-hardier than Salvinia
T_lethal (low / high) 2.0 / 40.0 °C Cold-hardy via turion formation
Q10,photo 2.1 Slightly below Salvinia
Q10,resp 2.2 Mirror base

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.0 / 9.5 Wider low-end than Salvinia
pH lethal (low / high) 4.0 / 10.5

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 2.5 PSU Narrow (salt-sensitive)
S_stress (low / high) 0.0 / 3.0 PSU More sensitive than Salvinia
S_lethal (low / high) 0.0 / 6.0 PSU

Red Root Floater / Phyllanthus fluitans — divergent only

Tropical South American floating angiosperm with rounded leaves and trailing crimson roots. The slowest-growing and most light-demanding of the three floaters; sub-dominant in a mixed floating mat. Primary ecophysiological data for the species are sparse (it is an ornamental), so parameters are set by analogy to Salvinia and shifted to encode a moderate growth rate, a high light requirement, and tropical cold-intolerance. (Only divergences from the Floating macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
k_frond,atten 3.45 m² / mol C = 2.3 × SLA(1.5); one full leaf layer blocks ~90% PAR
SLA 1.5 m² / mol C Rounded ~1 cm flat leaves; slightly broader per unit C than Salvinia
Max cover fraction 0.90 fraction Single-layer rosette mat; less continuous than a duckweed sheet
kLa block at full cover 0.80 fraction Flat leaves — denser lid than porous Salvinia, gappier than duckweed
P_max 2.8e-2 /h Slowest floater (below Salvinia 3.0e-2, duckweed 4.5e-2); realized ~3-week doubling in bright light — aquarist consensus; Lemon & Posluszny 2000 as analogue
I_K 42.0 µmol m⁻² s⁻¹ Most light-demanding of the three floaters (vs Salvinia 30, duckweed 25); stays small/pale in dim tanks

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 6e-6 mol/L Low half-sat; surface atmospheric CO₂ access
CCM efficiency 0.15 fraction Weak CCM; floating leaves mostly breathe air
K_HCO3 2.0e-3 mol/L Floating C3 leaf; poor lower-epidermis HCO₃⁻ uptake
Aerial C fraction 0.85 fraction Hydrophobic-haired upper surface rides clear of the water
SLA_cm2_per_mg_C 3.0 cm² / mg C Conspicuous dangling roots add wetted biofilm substrate; scaled by (1 − aerial) = 0.15 ⇒ ~0.45 cm² effective per mg frond C

Stoichiometry

Symbol Value Units Source / Rationale
C:N 10.0 mol / mol N-rich angiosperm tissue
C:N (max under N starvation) 24.0 mol / mol Wider than Salvinia — the lean, reddening N-limited state
N:P 14.0 mol / mol Near-Redfield

N & P uptake

Symbol Value Units Source / Rationale
K_N (water) 5e-6 mol/L ~0.070 mg N/L; competent but less avid scavenger than Salvinia (4e-6)
K_NO3 (water) 1.5e-5 mol/L Lower NO3 affinity vs. NH4
K_P (water) 3e-7 mol/L High P affinity
Q_P,max 0.025 mol P / mol C Salvinia-scale P reservoir
Q_N,min 0.005 mol N / mol C Droop floor
Q_N,max 0.018 mol N / mol C Modest luxury-N margin
V_P,max (luxury) 3.0e-4 mol P / (mol C · h) Salvinia-scale (sub-duckweed) luxury kernel
V_N,max (luxury) 2.0e-3 mol N / (mol C · h) Salvinia-scale luxury N rate
K_PO4 (luxury uptake) 1.5e-7 mol/L Salvinia-scale transporter half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 8.0e-4 /h ~3.6% of P_max; preserves the floater maintenance ratio at the lower P_max

Mortality & death routing

Symbol Value Units Source / Rationale
Frond mortality 1.5e-4 /h ~0.36%/day; slightly higher turnover than Salvinia (melts more readily)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 26.0 °C Tropical; warmer optimum than Salvinia
T_lethal,photo 42.0 °C Warm-water lethal
T_stress (low / high) 16.0 / 34.0 °C Cold-sensitive tropical lower bound
T_lethal (low / high) 8.0 / 42.0 °C Killed by cold well before Salvinia (4 °C) / duckweed (2 °C)
Q10,photo 2.0 Base
Q10,resp 2.2 Base

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.0 / 8.0 Prefers soft, slightly acidic to neutral water
pH lethal (low / high) 4.0 / 9.5

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Strictly freshwater
σ_S 2.5 PSU Salt-sensitive
S_stress (low / high) 0.0 / 3.0 PSU Sensitive tropical species
S_lethal (low / high) 0.0 / 6.0 PSU

Submerged macrophyte base

Generic submerged-plant kinetic skeleton — stems suspended in the water column with leaf-borne uptake and Beer-Lambert self-shading.

Trace-metal:C overrides

Symbol Value Units Source / Rationale
K:C 5.0e-2 mol K / mol C Macrophyte K:C anchor (mirrors floating/rooted)
B:C 5.0e-5 mol B / mol C Marschner 1995 — vascular cell-wall pectin RG-II
K_K (growth) 1.0e-5 mol/L Mirror of floating base K leaf scale

Stem geometry & light

Symbol Value Units Source / Rationale
Stem depth 7.5 cm Mid-tank in 15 cm tank (scenario-overridable)
k_stem,atten 120.0 L / (mol C · m) Kirk 1994; Spence 1975 — macrophyte tissue ~40% of phytoplankton absorbance per mol C
P_max 0.006 /h ~0.14/day generic submerged-macrophyte rate
I_K 30.0 µmol m⁻² s⁻¹ Generic submerged-macrophyte half-sat

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 15e-6 mol/L Mid-point of the 10–25 µM CO₂ half-sat band (passive diffusion / RuBisCO; producer.py note). Raised from 5e-6, which left a plant ~75% carbon-saturated at atmospheric CO₂ (~14 µM) and unable to respond to CO₂ injection. Concrete species override (hornwort 5e-6, Rotala 25e-6); no existing scenario uses the bare default.
CCM efficiency 0.35 fraction Moderate HCO₃ use; subclasses override
K_HCO3 1.5e-3 mol/L Madsen & Sand-Jensen 1991 — mid-range for submerged macrophytes with CCM
Sc/o 80.0 Standard C3 RuBisCO
PQ 1.0 mol O₂ / mol C Standard
DOC excretion fraction 0.05 fraction Generic excretion fraction

Stoichiometry

Symbol Value Units Source / Rationale
C:N 17.0 mol / mol Submerged macrophyte structural ratio
C:N (max under N starvation) 35.0 mol / mol Maximum C:N under N starvation
N:P 22.0 mol / mol Generic submerged ratio

N & P uptake

Symbol Value Units Source / Rationale
V_N,max (water) 1.2e-3 mol N / (mol C · h) Generic high-affinity submerged macrophyte uptake
V_P,max (water) 8e-5 mol P / (mol C · h) Generic submerged macrophyte P uptake
K_N (water) 5e-6 mol/L ~0.07 mg N/L (high-affinity leaf system)
K_NO3 (water) 2e-5 mol/L Lower NO3 affinity
K_P (water) 4e-7 mol/L ~0.012 mg P/L
NO₃ preference (dark / light) 0.1 / 0.4 fraction Standard producer source preference
K_N (total, helper) 8e-6 mol/L Producer helper
K_NH4 (helper) 5e-6 mol/L Producer helper
K_NO3 (helper) 2e-5 mol/L Producer helper
K_PO4 (helper) 4e-7 mol/L Producer helper
Min photo N factor 0.10 fraction Floor on photo-N factor

Droop internal stores

Symbol Value Units Source / Rationale
Q_P,min 0.004 mol P / mol C Gerloff 1966 critical tissue P, slightly lower than floating (more cellulose)
Q_P,max 0.025 mol P / mol C Madsen & Cedergreen 2002; Pedersen et al. 2013 vacuolar Pi
Q_N,min 0.0015 mol N / mol C ~0.3 × Q_N,max
Q_N,max 0.005 mol N / mol C Gerloff & Krombholz 1966; Best 1979; Madsen & Cedergreen 2002 — C:N 16–25
V_P,max (luxury) 2.0e-4 mol P / (mol C · h) Proportional to lower P_max vs. Lemna
V_N,max (luxury) 1.5e-3 mol N / (mol C · h) Generic submerged-macrophyte luxury rate
K_PO4 (luxury uptake) 1.5e-7 mol/L Pedersen et al. 2013 — Lk ≈ 0.15 µM for M. spicatum
K_NH4 (luxury uptake) 5.0e-6 mol/L Source preference half-sat
K_NO3 (luxury uptake) 2.0e-5 mol/L Source preference half-sat
Q10 (uptake) 2.0 Eppley 1972 transporter scaling
k_catab (storage) 0.001 /h Slow stored-pool hydrolysis
k_N homeostasis 0.01 /h 4-day timescale matched to recalibrated Q_N,max

Respiration

Symbol Value Units Source / Rationale
R_maint 6e-4 /h ~0.06%/h (10% of P_max)
K_O2 (respiration) 1.0e-5 mol/L O₂ half-sat for respiration
Osmoregulation cost 0.002 per PSU deviation Osmoregulation cost
Dark respiration factor 0.65 fraction Heskel et al. 2013; Atkin & Tjoelker 2003 LEDR

Mortality & death routing

Symbol Value Units Source / Rationale
Stem mortality 1.5e-4 /h ~0.36%/day baseline senescence
O2 stress threshold 1.5 mg/L Mortality ×2 threshold
m_total,max 0.30 /h Mortality cap
Death → suspended fraction 0.30 fraction Higher than floating (fragments, no fronds to sink)
Surface death → suspended 0.30 fraction Mirror

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 22.0 °C Temperate submerged optimum
T_lethal,photo 38.0 °C Upper lethal photo
T_ref T_REF_C (25) °C Standard biology reference
Q10,photo 2.0 Standard
Q10,resp 2.2 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 8.0 / 32.0 °C Stress thresholds (temperate)
T_lethal (low / high) 2.0 / 38.0 °C Cold-hardy lower; upper lethal
m_thermal,max 0.02 /h Max thermal mortality

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.5 Broad tolerance (hallmark)
pH lethal (low / high) 4.5 / 11.0
m_pH,max 0.015 /h Max pH mortality

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 4.0 PSU Broad salinity tolerance width
S_stress (low / high) 0.0 / 5.0 PSU
S_lethal (low / high) 0.0 / 10.0 PSU
m_salinity,max 0.10 /h Max salinity mortality

Hornwort / Ceratophyllum — divergent only

Rootless K-strategist submerged angiosperm that drives high-pH soft-water systems via aggressive HCO₃⁻ stripping and a strong polyphenol allelopathy. (Only divergences from the Submerged macrophyte base are shown.)

Stem geometry & light

Symbol Value Units Source / Rationale
k_stem,atten 120.0 L / (mol C · m) Spence 1975 — dense hornwort mats ~70–80% attenuation per 20 cm
P_max 6e-3 /h Nichols & Shaw 1986; Barko & Smart 1981 — net doubling 15–25 d
I_K 20.0 µmol m⁻² s⁻¹ Shade-tolerant; persists under floating mats and turbid water
SLA_cm2_per_mg_C 100.0 cm² / mg C Brönmark 1985; Mony et al. 2010 — highly dissected filiform leaves; the largest epiphytic substrate of any tracked macrophyte. Recalibrated from V1=300 (May 2026) against Walstad-target leaf area (~10× static substrate at peak macrophyte biomass)

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 5e-6 mol/L Intentionally high-affinity (below the 15e-6 submerged base): efficient dual-pathway carbon user / low CO₂ compensation point. Immaterial to behaviour — the strong CCM below dominates carbon supply (5→15 µM shifts biomass −2.6%), which is why hornwort barely responds to CO₂ injection (a hardy low-tech plant).
CCM efficiency 0.45 fraction Prins & Elzenga 1989 — strong HCO₃⁻ user; raises pH in hard water
K_HCO3 0.6e-3 mol/L Maberly & Madsen 2002 — one of most aggressive HCO₃⁻ strippers
DOC excretion fraction 0.06 fraction Slightly elevated; phenolic exudates

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.001 fraction Hilt & Gross 2008; Nakai 2000; Hilt 2006 — calibrated to <50 µg GAE/L field window

Stoichiometry

Symbol Value Units Source / Rationale
C:N 17.0 mol / mol Duarte 1992; Vestergaard & Sand-Jensen 2000 — C:N 15–20
C:N (max under N starvation) 35.0 mol / mol Maximum under N starvation
N:P 22.0 mol / mol N:P 20–25 (Duarte 1992)

N & P uptake

Symbol Value Units Source / Rationale
V_N,max (water) 1.2e-3 mol N / (mol C · h) Rattray et al. 1991 — high-affinity stem uptake
V_P,max (water) 8e-5 mol P / (mol C · h) Generic submerged P uptake
K_N (water) 5e-6 mol/L ~0.07 mg N/L — high affinity
K_NO3 (water) 2e-5 mol/L Lower NO3 affinity
K_P (water) 4e-7 mol/L ~0.012 mg P/L
Q_P,min 0.004 mol P / mol C Generic submerged structural floor
Q_P,max 0.025 mol P / mol C Best 1977 — vacuolar Pi in Ceratophyllum
Q_N,min 0.0015 mol N / mol C Mirror of submerged base
Q_N,max 0.005 mol N / mol C Gerloff & Krombholz 1966; Best 1979 — C:N 16–25 for C. demersum
V_P,max (luxury) 2.0e-4 mol P / (mol C · h) Proportional to lower P_max
V_N,max (luxury) 1.5e-3 mol N / (mol C · h) Generic submerged luxury rate
K_PO4 (luxury uptake) 1.5e-7 mol/L Pedersen et al. 2013 (M. spicatum)
K_NH4 (luxury uptake) 5.0e-6 mol/L Source preference half-sat
K_NO3 (luxury uptake) 2.0e-5 mol/L Source preference half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 6e-4 /h 10% of P_max ratio
K_O2 (respiration) 1e-5 mol/L O₂ half-sat for respiration

Mortality & death routing

Symbol Value Units Source / Rationale
Stem mortality 1.5e-4 /h ~0.36%/day baseline
O2 stress threshold 1.5 mg/L Tolerates moderate hypoxia
Death → suspended fraction 0.35 fraction Slightly higher than base (fragmenting stems)

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 22.0 °C Best 1977 — temperate hardy, optimum 20–24 °C
T_lethal,photo 38.0 °C Upper lethal
T_ref 20.0 °C Hornwort-specific reference
T_stress (low / high) 8.0 / 32.0 °C
T_lethal (low / high) 2.0 / 38.0 °C Survives near-freezing

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.5 Thrives at pH 6–9
pH lethal (low / high) 4.5 / 11.0

Salinity envelope

Symbol Value Units Source / Rationale
σ_S 2.0 PSU Narrow (no marine tolerance)
S_stress (low / high) 0.0 / 3.0 PSU
S_lethal (low / high) 0.0 / 6.0 PSU

Rotala rotundifolia — divergent only

The archetypal high-tech stem plant and the model's CO₂-responsive submersed species: fast, a poor bicarbonate user, low CO₂ affinity, water-column carbon. Built as the carbon-limited counterpoint to hornwort — it is the species that does respond strongly to CO₂ injection (+263% biomass vs a no-CO₂ twin with N/P/K held replete). (Only divergences from the Submerged macrophyte base are shown.)

Stem geometry & light

Symbol Value Units Source / Rationale
Stem depth 5.0 cm Stem tips grow toward the light (shallower effective depth than hornwort)
k_stem,atten 90.0 L / (mol C · m) Rounded leaves, less feathery than hornwort whorls
P_max 1.8e-2 /h ~0.43/day — fast stem plant; between hornwort (6e-3) and the fast floaters. Barko & Smart 1981
I_K 45.0 µmol m⁻² s⁻¹ High-light demanding (cf hornwort 20)
SLA_cm2_per_mg_C 60.0 cm² / mg C Rounded leaves; less epiphytic area than hornwort

Carbon kinetics — the CO₂-responsive profile

Symbol Value Units Source / Rationale
K_CO2 2.5e-5 mol/L ≈25 µM effective whole-plant half-sat → only ~36% carbon-saturated at ambient (~14 µM), relieved by injection (the model's carbon-limited end). NOTE: this is NOT "poor RuBisCO affinity" — CO2-restricted submerged plants in fact have higher intrinsic CO2 affinity than HCO3 users (Maberly & Madsen 2002). Rotala is carbon-limited because (a) high P_max ⇒ high carbon DEMAND, and (b) the unstirred diffusive boundary layer (CO2 diffuses ~10⁴× slower in water than air) raises the apparent whole-leaf half-saturation. Madsen & Sand-Jensen 1991; Maberly & Madsen 2002.
CCM efficiency 0.10 fraction Poor bicarbonate user — the defining "high-tech only" trait. Maberly & Madsen 2002
K_HCO3 2.0e-3 mol/L Weak, low-affinity CCM
Allelo release fraction 0.0 fraction Not notably allelopathic

Stoichiometry & uptake

Symbol Value Units Source / Rationale
C:N 15.0 mol / mol Fast grower, N-rich tissue
C:N (max) 30.0 mol / mol Max under N starvation
N:P 20.0 mol / mol Fast-grower ratio
V_N,max / V_P,max (water) 1.8e-3 / 1.2e-4 mol / (mol C · h) Scaled ~50% above hornwort to match the higher P_max (so N/P don't mask carbon)

Respiration, mortality, temperature

Symbol Value Units Source / Rationale
maint_O2 1.8e-3 /h 10% of P_max (base-class scaling rule)
Senescence 3.0e-4 /h ~0.72%/day — faster turnover than the hardy plants
T_opt (photo) 26.0 °C Tropical SE Asian; warmer optimum than hornwort
pH stress (low / high) 5.5 / 8.5 pH Comfortable in the injected-tank range

Rooted macrophyte base

Two-compartment plant with shoot (leaf-borne water-column uptake) and root (sediment pore-water uptake), aerenchyma-mediated rhizosphere O₂ release and pore CO₂ access, and phloem translocation between compartments.

Trace-metal:C overrides

Symbol Value Units Source / Rationale
K:C 5.0e-2 mol K / mol C Quigg / Sterner & Elser / Marschner 2012 — plant K:C anchor, ~2× universal; ~50 mg K/g tissue C
B:C 5.0e-5 mol B / mol C O'Neill 2004; Kobayashi 1996; Marschner 1995 — RG-II pectin crosslinker, ~50 µg B/g DW

Attachment

Symbol Value Units Source / Rationale
Attached surface "" string Empty = first non-dynamic static surface
anchorage_factor 1.0 Substrate establishment factor — a direct multiplier on gross photosynthesis (→ growth), like Fe_factor / allelo_factor. Models how well the bed lets the crown root and establish, NOT fertility (an inert bed still feeds the plant only from the water column). Set per-instance by the webapp builder from substrate_type via surface_generator.SUBSTRATE_ANCHORAGE: soil 1.0 (roots grip + pore-fed, existing behaviour), inert sand 1.0 (fine grains anchor a crown as well as a soil sand-cap), inert gravel 0.6 (coarse grains let crowns work loose — hobbyist lore that most stem/rosette plants struggle in bare gravel without root tabs; reduced, not zero), bare 0.0 (nothing to root into → the plant can't establish and declines). config.py does NOT inject it; hand-authored/legacy scenarios keep the 1.0 default and are bit-identical. Realised growth effect is condition-dependent — strongest when the plant is carbon/light-limited, muted when water-column nutrient-limited; the bare 0.0 (decline) case is unconditional.

Canopy & light

Symbol Value Units Source / Rationale
P_max 0.010 /h ~0.24/day generic rooted-macrophyte rate (10–100× slower than algae)
I_K 20.0 µmol m⁻² s⁻¹ Low-light adapted
k_canopy,atten 0.0 m² / mol C Default: rosette plants don't form a water-column canopy
k_shoot,atten 0.0 L / (mol C · m) Default: rosette plants don't attenuate at depth

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 15e-6 mol/L Within the 10–25 µM band (producer.py note). Concrete species override (Cryptocoryne 9e-6, Vallisneria 25e-6) and now carry the carbon response directly — rooted plants are leaf/water-column carbon users (f_root_CO2 small/zero), so this is no longer "moot via pore CO2"; it just keeps the base default self-consistent. No scenario uses the bare default.
CCM efficiency 0.25 fraction Moderate CCM HCO₃⁻ use
K_HCO3 1.5e-3 mol/L Madsen & Sand-Jensen 1991; Maberly & Madsen 2002 — Elodea/Potamogeton range
Sc/o 80.0 Standard C3 RuBisCO
PQ 1.0 mol O₂ / mol C Standard
DOC excretion fraction 0.05 fraction Standard producer excretion
f_root,CO2 0.0 fraction Default: no pore-CO2 access; subclasses override
f_root,O2 release 0.0 fraction Default: no aerenchyma ROL; subclasses set per literature (1–8% of GPP)

Stoichiometry

Symbol Value Units Source / Rationale
C:N (shoot) 15.0 mol / mol Structural C:N (rooted shoot tissue)
C:N (shoot, max under N starvation) 30.0 mol / mol Maximum under N starvation
N:P (shoot) 20.0 mol / mol Redfield-like; macrophytes P-poor
C:N (root) 20.0 mol / mol Roots more C-rich / N-poor than shoots
N:P (root) 30.0 mol / mol Generic root stoichiometry

Acquisition split (shoot vs root)

Symbol Value Units Source / Rationale
f_water 0.30 fraction Barko & Smart 1985; Carignan & Kalff 1980 — sediment-dominated default
f_root 0.70 fraction Barko & Smart 1985 — 60–90% of P from sediment in most species
α_root 0.25 fraction Lambers et al. 2008 — 20–40% below-ground C allocation
k_translocate 0.005 /h Marschner 1995 — phloem mass-flow ~3-day timescale. Conductance scales by the phloem bottleneck min(shoot_C, root_C) (narrower conduit limits transport), so the flux vanishes as either compartment senesces — equals the legacy × root_C scaling whenever shoot ≥ root (the established case) and bounds the term's Jacobian to ±k, removing a die-off stiffness trap

N & P uptake (shoot, water-column)

Symbol Value Units Source / Rationale
V_N,max (water) 5e-4 mol N / (mol C · h) Lower than microalgae (leaf area-limited)
V_P,max (water) 3e-5 mol P / (mol C · h) Lower than microalgae
K_N (water) 1e-5 mol/L Nurnberg 1984 — K_NH4 10–50 µmol/L for submersed leaves
K_NO3 (water) 4e-5 mol/L Lower NO3 affinity
K_P (water) 5e-7 mol/L Bole & Allan 1978 — leaf K_P
K_K (water) 1e-5 mol/L ~0.39 mg K/L; leaf uptake (higher than phytoplankton)
V_P,max (luxury, water) 8.0e-5 mol P / (mol C · h) Generic shoot luxury P
V_N,max (luxury, water) 6.0e-4 mol N / (mol C · h) Generic shoot luxury N
K_PO4 (luxury water uptake) 5.0e-7 mol/L Leaf transporter half-sat
K_NH4 (luxury water uptake) 1.0e-5 mol/L Leaf transporter half-sat
K_NO3 (luxury water uptake) 4.0e-5 mol/L Leaf NO3 half-sat
K_N (helper) 1e-5 mol/L Inline-uptake half-sat (dual-uptake logic)
K_NH4 (helper) 5e-6 mol/L Inline-uptake half-sat
K_NO3 (helper) 2e-5 mol/L Inline-uptake half-sat
K_PO4 (helper) 5e-7 mol/L Inline-uptake half-sat
NO₃ preference (dark / light) 0.1 / 0.4 fraction Source preference
Min photo N factor 0.15 fraction Floor on photo N factor (slightly higher than algae)

N & P uptake (root, pore-water)

Symbol Value Units Source / Rationale
K_N (pore) 2e-6 mol/L Epstein & Hagen 1952; Caffrey & Kemp 1992 — high-affinity root system I
K_NO3 (pore) 8e-6 mol/L Root NO3 half-sat
K_P (pore) 1e-7 mol/L Barko et al. 1991 — K_P_pore ~0.1 µmol/L
K_K (pore) 2e-6 mol/L Schroeder & Fang 1991; Britto & Kronzucker 2008 — HAK/KUP at ~0.05 mg K/L
V_P,max (luxury, root) 2.0e-4 mol P / (mol C · h) ~3× shoot (Epstein & Hagen 1952; Caffrey & Kemp 1992)
V_N,max (luxury, root) 1.5e-3 mol N / (mol C · h) ~3× shoot luxury rate
K_PO4 (luxury pore uptake) 1.0e-7 mol/L Pedersen et al. 2013 — root high-affinity Pi (M. spicatum)
K_NH4 (luxury pore uptake) 2.0e-6 mol/L Root high-affinity
K_NO3 (luxury pore uptake) 8.0e-6 mol/L Root NO3 half-sat
V_K,max 1.5e-3 mol K / (mol C · h) ~3× V_N,max to accommodate K:C anchor + luxury

Droop internal stores

Symbol Value Units Source / Rationale
Q_P,min 0.003 mol P / mol C Gerloff 1966 critical tissue P
Q_P,max 0.020 mol P / mol C Madsen & Cedergreen 2002; Barko et al. 1991; Carignan & Kalff 1980
Q_N,min 0.002 mol N / mol C ~0.25 × Q_N,max
Q_N,max 0.008 mol N / mol C Barko & Smart 1981; Madsen & Cedergreen 2002; Lambers 2008 — C:N 15–30
Q10 (uptake) 2.0 Eppley 1972
k_catab (storage) 0.001 /h Slow stored-pool hydrolysis
k_N homeostasis 0.01 /h 4-day timescale (recalibrated with Q_N,max anchor)

Sediment coupling

Symbol Value Units Source / Rationale
Pore-water volume 0.02 L Default; should match PoreWaterDiffusion process
Fe-oxide sufficient 1.0e-5 mol Rhizosphere Fe acquisition threshold (proxy for pore Fe²⁺)

Respiration

Symbol Value Units Source / Rationale
R_maint 8e-4 /h ~0.08%/h base; must scale with P_max in subclasses
K_O2 (respiration) 1.0e-5 mol/L O₂ half-sat for respiration
Root respiration 0.001/24 (~4.17e-5) /h Lambers et al. 2008 — roots ~30–50% of 0.5–2%/day whole-plant respiration
Osmoregulation cost 0.002 per PSU deviation Osmoregulation cost
Dark respiration factor 0.65 fraction Heskel 2013; Atkin & Tjoelker 2003; Turnbull et al. 2005 LEDR

Mortality & death routing

Symbol Value Units Source / Rationale
Root mortality 0.005/24 (~2.08e-4) /h Sand-Jensen 1975; Chambers & Kalff 1985 — 0.3–1%/day temperate
Shoot mortality 0.003/24 (~1.25e-4) /h ~0.3%/day baseline leaf senescence
O2 stress threshold 2.0 mg/L O2 below → shoot mortality ×3
m_total,max 0.30 /h Mortality cap
Death → suspended fraction 0.05 fraction Mostly settled (heavy leaf litter)
Surface death → suspended 0.05 fraction Mirror

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 24.0 °C Generic rooted-macrophyte optimum
T_lethal,photo 38.0 °C Upper lethal photo
T_ref T_REF_C (25) °C Standard biology reference
Q10,photo 2.0 Standard
Q10,resp 2.2 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 15.0 / 30.0 °C Tropical-aroid lower stress; upper
T_lethal (low / high) 5.0 / 38.0 °C
m_thermal,max 0.02 /h Max thermal mortality

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0
pH lethal (low / high) 5.0 / 10.5
m_pH,max 0.015 /h Max pH mortality

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 3.0 PSU Tolerance width
S_stress (low / high) 0.0 / 5.0 PSU
S_lethal (low / high) 0.0 / 15.0 PSU Slightly more tolerant than other macrophytes
m_salinity,max 0.10 /h Max salinity mortality

Vallisneria — divergent only

Tall strap-leaved rooted angiosperm with a canopy that attenuates water-column light and balanced shoot/root uptake. (Only divergences from the Rooted macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
P_max 1.5e-3 /h Titus & Adams 1979 — optimal 0.04–0.10/day for V. americana
I_K 45.0 µmol m⁻² s⁻¹ Physiological literature half-saturation for V. americana (Titus & Adams 1979; Meyer et al. 1943). Restored from a prior proxy value of 20 now that rooted-shoot light is modelled geometrically: a rooted plant's leaves rise off the bed into the water column and read the depth-averaged column light (Model.rhs → env._rooted_shoot_water_column_light), not the shaded benthic-substrate light. Previously, fed shaded benthic light at the true I_K=45, Vallisneria ran at ~½ of shade-tolerant Crypt's Lfac and became the slowest grower despite a 3× higher P_max (backwards); the 20 proxy compensated. With the geometry now explicit, the half-saturation returns to its honest value and the height advantage shows up as the intended column-light advantage.
Light saturation 200.0 µmol m⁻² s⁻¹ Informational saturation point
Photoinhibition threshold 1200.0 µmol m⁻² s⁻¹ Informational photoinhibition threshold
k_canopy,atten 0.45 m² / mol C Sand-Jensen 1998; Madsen et al. 2001; Titus & Adams 1979 — SLA × k_extinction
k_shoot,atten 40.0 L / (mol C · m) Tall strap-leaves attenuate at depth (Beer-Lambert)
SLA_cm2_per_mg_C 17.0 cm² / mg C Madsen & Brix 1997 — strap leaves, ~100–200 cm²/g dry weight. Recalibrated from V1=50 (May 2026) against Walstad-target leaf area (~10× static substrate at peak macrophyte biomass)

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 2.5e-5 mol/L Generic Vallisneria-scale half-sat (the strong HCO3 CCM, not CO2 diffusion, is its main carbon route)
CCM efficiency 0.40 fraction Prins & Elzenga 1989 — strong bicarbonate user; this (not pore CO2) is its low-tech carbon security
K_HCO3 0.8e-3 mol/L Maberly 1985 — Elodea/Potamogeton high-affinity CCM
f_root,CO2 0.15 fraction Reduced from 0.30. Vallisneria is an elodeid; elodeids make little use of sediment CO2 (Madsen & Sand-Jensen 1991; Maberly & Madsen 2002). Small residual = aerenchyma CO2 reaching the crown; the strong CCM carries low-tech viability. Yields a modest CO2-injection response (small in hard water where HCO3 saturates it, larger in soft water).
f_root,O2 release 0.06 fraction Sand-Jensen et al. 1982 — Vallisneria ROL ~5–8% of GPP

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.0003 fraction Hilt 2006 — ~1/3 of hornwort baseline; field-realistic

Stoichiometry

Symbol Value Units Source / Rationale
C:N (shoot) 20.0 mol / mol Structural shoot ratio
C:N (shoot, max under N starvation) 40.0 mol / mol Maximum under N starvation
N:P (shoot) 28.0 mol / mol Leaf N:P
C:N (root) 16.0 mol / mol Roots slightly less C-rich than leaves
N:P (root) 22.0 mol / mol Root N:P

Acquisition split

Symbol Value Units Source / Rationale
f_water 0.45 fraction More balanced than Crypt; exploits open-water NH4 via leaves
f_root 0.55 fraction Less sediment-dominated than Crypt
α_root 0.22 fraction Slightly less rhizome-heavy than Crypt; runners carry own C

N & P uptake

Symbol Value Units Source / Rationale
K_N (water) 1.2e-5 mol/L Vallisneria-scale leaf half-sat
K_N (pore) 1.8e-6 mol/L High-affinity root
K_P (water) 2.5e-7 mol/L Vallisneria-scale leaf P
K_P (pore) 4.0e-8 mol/L High-affinity root P
Q_P,min 0.003 mol P / mol C Mirror of rooted base
Q_P,max 0.020 mol P / mol C Mirror of rooted base
Q_N,min 0.0015 mol N / mol C ~0.25 × Q_N,max
Q_N,max 0.006 mol N / mol C Barko & Smart 1981; Tessier et al. 2008 — V. americana C:N 18–25
V_P,max (luxury, water) 8.0e-5 mol P / (mol C · h) Faster luxury kinetic vs base
V_P,max (luxury, root) 2.0e-4 mol P / (mol C · h) Root luxury P
V_N,max (luxury, water) 6.0e-4 mol N / (mol C · h) Fast-grower luxury N
V_N,max (luxury, root) 1.5e-3 mol N / (mol C · h) Root luxury N
K_PO4 (luxury water uptake) 2.5e-7 mol/L Leaf transporter half-sat
K_PO4 (luxury pore uptake) 4.0e-8 mol/L Root high-affinity
K_NH4 (luxury water uptake) 1.2e-5 mol/L Leaf NH4 half-sat
K_NH4 (luxury pore uptake) 1.8e-6 mol/L Root NH4 high-affinity
K_NO3 (luxury water uptake) 4.0e-5 mol/L Leaf NO3 half-sat
K_NO3 (luxury pore uptake) 8.0e-6 mol/L Root NO3 half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 1.875e-4 /h Preserves 0.125 ratio with P_max (matches Crypt scaling)
Root respiration 2.0e-4 /h Somewhat faster turnover than Crypt

Mortality & death routing

Symbol Value Units Source / Rationale
Root mortality 5.0e-5 /h ~0.12%/day
Shoot mortality 3.5e-5 /h ~0.084%/day
O2 stress threshold 1.5 mg/L O2 below → shoot mortality ×3
O2 anoxia threshold 0.2 mg/L Informational anoxia threshold

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 24.0 °C Warm optimum
T_stress (low / high) 15.0 / 28.0 °C
T_lethal (low / high) 12.0 / 32.0 °C Cooler-tolerant than Crypt
Q10,photo 2.1 Slightly elevated
Q10,resp 2.1 Mirror

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 Tolerates hard water well
pH lethal (low / high) 5.5 / 10.5 More alkaline-tolerant

Dwarf Sagittaria / Sagittaria subulata — divergent only

Short, runner-spreading rooted Alismataceae grown as a hardy foreground carpet. Functionally a shorter, more brackish- and cool-tolerant, more root-dependent cousin of Vallisneria: a moderate carpeter with no water-column canopy, a lower light requirement, and — its distinguishing trait among the rooted roster — genuine brackish tolerance from its native tidal-freshwater / oligohaline range. Submerged-form ecophysiology is sparse, so parameters are set by analogy to Vallisneria and shifted to encode those four traits. (Only divergences from the Rooted macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
P_max 1.0e-3 /h ~2.4%/day; a moderate carpeter — above shade-adapted Cryptocoryne (5e-4), below fast Vallisneria (1.5e-3). Kasselmann 2003 (undemanding, runner-carpeting Sagittaria)
I_K 30.0 µmol m⁻² s⁻¹ Between shade-adapted Cryptocoryne (20) and light-demanding Vallisneria (45). Undemanding, low-to-medium-light plant; a genuine half-saturation, not a geometry proxy (rooted-shoot light is modelled directly). The lower I_K gives it a modest column-light edge over Vallisneria in dimmer tanks
Light saturation 180.0 µmol m⁻² s⁻¹ Informational saturation point
Photoinhibition threshold 1200.0 µmol m⁻² s⁻¹ Informational photoinhibition threshold
k_canopy,atten 0.0 m² / mol C Short foreground carpet — leaves stay well below the surface, so no water-column canopy (matches short-rosette Cryptocoryne; contrast Vallisneria 0.45). The primary stature difference from Vallisneria
k_shoot,atten 0.0 L / (mol C · m) Short blades — no Beer-Lambert depth shading of benthos
SLA_cm2_per_mg_C 15.0 cm² / mg C Madsen & Brix 1997 strap-leaf range; narrow awl/strap blades — a little below Vallisneria's 17

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 2.5e-5 mol/L Vallisneria-scale half-sat; carbon-secure across the aquarium pH range via the CCM
CCM efficiency 0.35 fraction Competent HCO₃⁻ user (hard/alkaline tolerant) but weaker than Vallisneria's strong 0.40 — less biogenic decalcification. Maberly & Madsen 2002
K_HCO3 1.0e-3 mol/L Working-CCM affinity (Maberly & Madsen 2002 — Elodea/Potamogeton 0.5–2 mM band)
f_root,CO2 0.15 fraction Small aerenchyma pore-CO₂ residual, as Vallisneria. Flexible-leaved submerged grass (elodeid-type carbon acquisition), not a stiff isoetid rosette; kept low because f_root,CO2 is near-binary (pore CO₂ ≫ water CO₂). Modest CO₂-injection response (small in hard water, larger in soft)
f_root,O2 release 0.05 fraction Amphibious Alismataceae with well-developed aerenchyma; a little below Vallisneria (0.06) for its lower shoot:root ratio. Sand-Jensen et al. 1982

Stoichiometry

Symbol Value Units Source / Rationale
C:N (shoot) 18.0 mol / mol Structural grassy blade — a touch less C-rich than Vallisneria (20)
N:P (shoot) 26.0 mol / mol Leaf N:P
C:N (root) 16.0 mol / mol Roots slightly less C-rich than leaves
N:P (root) 22.0 mol / mol Root N:P

Acquisition split

Symbol Value Units Source / Rationale
f_water 0.35 fraction Heavy root feeder — leaf uptake secondary
f_root 0.65 fraction Between Cryptocoryne (0.80) and Vallisneria (0.55); Alismataceae rosette responds strongly to rich substrate. Barko & Smart 1985; Carignan & Kalff 1980
α_root 0.28 fraction Runner-and-rhizome-heavy carpet invests substantially below-ground (stolons + crown)

N & P uptake

Symbol Value Units Source / Rationale
K_N (water) 1.2e-5 mol/L Vallisneria-scale leaf half-sat
K_N (pore) 1.6e-6 mol/L High-affinity root; a touch tighter than Vallisneria (heavier root reliance)
K_P (water) 2.5e-7 mol/L Vallisneria-scale leaf P
K_P (pore) 4.0e-8 mol/L High-affinity root P
Q_P,min / Q_P,max 0.003 / 0.020 mol P / mol C Mirror of rooted base
Q_N,min / Q_N,max 0.0015 / 0.006 mol N / mol C Structural strap-leaf tissue carries little luxury N (Barko & Smart 1981)
V_P,max (luxury, water / root) 7.0e-5 / 2.2e-4 mol P / (mol C · h) Root-weighted vs Vallisneria — heavier root reliance
V_N,max (luxury, water / root) 5.0e-4 / 1.5e-3 mol N / (mol C · h) Vallisneria-scale luxury N
K_PO4 (luxury water / pore) 2.5e-7 / 4.0e-8 mol/L Leaf / root high-affinity
K_NH4 (luxury water / pore) 1.2e-5 / 1.6e-6 mol/L Leaf / root high-affinity
K_NO3 (luxury water / pore) 4.0e-5 / 8.0e-6 mol/L Leaf / root half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 1.25e-4 /h Preserves the 0.125 maintenance-to-P_max ratio (1.25e-4 / 1.0e-3)
Root respiration 1.8e-4 /h Near Vallisneria

Mortality & death routing

Symbol Value Units Source / Rationale
Root mortality 4.5e-5 /h ~0.11%/day
Shoot mortality 3.0e-5 /h ~0.072%/day; hardy blades, slightly slower senescence than Vallisneria
O2 stress threshold 1.5 mg/L O2 below → shoot mortality ×3

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 23.0 °C Subtropical/temperate optimum
T_stress (low / high) 14.0 / 29.0 °C
T_lethal (low / high) 8.0 / 34.0 °C Tolerates cooler water than Vallisneria (12 °C) / Cryptocoryne (14 °C) — eastern-N.-American native
Q10,photo 2.0 Base
Q10,resp 2.1 Mirror

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 Tolerates hard water well
pH lethal (low / high) 5.0 / 10.0 Wide, hard-water capable

Salinity envelope — the distinctive trait

Symbol Value Units Source / Rationale
S_opt 1.0 PSU Optimum still freshwater, but shifted off zero
σ_S 6.0 PSU Wide Gaussian — genuine brackish tolerance
S_stress (low / high) 0.0 / 8.0 PSU Tolerates oligohaline water that stresses the other rooted plants
S_lethal (low / high) 0.0 / 18.0 PSU True brackish ceiling (above rooted base 15); native tidal-freshwater / oligohaline range (Godfrey & Wooten 1979; Haynes & Hellquist 2000)

Amazon Sword / Echinodorus grisebachii — divergent only

Large rosette specimen plant (Alismataceae; the aggregate that subsumes the old aquarium names E. bleheri / E. amazonicus), the classic planted-tank background sword. Functionally a tall, canopy-forming, very-heavy-root-feeding, strictly-tropical big brother of the roster: a Vallisneria-scale canopy plant with Cryptocoryne-scale root dependence and no cold or salt tolerance. Submerged-form ecophysiology is sparse, so parameters are set by analogy to Vallisneria (the other tall canopy former) and dwarf sagittaria (its small Alismataceae cousin), then shifted to encode four traits: large canopy stature, very heavy root feeding with the largest root allocation, a warm tropical envelope, and moderate growth with a clear CO₂ response. (Only divergences from the Rooted macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
P_max 8.0e-4 /h ~1.9%/day; a moderate grower — above shade-adapted Cryptocoryne (5e-4), below the moderate carpeter dwarf sag (1.0e-3) and fast Vallisneria (1.5e-3). Large final size is an emergent of sustained moderate growth on a big individual, not a high specific rate. Kasselmann 2003 (Echinodorus "medium" growth)
I_K 40.0 µmol m⁻² s⁻¹ A large plant that needs moderate-to-bright light to fill big leaves, but hardy/adaptable — a notch below light-demanding Vallisneria (45), above shade-adapted Cryptocoryne (20) / dwarf sag (30). Genuine half-saturation, not a geometry proxy (rooted-shoot light modelled directly)
Light saturation 220.0 µmol m⁻² s⁻¹ Informational saturation point
Photoinhibition threshold 1200.0 µmol m⁻² s⁻¹ Informational photoinhibition threshold
k_canopy,atten 0.50 m² / mol C Tall canopy former — broad leaves rise toward the surface and cast a heavy shadow (like Vallisneria, unlike short dwarf-sag / Crypt rosettes). Just above Vallisneria's 0.45: a broad-leaf umbrella shades more per unit biomass than narrow straps. The primary stature contrast with dwarf sag (k=0)
k_shoot,atten 45.0 L / (mol C · m) Broad leaves → a touch above Vallisneria's 40 for Beer-Lambert depth shading of benthos
SLA_cm2_per_mg_C 16.0 cm² / mg C Broad, relatively thin lanceolate leaves; a touch below Vallisneria's straps (17). Madsen & Cedergreen 2002 broad-leaf range

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 2.0e-5 mol/L High CO₂ affinity → clear CO₂-injection response; carbon-secure at ambient via the CCM
CCM efficiency 0.30 fraction Moderate HCO₃⁻ user (hard/alkaline tolerant) but weaker than Vallisneria's strong 0.40; combined with the high CO₂ affinity, low-tech viable yet a clear CO₂ responder. Maberly & Madsen 2002
K_HCO3 1.0e-3 mol/L Working-CCM affinity (Maberly & Madsen 2002)
f_root,CO2 0.15 fraction Small aerenchyma pore-CO₂ residual, as Vallisneria/dwarf sag. Leafy elodeid-type carbon acquisition, not a stiff isoetid; kept low because f_root,CO2 is near-binary (pore CO₂ ≫ water CO₂). Leaves a clear CO₂-injection response in soft water
f_root,O2 release 0.06 fraction Large, well-aerenchymatised amphibious Alismataceae with an extensive root system; at the Vallisneria level. Sand-Jensen et al. 1982

Stoichiometry

Symbol Value Units Source / Rationale
C:N (shoot) 19.0 mol / mol Broad structural leaf — between the grassy dwarf sag / Crypt (18) and Vallisneria's straps (20)
N:P (shoot) 27.0 mol / mol Leaf N:P
C:N (root) 16.0 mol / mol Roots slightly less C-rich than leaves
N:P (root) 22.0 mol / mol Root N:P

Acquisition split

Symbol Value Units Source / Rationale
f_water 0.25 fraction Very heavy root feeder — leaf uptake secondary, though the big leaf canopy still captures meaningful water-column N
f_root 0.75 fraction Between dwarf sag (0.65) and Cryptocoryne (0.80); the archetypal root-tab plant, responds dramatically to a rich substrate. Barko & Smart 1985; Carignan & Kalff 1980
α_root 0.30 fraction The largest below-ground carbon allocation of the roster (thick extensive root system + rhizome), above Cryptocoryne / dwarf sag (0.28), well above Vallisneria (0.22) — the source of the pronounced establishment lag

N & P uptake

Symbol Value Units Source / Rationale
K_N (water) 1.2e-5 mol/L Vallisneria-scale leaf half-sat
K_N (pore) 1.5e-6 mol/L Very high-affinity root; tighter than Vallisneria (heaviest root reliance)
K_P (water) 2.5e-7 mol/L Vallisneria-scale leaf P
K_P (pore) 3.5e-8 mol/L Heaviest-root-feeder pore-P affinity (below dwarf sag 4.0e-8)
Q_P,min / Q_P,max 0.003 / 0.022 mol P / mol C Slightly larger P reservoir than dwarf sag (0.020) — a big rhizome/root system stores more luxury P (Walstad 1999)
Q_N,min / Q_N,max 0.0015 / 0.006 mol N / mol C Structural broad-leaf tissue carries little luxury N (Barko & Smart 1981)
V_P,max (luxury, water / root) 7.0e-5 / 2.4e-4 mol P / (mol C · h) Root-weighted — heaviest root reliance of the roster
V_N,max (luxury, water / root) 5.0e-4 / 1.6e-3 mol N / (mol C · h) Root-weighted vs Vallisneria/dwarf sag
K_PO4 (luxury water / pore) 2.5e-7 / 3.5e-8 mol/L Leaf / root high-affinity
K_NH4 (luxury water / pore) 1.2e-5 / 1.5e-6 mol/L Leaf / root high-affinity
K_NO3 (luxury water / pore) 4.0e-5 / 7.0e-6 mol/L Leaf / root half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 1.0e-4 /h Preserves the 0.125 maintenance-to-P_max ratio (1.0e-4 / 8.0e-4)
Root respiration 1.8e-4 /h Near Vallisneria

Mortality & death routing

Symbol Value Units Source / Rationale
Root mortality 4.0e-5 /h ~0.10%/day; the big root system persists
Shoot mortality 2.5e-5 /h ~0.06%/day; hardy broad leaves, long-lived once established (between Cryptocoryne 2.0e-5 and dwarf sag 3.0e-5)
O2 stress threshold 1.5 mg/L O2 below → shoot mortality ×3

Thermal envelope — genuinely tropical

Symbol Value Units Source / Rationale
T_opt 26.0 °C Warm tropical optimum
T_stress (low / high) 18.0 / 30.0 °C Warm-water plant
T_lethal (low / high) 15.0 / 34.0 °C No cold tolerance — markedly higher lethal floor than temperate dwarf sag (8 °C) or subtropical Vallisneria (12 °C); tropical Central/South-American native
Q10,photo 2.0 Base
Q10,resp 2.1 Mirror

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 8.5 Soft acidic to moderately hard
pH lethal (low / high) 5.0 / 9.5 Wide, adaptable

Salinity envelope

Strictly freshwater — not overridden, inherits the rooted base (S_opt 0.5 PSU, σ_S 3.0, S_lethal 15). The clean contrast with dwarf sag's estuarine brackish tolerance.

Cryptocoryne — divergent only

Tropical rosette aroid that anchors the Walstad-tank archetype — sediment-dominated uptake, no CCM, primary CO₂ acquired via aerenchyma from pore water. (Only divergences from the Rooted macrophyte base are shown.)

Canopy & light

Symbol Value Units Source / Rationale
P_max 5.0e-4 /h Barko & Smart 1985; Sand-Jensen 1983 — submersed macrophyte low end (~0.14%/day net)
I_K 20.0 µmol m⁻² s⁻¹ Very shade-tolerant. Cryptocoryne are among the most shade-adapted aquarium plants — SE-Asian understory stream species (Kasselmann 2003) — so a half-saturation at the low end of the shade-plant range (10–25) is physiologically appropriate, and below Vallisneria's 45 (Crypt is the more shade-tolerant of the two). A genuine half-saturation, not a geometry proxy: rooted-shoot light is now modelled directly (leaves read the depth-averaged water-column light, env._rooted_shoot_water_column_light), so I_K no longer has to absorb the missing vertical-light geometry.
Light saturation 80.0 µmol m⁻² s⁻¹ Informational saturation point
Photoinhibition threshold 800.0 µmol m⁻² s⁻¹ Informational high-light inhibition
SLA_cm2_per_mg_C 13.0 cm² / mg C Madsen & Cedergreen 2002 — broad rosette leaves, ~80–150 cm²/g dry weight. Recalibrated from V1=40 (May 2026) against Walstad-target leaf area (~10× static substrate at peak macrophyte biomass)

Carbon kinetics

Symbol Value Units Source / Rationale
K_CO2 9.0e-6 mol/L High CO2 affinity (~0.4 mg CO2/L half-sat). Shade-/low-CO2-stream-adapted elodeid → low CO2 compensation point implies high diffusive affinity (Maberly & Madsen 2002: CO2-restricted species have HIGHER affinity than HCO3 users). Raised from 3.5e-5, which left a leaf-fed Crypt only ~29% carbon-saturated at ambient and non-viable in inert tanks where crypts thrive. At 9 µM ambient CO2_fac ≈ 0.67 (moderate water), climbing toward saturation under injection.
CCM efficiency 0.10 fraction Modest bicarbonate use (was 0.0). Crypts tolerate moderately hard/alkaline water (some SE-Asian species in limestone streams; Kasselmann 2003) → weak CCM, not pure CO2 dependence. Small enough to preserve a real injection response; large enough to floor low-tech viability in hard water.
K_HCO3 1.5e-3 mol/L Rooted-base default; now active (CCM efficiency > 0)
f_root,CO2 0.0 fraction DISABLED (was 0.70). Cryptocoryne is an elodeid, not an isoetid: significant sediment-CO2 use is not found in elodeids (long aerenchyma diffusion path, low shoot/root ratio, high inherent photosynthesis rate — Madsen & Sand-Jensen 1991; Maberly & Madsen 2002). The old isoetid analogue made Crypt a CO2 NON-responder; carbon is now leaf/water-column-sourced so injection reaches it (modest, all-positive response). Roots remain the dominant MINERAL-nutrient supply (f_root = 0.80); only the carbon-source split changed.
f_root,O2 release 0.03 fraction Sand-Jensen et al. 1982; Caffrey & Kemp 1991 — slow rosette ROL ~2–4% of GPP

Allelochemistry

Symbol Value Units Source / Rationale
Allelo release fraction 0.0003 fraction Walstad 1999 — phenolic suppression in low-tech tanks; ~1/3 hornwort baseline

Stoichiometry

Symbol Value Units Source / Rationale
C:N (shoot) 18.0 mol / mol Leaf C:N
C:N (shoot, max under N starvation) 35.0 mol / mol Maximum under N stress
N:P (shoot) 30.0 mol / mol P-conservative species
C:N (root) 15.0 mol / mol Roots more N-rich than leaves
N:P (root) 25.0 mol / mol Root N:P

Acquisition split

Symbol Value Units Source / Rationale
f_water 0.20 fraction Strongly substrate-dominated
f_root 0.80 fraction 80% N from pore water (Walstad-tank archetype)
α_root 0.28 fraction Rhizome-heavy plant (high end of 25–35%)

N & P uptake

Symbol Value Units Source / Rationale
K_N (water) 1.5e-5 mol/L Lower leaf affinity
K_N (pore) 2.0e-6 mol/L High-affinity root
K_P (water) 3.0e-7 mol/L Leaf P half-sat
K_P (pore) 5.0e-8 mol/L High-affinity root P
Q_P,min 0.003 mol P / mol C Mirror of rooted base
Q_P,max 0.025 mol P / mol C Walstad 1999 — long persistence under pulse-feeding (bigger Pi store than Vallisneria)
Q_N,min 0.0015 mol N / mol C ~0.3 × Q_N,max
Q_N,max 0.005 mol N / mol C Madsen & Cedergreen 2002; Lambers et al. 2008 — tropical-aroid C:N 18–30
V_P,max (luxury, water) 6.0e-5 mol P / (mol C · h) Slow K-strategist luxury P
V_P,max (luxury, root) 1.5e-4 mol P / (mol C · h) Root luxury P (slower than Vallisneria)
V_N,max (luxury, water) 4.0e-4 mol N / (mol C · h) Slow luxury N
V_N,max (luxury, root) 1.0e-3 mol N / (mol C · h) Root luxury N
K_PO4 (luxury water uptake) 3.0e-7 mol/L Leaf transporter half-sat
K_PO4 (luxury pore uptake) 5.0e-8 mol/L High-affinity Pi (upregulated under low-PO4)
K_NH4 (luxury water uptake) 1.5e-5 mol/L Leaf NH4 half-sat
K_NH4 (luxury pore uptake) 2.0e-6 mol/L Root high-affinity
K_NO3 (luxury water uptake) 4.0e-5 mol/L Leaf NO3 half-sat
K_NO3 (luxury pore uptake) 8.0e-6 mol/L Root NO3 half-sat

Respiration

Symbol Value Units Source / Rationale
R_maint 6.25e-5 /h Preserves 0.125 ratio with P_max
Root respiration 5.0e-5 /h ~0.12%/day; rhizome has low respiration

Mortality & death routing

Symbol Value Units Source / Rationale
Root mortality 3.0e-5 /h ~0.07%/day; very slow turnover
Shoot mortality 2.0e-5 /h ~0.048%/day; very hardy
O2 stress threshold 1.0 mg/L Less O2-sensitive than algae
O2 anoxia threshold 0.1 mg/L Informational anoxia threshold

Thermal envelope

Symbol Value Units Source / Rationale
T_opt 24.0 °C Tropical optimum
T_stress (low / high) 15.0 / 30.0 °C
T_lethal (low) 10.0 °C Lower lethal (warmer than Vallisneria)
Q10,photo 2.0 Standard
Q10,resp 2.0 Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 8.5 Kasselmann 2003 — accelerated senescence above pH 8.5
pH lethal (low / high) 4.5 / 9.5 Upper lethal narrower than Vallisneria

Consumers

Consumers — grazers, detritivores, and the first predator (hydra) — share a Holling-II ingestion / SDA-respiration / stoichiometric-homeostasis skeleton, layered with hypoxia, NH₃, NO₂, Cu²⁺, H₂S, and allelochemical tolerance kernels. Stage-structured zooplankton (daphnia, copepod, ostracod) add a dormant resting-pool channel; shrimp and snails add molting + shell Ca stoichiometry; gape-limited predators (hydra) target a specific prey life-stage.

Consumer symbol glossary

Symbol Meaning
Imax Maximum specific ingestion rate (per h per mol body C)
K_C Holling-II food-density half-saturation (mol C/L)
SDA fraction Specific dynamic action — heat increment of feeding (fraction of assimilated C)
Nocturnal feeding fraction Day-to-night ingestion ratio (>1 means more active at night)
Assim N / P multiplier Per-element assimilation efficiency relative to C (typically 1.10–1.15)
RQ Respiratory quotient — mol CO₂ released per mol O₂ consumed
R_maint, K_O2 (resp) Maintenance respiration rate and O₂ Monod for respiration
Q10,ingestion / resp / mort Temperature sensitivities per process
K_O2 (activity) O₂ Monod for ingestion (separate from respiration)
K_NH3,tox / K_NO2,tox / K_Cu,tox / K_H2S,tox Mortality half-saturations for each toxicant (Hill-2 with same K)
m_X,max Maximum mortality rate from stressor X (NH3, NO2, Cu, H2S, hypoxia, thermal, pH, salinity, viral, starvation, crowding)
K_allelo,polyphenol / K_allelo,cyanotoxin / K_allelo,cyanotoxin,feeding Half-sats for allelochemical kernels (mortality and feeding suppression)
K_crowding Density half-saturation for crowding mortality (per-volume or per-area)
Fe:C, Cu:C, ... Per-element body composition ratios (subset of producer trace-metal anchor for consumers)
Shell Ca per body C Calcareous structure routed to CaCO₃ substrate on death
Molt rate, molt Ca per C Crustacean molting interval (Q10-scaled) and Ca cost per molt
dev_a, dev_α, dev_b Belehrádek juvenile-to-adult development parameters (h·°C^
τ_brood Mean berried period for Erlang-3 reproduction pipeline (days)
t_mature Sexual maturity age (days)
Dormant base / max fraction Resting-egg (ephippia / cyst) allocation floor and ceiling
Hatch rate (max) Maximum specific hatching rate of dormant pool (per h)
Dormant mortality Resting-pool turnover (per h; viability often years to centuries)
Feces C:N, Feces → suspended fraction Egesta stoichiometry and routing between suspended/settled detritus
Sloppy feeding DOM fraction Fraction of egesta released as cytoplasmic DOM (Møller 2005)
K_viral, m_viral,max Density half-sat and max rate for viral-lysis kernel (only ciliate / nanoflagellate)
SURFACE_PROTECTION_PROFILE Dispatcher for prey-access modifier — NONE (planktonic / macrophyte / consumer prey, no surface kernel) or BIOFILM_RESIDENT (everything that lives on a surface — bacteria, nitrifiers, periphyton-forming algae — gets 1 − protection shelter that interpolates from a roughness-based M=0 floor up to a species-specific M=1 cap)

The shared consumer machinery lives in species/consumer.py (Holling-II / SDA / homeostasis / mortality), species/consumer_food.py (the catalogue of food-type structural recipes), species/consumer_removal.py (the mixin that routes intake back into prey pools, including stage-targeted juvenile prey), species/_element_release.py (per-element respiration release + mortality close-out), and species/access.py (single source of truth for prey accessibility: effective_access = static_access × density_refugia × M-modifier).

Between that framework and a named animal sit three guild bases, each a parameter surface rather than a species: species/consumers/_stage_structured_consumer.py (juvenile / adult / dormant zooplankton), species/consumers/_gastropod_base.py (snails) and species/consumers/_decapod_base.py (shrimp, scuds — and the crayfish and crabs that internal_docs/planning/invert_roster_expansion.md generates). A value in the Gastropod base or Decapod base table below is one that every animal in that guild carries; a species table only lists what that species actually differs on. Where a species row repeats a guild value, the guild table is the source of truth and the species declares nothing.

What "Derived" means on an invertebrate's thermal and pH rows

The five invertebrates the engine models — bladder snail, ramshorn, Malaysian trumpet snail, cherry shrimp, scud — no longer carry hand-set temperature and pH envelopes. Each is computed from that animal's published keeping range by the single rule in stocking/tolerance_model.py, the same one that gives all 982 generated fish their bands:

  • stress band = published range widened by ±3.0 °C / ±0.5 pH;
  • lethal band = stress widened by −5.0 / +3.0 °C and −1.0 / +0.8 pH (asymmetric on purpose: heat kills faster than cold);
  • a published pH range narrower than 1.5 units is first widened about its midpoint, because a range that narrow reads as an under-specified article rather than a genuinely narrow animal.

Two things about that rule are worth stating here rather than leaving in the planning doc.

The margins are the fish's, carried as a prior, not refitted on the inverts. Fitting them to the four hand-rolled invertebrates was tried and measured to fail: their cold margin spreads 14 °C and its sign flips, because the snails were written "a pest snail survives anything" and the shrimp narrower than published because shrimp are famously sensitive. Three usable points that disagree by more than the quantity being fitted are not a fit.

The rule inherits the quality of its input. Where a published range is thin or cold-shifted, so is the derived band — the derivation is consistent, not omniscient. The row most exposed to this is the cherry shrimp's cold bound, which the rule moves up from 15.0 °C to 19.0 °C.

The published range and the rung it came from are on each row. The derivation, the coverage measurement and the tier-row envelope that answers for animals with no page of their own live in stocking/invert_water.py and internal_docs/planning/invert_roster_expansion.md §I3.

Gastropod base

What is true of a freshwater aquarium snail rather than of one species. Concrete snails (bladder, ramshorn, MTS) override only what genuinely distinguishes them — body size, ingestion kinetics, the O₂ and thermal envelopes, and shell Ca demand.

Symbol Value Units Source / Rationale
Body C:N 5.5 mol/mol Protein-rich mollusc soft tissue, shell excluded (Dillon 2000)
Body N:P 20.0 mol/mol P-rich relative to a fish — shell formation concentrates P in the mantle
R_maint 0.0003 /h per mol C Low basal metabolism (ectotherm)
SDA fraction 0.15 fraction Simpler digestion than a copepod
O2-limited waste excretion True bool
Q10,ingestion / resp / mort 2.2 / 2.2 / 1.6 Standard mollusc temperature sensitivities
m_thermal,max 0.02 /h
S_opt / σ_S 0.3 / 3.0 PSU Freshwater pulmonate with the slight brackish tolerance Physidae and Planorbidae both show; the euryhaline thiarid (MTS) overrides the whole envelope
S_stress / S_lethal (high) 4.0 / 8.0 PSU
m_salinity,max 0.20 /h
Osmotic cost 0.003 per PSU deviation
Feces C:N 12.0 mol/mol
Feces → suspended fraction 0.10 fraction Benthic animal — 90% of feces settles
Death → suspended fraction 0.05 fraction Shells + tissue settle
Crowds over full surface True bool Snails climb glass, hardscape and plant leaves, not just the floor
Crowding Hill n 1.5 Feeding-interference steepness (Brown, Carman & Inchausty 1994)
m_crowding,max 0.0 /h Crowding suppresses per-capita grazing; it does not kill snails (Brown et al. 1994 — crowded snails retain C and respire more). Density dependence rides K_crowding,feeding instead, so the population booms then plateaus rather than crashing. MTS is the exception and overrides it: an obligate burrower with no soil genuinely fails to establish
pH stress (low) / lethal (low, high) 6.5 / 5.5 / 10.0 pH Shells dissolve below ~pH 6.5; snails tolerate alkaline water well (Dillon 2000). A fallback, not a shared value: since §I3 every snail with a published pH range derives all four bounds from it and declares them on the leaf. These are what a future snail with no range would get
K_NH3,tox (stress onset) 5.0e-6 mol/L Uniform across the aquarium snails; the lethal end is per-species
Soft-water growth factor 0.5 multiplier Growth halved when Ca²⁺ is below the species' shell-stress threshold
Shredding rate 0.0 /h per mol C Off by default — only the rasping surface-grazers shred; the deposit-feeding burrower does not
K_shred,settled 1.5e-5 mol C/L Half-sat on settled-detritus availability
K_Cu,tox 4.7e-7 mol/L ~30 µg/L. Gastropods are the target of the hobby's copper-sulfate "snail treatments" (10–50 µg/L clears a population overnight); EPA AWQC mollusc acute criteria cluster at 20–50 µg/L. Above the freshwater crustaceans — the operculum and less permeable foot epithelium buffer gill uptake
K_H2S,tox 2.0e-6 mol/L
m_total,max 0.50 /h Mortality rate cap

Decapod base

What is true of a freshwater aquarium crustacean. (Hyalella is an amphipod, not a decapod; the name is for the shared physiology — moulting, cuticle Ca demand, a soft-shell window, and gill NO₂⁻ uptake — every part of which is true of both and none of which is true of a snail.)

Symbol Value Units Source / Rationale
O2-limited waste excretion True bool
T_lethal (high) 32.0 °C Upper lethal for the temperate-to-subtropical freshwater crustaceans. A fallback since §I3: the scud derives to exactly this and inherits it, the cherry shrimp derives to 34.0 and declares it
S_opt 0.2 PSU Pure-freshwater default; the brackish cells are deferred (freshwater_v1_scope)
Osmotic cost 0.003 per PSU deviation
Death → suspended fraction 0.05 fraction Carcass and shed exuviae settle
Crowds over full surface True bool Shrimp and scuds crawl and swim over the whole tank. Reading the benthic floor alone is what used to kill adults at ordinary hobby stocking densities
Crowding Hill n 1.5
m_crowding,max 0.0 /h Interference, not death — same finding as the gastropods (Brown et al. 1994). Cherry shrimp additionally express density dependence as a reproduction plateau
pH stress (high) / lethal (low, high) 9.0 / 5.5 / 10.0 pH Acid-side stress point is per-species: cuticle Ca²⁺ uptake fails at low pH. A fallback, not a shared value — since §I3 both crustaceans derive all four bounds from their published range and declare them on the leaf
m_pH,max 0.04 /h
m_NH3,max 0.06 /h
K_NO2,tox (stress) 3.6e-5 mol/L ~0.5 mg NO₂-N/L — the lower "safe" bound for freshwater invertebrates (Lewis & Morris 1986). Inherited unchanged from the Consumer default
K_NO2,tox (lethal) 5.7e-4 mol/L ~8.0 mg NO₂-N/L, near the M. rosenbergii larval 96-h LC50 (Armstrong, Stephenson & Knight 1976)
m_NO2,max 0.021 /h A 96-h LC50 is a constant mortality of ln(2)/96 h = 0.0072/h; this ramp passes through that at the 3.14 mg-N/L M. malcolmsonii LC50. The crustacean NO₂ axis is one number for the whole guild — gill uptake on the Na⁺/Cl⁻ pathway oxidises haemocyanin Fe(II), putting crustaceans ~4× more sensitive than snails. Cl⁻ is protective and is not tracked in V1, so this is calibrated for soft-to-moderate freshwater
T_ref,molt 22.0 °C Reference temperature for the moult clock
Q10,molt 2.0
Molt Ca-stress rate factor 0.5 multiplier Below the species' molt_Ca_stress threshold the animal moults half as often…
Molt Ca-stress mortality factor 2.0 multiplier …and dies twice as readily in the soft-shell window
Shredding rate 0.0 /h per mol C Off by default — only the litter-tearing shredders (the scud) do this
K_shred,settled 1.5e-5 mol C/L
m_total,max 0.50 /h Mortality rate cap

Consumer base

Shared anchors for every grazer / detritivore / predator. Concrete species override individual rows where they deviate.

Ingestion & assimilation

Symbol Value Units Source / Rationale
SDA fraction 0.20 fraction of assim C Specific dynamic action — heat increment of feeding, 10–25% of assimilated energy in crustaceans (Gnaiger 1983)
Nocturnal feeding fraction 0.7 fraction of day rate Diel ingestion scaling
O2-limited waste excretion False bool Excrete excess C as DIC under O2 limit
RQ 0.85 mol CO₂ / mol O₂ Mixed protein/lipid catabolism (Gnaiger 1983)
Assim N multiplier 1.10 × C assim N assimilated ~10% more efficiently than C (Sterner & Elser 2002; Urabe et al. 1995)
Assim P multiplier 1.15 × C assim P assimilated ~15% more efficiently than C (Sterner & Elser 2002; Urabe et al. 1995)
Sloppy feeding DOM fraction 0.10 fraction of egest Sloppy-feeding cytoplasmic leakage to DOM (Møller 2005)
Bare-surface algae access max 3.0 × access Max bare-surface algae access boost on smooth substrate (roughness→0)

Trace-metal:C overrides (consumer-specific deviations from universal detritus anchor)

Symbol Value Units Source / Rationale
Fe:C 3.0e-5 mol Fe / mol C Above universal detritus anchor (haemoproteins, cytochromes)
Mo:C 2.0e-8 mol Mo / mol C Xanthine / sulfite / aldehyde oxidase Mo holdings
Zn:C 1.0e-6 mol Zn / mol C Zinc-fingers, metalloproteases, Cu/Zn-SOD (Sterner & Elser 2002; Martin & Knauer 1973)
Cu:C 2.0e-7 mol Cu / mol C Crustacean haemocyanin, cyt-c oxidase (Sterner & Elser 2002; White & Rainbow 1987)
K:C 1.0e-2 mol K / mol C Below universal anchor — shells/chitin dilute K demand (Sterner & Elser 2002)
Ni:C 2.0e-7 mol Ni / mol C Digestive urease + Ni metalloproteins (Sterner & Elser 2002)
Co:C 1.0e-8 mol Co / mol C Cobalamin (B12) cofactor (Sterner & Elser 2002)
B:C 5.0e-6 mol B / mol C At universal anchor — incidental dietary B
S:C 5.0e-3 mol S / mol C At universal anchor — protein S close to bulk biomass

Mortality routing & NO₂ toxicity defaults

Symbol Value Units Source / Rationale
Exposure mortality max 0.0 /h Biofilm-immaturity mortality on bare surfaces; ostracod overrides (Roca et al. 1993)
Death → DOM fraction 0.0 fraction Direct lysis-to-DOM at death; protist overrides (Nagata 2000; Fuhrman 1992)
Shell Ca per body C 0.0 mol Ca / mol C Calcareous-structure Ca routed to CACO3_SUBSTRATE on death
K_NO2,tox (stress) 3.6e-5 mol/L ~0.5 mg NO2-N/L invertebrate stress
K_NO2,tox (lethal) 3.6e-4 mol/L ~5 mg NO2-N/L invertebrate lethal
m_NO2,max 0.04 /h Slightly gentler than NH3 (Cl⁻ competes, reversible)

Rotifer

Smallest planktonic grazer — high mass-specific metabolism, exquisitely cyano-sensitive, mechanically suppressed by Daphnia.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.015 cm ~100–200 µm
Imax 0.07 /h ~1.7/day; higher than Daphnia (Starkweather & Gilbert 1977)
K_C 4.0e-5 mol C/L ~0.48 mg C/L half-sat
SDA fraction 0.20 fraction No direct source
Nocturnal feeding fraction 0.9 fraction No direct source

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Yufera & Pascual 1989
N:P 16.0 mol / mol Redfield

Respiration

Symbol Value Units Source / Rationale
R_maint 0.004 /h Higher mass-specific metabolism than Daphnia
K_O2 (respiration) 3.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 4.0e-5 mol/L No direct source
O2 stress 4.0e-5 mol/L No direct source
O2 lethal 1.5e-5 mol/L No direct source
m_hypoxia,max 0.08 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion 2.3 No direct source
Q10,resp 2.0 No direct source
Q10,mort 1.8 No direct source
T_stress (low / high) 8.0 / 30.0 °C No direct source
T_lethal (low / high) 2.0 / 38.0 °C No direct source
m_thermal,max 0.04 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater optimum
σ_S 2.5 PSU No direct source
S_stress (low / high) 0.0 / 3.0 PSU Stenohaline
S_lethal (low / high) 0.0 / 8.0 PSU No direct source
m_salinity,max 0.30 /h No direct source
Osmoregulation cost 0.005 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 No direct source
pH lethal (low / high) 5.0 / 10.0 No direct source
m_pH,max 0.05 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 3.5e-6 mol/L No direct source
NH3 lethal 7.0e-5 mol/L No direct source
m_NH3,max 0.10 /h No direct source

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_allelo,cyanotoxin 5.0e-6 mol C/L Most cyano-sensitive grazer (Gilbert 1990; Pereira et al. 2004)
K_allelo,cyanotoxin,feeding 2.0e-6 mol C/L Cilia paralysis sub-µg/L (Gilbert 1990)

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.06 / 24 /h ~6%/day (Galkovskaya 1995)
Feces C:N 10.0 mol / mol No direct source
Feces → suspended fraction 0.70 fraction Small body — most feces stays suspended
Death → suspended fraction 0.50 fraction No direct source
Starvation m_max 0.10/24 /h No direct source
Crowding m_max 0.06/24 /h No direct source
K_crowding 1.0e-4 mol/L No direct source
Daphnia interference m_max 0.04/24 /h Mechanical-interference suppression (Gilbert 1988)
K_Daphnia interference 1.5e-4 mol C/L ~1.8 mg C Daphnia density half-sat
m_total,max 0.50 /h Cap

Daphnia

Filter-feeding cladoceran with high-P body and ephippial dormancy; tightly linked to chlorophyll and prone to crash under cyanobacterial blooms.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.15 cm ~1–2 mm adult
Imax 0.06 /h ~1.4/day max ingestion
K_C 5.0e-5 mol C/L ~0.6 mg C/L half-sat (Lampert 2006)
SDA fraction 0.20 fraction No direct source
Nocturnal feeding fraction 0.7 fraction No direct source

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol No direct source
N:P 12.0 mol / mol P-rich (Elser et al. 2000)

Respiration

Symbol Value Units Source / Rationale
R_maint 0.003 /h No direct source
K_O2 (respiration) 5.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 6.0e-5 mol/L ~2 mg/L
O2 stress 7.0e-5 mol/L ~2.2 mg/L
O2 lethal 2.0e-5 mol/L ~0.6 mg/L
m_hypoxia,max 0.08 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion 2.0 Bottrell 1975; Lampert 1977 (ingestion Q10 ≈ 1.9–2.1, 10–25 °C)
Q10,resp 2.0 No direct source
Q10,mort 1.8 No direct source
T_stress (low / high) 4.0 / 25.0 °C No direct source
T_lethal (low / high) 0.0 / 30.0 °C No direct source
m_thermal,max 0.04 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 3.0 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 10.0 PSU No direct source
m_salinity,max 0.30 /h No direct source
Osmoregulation cost 0.005 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 No direct source
pH lethal (low / high) 5.0 / 10.0 No direct source
m_pH,max 0.05 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 3.5e-6 mol/L No direct source
NH3 lethal 7.0e-5 mol/L No direct source
m_NH3,max 0.10 /h No direct source
NO2 stress 2.1e-5 mol/L ~0.3 mg N/L (Dowden & Bennett 1965; Russo 1985)
NO2 lethal 2.1e-4 mol/L ~3 mg N/L
m_NO2,max 0.06 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 1.6e-7 mol/L Borgmann et al. 1993
K_H2S,tox 5.0e-7 mol/L No direct source

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_allelo,cyanotoxin 8.0e-6 mol C/L ~0.16 mg MC-LR/L; 50% mortality 24h (Rohrlack et al. 2003)
K_allelo,cyanotoxin,feeding 3.0e-6 mol C/L Feeding suppression below mortality K (Rohrlack 1999; DeMott 1991)

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.02/24 /h ~2%/day
Feces C:N 10.0 mol / mol No direct source
Feces → suspended fraction 0.25 fraction No direct source
Death → suspended fraction 0.10 fraction No direct source
Starvation m_max 0.07/24 /h No direct source
Crowding m_max 0.05/24 /h ~5%/day at high density
K_crowding 2.0e-4 mol N/L ~4 mg N/L half-sat
m_total,max 0.50 /h Cap

Reproduction & life-stage (Belehrádek + ephippia)

Symbol Value Units Source / Rationale
dev_a 10650.0 h·°C^|b| Belehrádek a; egg→primipara ~10 d at 20 °C (Bottrell 1975; Goss & Bunting 1983)
dev_α -10.0 °C Belehrádek biological-zero
dev_b -2.05 Belehrádek exponent
Dormant food-limit threshold 0.30 fraction Ephippial-cue food limit (Stross & Hill 1965)
Dormant density threshold 1.0e-3 mol N/L Crowding cue
Dormant T-drop threshold 12.0 °C Cool-T cue
Dormant short-day threshold 12.0 h Short-day cue (Hobæk & Larsson 1990)
Dormant max fraction 0.40 fraction Max ephippial allocation
Dormant base fraction 0.03 fraction Constitutive ephippia (3%)
T_hatch (min) 10.0 °C No direct source
K_food (hatch) 2.0e-5 mol C/L Food-Monod for hatching
k_hatch,max 1.4e-4 /h ~10%/month under ideal (Cáceres 1998)
Dormant mortality 1.4e-7 /h ~0.1%/yr; ephippia viable for centuries (Hairston et al. 1995)
Initial adult fraction 1.0 fraction Hobbyist adds adults
Initial dormant fraction 0.0 fraction No pre-existing egg bank by default
Introduction adult fraction 1.0 fraction
Introduction dormant fraction 0.0 fraction

Copepod

Cyclopoid-leaning omnivore with adult cannibalism on nauplii, broader thermal tolerance than Daphnia, and longer-lived resting eggs.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.10 cm ~1 mm
Imax 0.058 /h Cyclopoid-leaning defaults
K_C 2.0e-5 mol C/L No direct source
SDA fraction 0.18 fraction No direct source
Nocturnal feeding fraction 0.8 fraction No direct source

Stoichiometry

Symbol Value Units Source / Rationale
C:N 4.5 mol / mol No direct source
N:P 22.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0025 /h No direct source
K_O2 (respiration) 4.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 5.0e-5 mol/L No direct source
O2 stress 5.5e-5 mol/L No direct source
O2 lethal 1.5e-5 mol/L No direct source
m_hypoxia,max 0.06 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion 2.0 No direct source
Q10,resp 1.8 No direct source
Q10,mort 1.6 No direct source
T_stress (low / high) 1.0 / 30.0 °C No direct source
T_lethal (low / high) 0.0 / 34.0 °C No direct source
m_thermal,max 0.03 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 4.0 PSU No direct source
S_stress (low / high) 0.0 / 6.0 PSU No direct source
S_lethal (low / high) 0.0 / 15.0 PSU No direct source
m_salinity,max 0.25 /h No direct source
Osmoregulation cost 0.004 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.5 No direct source
pH lethal (low / high) 4.5 / 10.5 No direct source
m_pH,max 0.04 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 5.0e-6 mol/L No direct source
NH3 lethal 1.0e-4 mol/L No direct source
m_NH3,max 0.08 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 2.4e-7 mol/L ~15 µg Cu/L; less Cu-sensitive than Daphnia (Hutchinson 1947; Williamson 1986)
K_H2S,tox 8.0e-7 mol/L No direct source

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_allelo,cyanotoxin 1.2e-5 mol C/L Less acute than Daphnia (Reinikainen et al. 2002; DeMott 1991)
K_allelo,cyanotoxin,feeding 5.0e-6 mol C/L Feeding suppression earlier than mortality

Mortality, feces, cannibalism

Symbol Value Units Source / Rationale
m_base 0.015/24 /h No direct source
Feces C:N 9.0 mol / mol No direct source
Feces → suspended fraction 0.35 fraction No direct source
Death → suspended fraction 0.20 fraction No direct source
Starvation m_max 0.04/24 /h No direct source
Cannibalism m_max 0.05/24 /h Cyclopoid adults predate nauplii
K_cannibalism 2.0e-5 mol N/L Calibrated to planted-aquarium cyclopoid densities (~10-100 ind/L × ~0.5 µg N each → ~5e-6 to 5e-5 mol N/L). The legacy 3e-4 was anchored to eutrophic-pond bloom densities and never engaged in 20 L tanks. May 2026: validated via Walstad 365d diagnostic where the new K reduced copepod peak by 74%.
m_total,max 0.50 /h Cap

Reproduction & life-stage (Belehrádek + resting eggs)

Symbol Value Units Source / Rationale
dev_a 26600.0 h·°C^|b| Belehrádek a; calanoid egg→adult ~25 d at 20 °C (Munro 1974; Hart 1990)
dev_α -10.0 °C Belehrádek biological-zero
dev_b -2.05 Belehrádek exponent
Dormant food-limit threshold 0.30 fraction No direct source
Dormant density threshold 1.5e-3 mol N/L Widened vs Daphnia (Frisch 2002; Hansen 1998)
Dormant T-drop threshold 8.0 °C Widened — cyclopoids encyst at both ends
Dormant short-day threshold 12.0 h No direct source
Dormant max fraction 0.50 fraction Higher ceiling than Daphnia (Frisch 2002)
Dormant base fraction 0.04 fraction Constitutive 4%
T_hatch (min) 10.0 °C No direct source
K_food (hatch) 2.0e-5 mol C/L No direct source
k_hatch,max 1.4e-4 /h Same envelope as Daphnia
Dormant mortality 1.4e-7 /h Hairston 1987/1996 (centuries-viable)
Initial adult / dormant fraction 1.0 / 0.0 fraction
Introduction adult / dormant fraction 1.0 / 0.0 fraction

Ostracod

Benthic seed-shrimp browser/picker — durable resting eggs and a constitutive bare-substrate exposure mortality (vulnerable to predation when biofilm immature).

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.075 cm ~0.75 mm
Imax 0.030 /h No direct source
K_C 1.0e-5 mol C/L No direct source
SDA fraction 0.18 fraction No direct source
Nocturnal feeding fraction 0.7 fraction No direct source
Water-change removal fraction 0.15 fraction Benthic crawler, mostly avoids siphon
Exposure mortality max 0.001 /h Bare-substrate vulnerability (Roca et al. 1993)

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol No direct source
N:P 20.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0022 /h No direct source
K_O2 (respiration) 3.5e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 4.0e-5 mol/L No direct source
O2 stress 4.0e-5 mol/L No direct source
O2 lethal 1.0e-5 mol/L No direct source
m_hypoxia,max 0.05 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.1 / 2.15 / 1.7 No direct source
T_stress (low / high) 5.0 / 28.0 °C No direct source
T_lethal (low / high) 0.0 / 33.0 °C No direct source
m_thermal,max 0.03 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU No direct source
σ_S 4.0 PSU No direct source
S_stress (low / high) 0.0 / 6.0 PSU No direct source
S_lethal (low / high) 0.0 / 15.0 PSU No direct source
m_salinity,max 0.25 /h No direct source
Osmoregulation cost 0.004 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.5 No direct source
pH lethal (low / high) 4.5 / 10.5 No direct source
m_pH,max 0.04 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 4.0e-6 mol/L No direct source
NH3 lethal 8.0e-5 mol/L No direct source
m_NH3,max 0.08 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 3.1e-7 mol/L No direct source
K_H2S,tox 1.0e-6 mol/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.015/24 /h No direct source
Feces C:N 10.0 mol / mol No direct source
Feces → suspended fraction 0.15 fraction Benthic
Death → suspended fraction 0.10 fraction No direct source
Starvation m_max 0.05/24 /h No direct source
Crowding m_max 0.10/24 /h No direct source
K_crowding (benthic areal) 4.0e-7 mol N / cm² Benthic areal density half-sat
m_total,max 0.50 /h Cap

Reproduction & resting eggs

Symbol Value Units Source / Rationale
Dormant food-limit threshold 0.30 fraction No direct source
Dormant density threshold 1.5e-3 mol N/L No direct source
Dormant T-drop threshold 8.0 °C No direct source
Dormant short-day threshold 12.0 h No direct source
Dormant max fraction 0.50 fraction No direct source
Dormant base fraction 0.05 fraction Higher base — textbook resting-egg producer (Brendonck & De Meester 2003)
T_hatch (min) 10.0 °C No direct source
K_food (hatch) 2.0e-5 mol C/L No direct source
k_hatch,max 1.4e-4 /h No direct source
Dormant mortality 7.0e-8 /h Half Daphnia — exceptionally durable (Brendonck & De Meester 2003)
Initial / introduction dormant fraction 0.0 / 0.0 fraction

Ciliate

Bacterivorous protist with strong temperature dependence and density-dependent giant-virus lysis; routes a larger lysate share to DOM than larger consumers.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.005 cm ~50 µm
Imax 0.08 /h ~1.9/day; Fenchel 1987 mixed-community ingestion 2–20× body C/day
K_C 1.2e-5 mol C/L ~0.15 mg C/L; higher K than HNF for trophic-cascade realism (Fenchel 1987)
SDA fraction 0.15 fraction No direct source
Nocturnal feeding fraction 0.95 fraction Active day and night
RQ 0.90 mol CO₂ / mol O₂ Protist mixed substrates

Stoichiometry

Symbol Value Units Source / Rationale
C:N 4.5 mol / mol High protein
N:P 16.0 mol / mol Redfield

Respiration

Symbol Value Units Source / Rationale
R_maint 0.004 /h Higher than copepods
K_O2 (respiration) 2.0e-5 mol/L ~0.64 mg/L (Fenchel & Finlay 1995)

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 4.0e-5 mol/L ~1.3 mg/L
O2 stress 4.0e-5 mol/L ~1.3 mg/L
O2 lethal 1.0e-5 mol/L ~0.3 mg/L
m_hypoxia,max 0.10 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.5 / 2.2 / 1.8 Strong T dependence for protists (Weisse 2002)
T_stress (low / high) 8.0 / 30.0 °C No direct source
T_lethal (low / high) 2.0 / 38.0 °C No direct source
m_thermal,max 0.05 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater stenohaline
σ_S 3.0 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 10.0 PSU No direct source
m_salinity,max 0.30 /h No direct source
Osmoregulation cost 0.005 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.8 / 9.0 No direct source
pH lethal (low / high) 5.0 / 10.0 No direct source
m_pH,max 0.06 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 8.0e-6 mol/L ~0.11 mg/L NH3-N
NH3 lethal 1.5e-4 mol/L ~2.1 mg/L NH3-N
m_NH3,max 0.10 /h No direct source

Viral lysis

Symbol Value Units Source / Rationale
m_viral,max 0.02 /h Density-dependent giant-virus lysis (Montagnes et al. 2008)
K_viral 5.0e-6 mol C/L No direct source

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.04/24 /h ~4%/day
Feces C:N 8.0 mol / mol C-rich
Feces → suspended fraction 0.80 fraction Small fecal pellets
Death → suspended fraction 0.70 fraction Small cells lyse
Death → DOM fraction 0.25 fraction Lower than HNF — denser pellicle (Nagata 2000)
Starvation m_max 0.20/24 /h ~20%/day; active ciliates die 3–7 d w/o prey (Fenchel 1987; Weisse 2002)
m_total,max 0.60 /h Cap

Nanoflagellate

Smallest heterotrophic flagellate — primary bacterivore in the microbial loop, fragile, strong T dependence, lyses to DOM at death.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.0005 cm ~5 µm
Imax 0.10 /h ~2.4/day; 10–100 bacteria/cell/h (Fenchel 1982)
K_C 8.0e-6 mol C/L ~0.10 mg C/L; mixed-community (Fenchel 1982)
SDA fraction 0.15 fraction No direct source
Nocturnal feeding fraction 0.95 fraction Active day and night
RQ 0.90 mol CO₂ / mol O₂ Protist mixed substrates

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Caron et al. 1990
N:P 16.0 mol / mol Redfield

Respiration

Symbol Value Units Source / Rationale
R_maint 0.005 /h Allometric (Fenchel & Finlay 1983)
K_O2 (respiration) 2.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 4.0e-5 mol/L ~1.3 mg/L
O2 stress 4.0e-5 mol/L ~1.3 mg/L
O2 lethal 1.0e-5 mol/L ~0.3 mg/L
m_hypoxia,max 0.10 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.5 / 2.2 / 1.8 Strong T dependence (Weisse 2002)
T_stress (low / high) 8.0 / 30.0 °C No direct source
T_lethal (low / high) 2.0 / 38.0 °C No direct source
m_thermal,max 0.05 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 3.0 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 10.0 PSU No direct source
m_salinity,max 0.30 /h No direct source
Osmoregulation cost 0.005 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.8 / 9.0 No direct source
pH lethal (low / high) 5.0 / 10.0 No direct source
m_pH,max 0.06 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 8.0e-6 mol/L ~0.11 mg/L NH3-N
NH3 lethal 1.5e-4 mol/L ~2.1 mg/L NH3-N
m_NH3,max 0.10 /h No direct source

Viral lysis

Symbol Value Units Source / Rationale
m_viral,max 0.03 /h NCLDV / giant-virus lysis, 10–60% HNF mortality (Massana et al. 2007; Montagnes et al. 2008)
K_viral 5.0e-6 mol C/L No direct source

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.05/24 /h ~5%/day, higher turnover than ciliate
Feces C:N 8.0 mol / mol No direct source
Feces → suspended fraction 0.90 fraction Tiny pellets
Death → suspended fraction 0.85 fraction Naked flagellates lyse
Death → DOM fraction 0.30 fraction No cell wall (Nagata 2000)
Starvation m_max 0.30/24 /h 20–50%/day starvation (Zubkov & Sleigh 1995; Weisse 2002)
m_total,max 0.60 /h Cap

Amphipod / Scuds

First detrital shredder — fragments settled detritus mechanically (parallel flux on top of biological feeding) at a calibrated 1/3 share of the amphipod–detritus interaction (Wallace & Webster 1996).

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.5 cm ~5 mm adult
Imax 0.010 /h ~0.24/day gross; deposit feeder processes large detritus quantities, matched to the comparable detritivores (snail 0.012, MTS 0.010). Restores literature population growth r ≈ 0.05–0.1/day (Othman & Pascoe 2001; Panov & McQueen 1998). Was 0.005 — below maintenance+mortality even at food saturation (cycling-matrix F10-2)
K_C 1.5e-5 mol C/L ~0.18 mg C/L; benthic forager
SDA fraction 0.10 fraction Low SDA on detrital diet
Nocturnal feeding fraction 1.10 fraction Nocturnal — more active at night
Water-change removal fraction 0.0 fraction Fully benthic — hides in litter

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Protein-rich crustacean
N:P 22.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0006 /h Moderate basal metabolism
K_O2 (respiration) 3.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 6.0e-5 mol/L ~1.9 mg/L
O2 stress 9.4e-5 mol/L 3.0 mg/L
O2 lethal 3.13e-5 mol/L 1.0 mg/L
m_hypoxia,max 0.03 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.2 / 2.2 / 1.7 No direct source
T_stress (low / high) 7.0 / 29.0 °C Derived — hand-authored published range 10.0–26.0 °C ±3.0. Cool-water Nearctic taxon; the wiki carries no amphipod page, so the range is the cited record in stocking/data/hand_authored_water.json
T_lethal (low / high) 2.0 / 32.0 °C Derived — stress −5.0 / +3.0. Overwinters under ice. The high bound lands exactly on Decapod's 32.0 and is inherited
m_thermal,max 0.025 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.2 PSU Freshwater; some brackish tolerance
σ_S 2.5 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 8.0 PSU No direct source
m_salinity,max 0.12 /h No direct source
Osmoregulation cost 0.003 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 Derived — hand-authored published range 6.5–8.5 ±0.5. Among the more acid-sensitive freshwater crustaceans: cuticular Ca uptake fails at low pH (France & Stokes 1987)
pH lethal (low / high) 5.0 / 9.8 Derived — stress −1.0 / +0.8
m_pH,max 0.04 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 5.0e-6 mol/L ~0.07 mg N/L; 96-h LC50 (Borgmann 1994)
NH3 lethal 1.5e-4 mol/L No direct source
m_NH3,max 0.06 /h No direct source
NO2 stress 3.6e-5 mol/L ~0.5 mg N/L; lower "safe" bound (Lewis & Morris 1986)
NO2 lethal 5.7e-4 mol/L ~8.0 mg N/L; near M. rosenbergii larvae LC50
m_NO2,max 0.021 /h LC50-anchored: ramp passes through ln(2)/96h at the ~3.14 mg-N/L LC50 (matches corrected Neocaridina kernel). Was 0.05 — unsourced over-kill copied from the pre-fix shrimp

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 1.5e-7 mol/L 96-h LC50 ~25–35 µg Cu/L; EPA reference organism (Borgmann et al. 1991)
K_H2S,tox 2.5e-7 mol/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 2.0e-4 /h ~0.5%/day; ~1-yr lifespan
Feces C:N 14.0 mol / mol High-C detrital diet
Feces → suspended fraction 0.10 fraction 90% settles (benthic)
Death → suspended fraction 0.05 fraction Carcasses settle
Starvation m_max 0.025/24 /h ~10 d tolerance (lipid reserves)
Crowding mortality 0 (disabled) /h Density self-limits via feeding interference, not death — unified with snail/shrimp (Brown et al. 1994). _calc_density_dependent_mortality → 0
K_crowd-feeding (areal) 2.0e-6 mol N / cm² Half-feeding density; between snail (2.3e-7) and shrimp (4.0e-6); Hyalella pack densely on litter (~150 ind / 1000 cm²)
Crowd-feeding Hill n 1.5 Interference steepness (matches siblings)
Crowds over full surface True bool Mobile — crawls/swims over litter, plants, hardscape
m_total,max 0.50 /h Cap

Molting & shredding

Symbol Value Units Source / Rationale
Molt rate (ref) 1/(14·24) /h ~14-day molt at 22°C (Othman & Pascoe 2001)
T_ref (molt) 22.0 °C Othman & Pascoe 2001
Q10,molt 2.0 No direct source
Molt Ca per C 0.003 mol Ca / mol C / molt Thin cuticle vs shrimp/crayfish
Molt mortality 0.004 /h Post-molt soft-shell vulnerability
Molt Ca stress threshold 2.5e-4 mol/L ~1.4 °dGH; Hyalella need >0.5 mg Ca/L
Molt Ca-stress rate factor 0.5 × Molt-rate halving under Ca stress
Molt Ca-stress mortality factor 2.0 × Post-molt mortality doubling under Ca stress
Shell Ca per body C 0.003 mol Ca / mol C Lightly calcified cuticle
Shredding rate 0.0056 /h per mol C Calibrated so ~1/3 of amphipod-detritus interaction is shredding: 0.0056/(0.0056+Imax 0.010) ≈ 0.36 (Wallace & Webster 1996; Graça 2001). Tracks Imax to preserve the ratio
K_shred (settled C) 1.5e-5 mol C/L Half-sat on settled-detritus availability

Bladder snail

Hardy radula-grazing gastropod with shell Ca demand and Physella-style tolerance to poor water quality (notably high NO₂).

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.5 cm ~5 mm adult
Imax 0.012 /h ~0.29/day max; gen time 2–3 wks (Dillon 2000)
K_C 1.2e-5 mol C/L ~0.14 mg C/L; raised vs 5e-6 to avoid over-grazing periphyton (Feminella & Hawkins 1995)
SDA fraction 0.15 fraction Lower than copepods — simpler digestion
Nocturnal feeding fraction 0.9 fraction Snails more active at night
Water-change removal fraction 0.0 fraction Benthic crawler

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol Protein-rich mollusc body
N:P 20.0 mol / mol P-rich due to shell

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0003 /h Low ectotherm basal
K_O2 (respiration) 2.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 2.5e-5 mol/L Lower than copepods — more tolerant
O2 stress 4.69e-5 mol/L 1.5 mg/L
O2 lethal 9.38e-6 mol/L 0.3 mg/L
m_hypoxia,max 0.03 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.2 / 2.2 / 1.6 No direct source
T_stress (low / high) 15.0 / 28.0 °C DerivedPhysa acuta published range 18.0–25.0 °C ±3.0 (Aquarium Wiki). Was 5.0 / 30.0, hand-set as "a pest snail survives anything"; the largest single change in the §I3 regeneration
T_lethal (low / high) 10.0 / 31.0 °C Derived — stress −5.0 / +3.0
m_thermal,max 0.02 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.3 PSU Freshwater
σ_S 3.0 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 8.0 PSU No direct source
m_salinity,max 0.20 /h No direct source
Osmoregulation cost 0.003 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.6 / 9.1 Derived — published range 7.2–8.5 ±0.5. Corroborates the hand-set 6.5 / 9.0: shells dissolve below ~6.5 (Dillon 2000), thrives in alkaline water (Byers & Herbst 2002)
pH lethal (low / high) 5.6 / 9.9 Derived — stress −1.0 / +0.8
m_pH,max 0.05 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 5.0e-6 mol/L No direct source
NH3 lethal 1.0e-4 mol/L No direct source
m_NH3,max 0.06 /h No direct source
NO2 stress 1.4e-4 mol/L 2 mg N/L — Physella notoriously tolerant of poor water
NO2 lethal 1.4e-3 mol/L 20 mg N/L
m_NO2,max 0.04 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 4.7e-7 mol/L ~30 µg Cu/L; EPA mollusc acute AWQC 20–50 µg/L
K_H2S,tox 2.0e-6 mol/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.0002 /h ~0.48%/day; hardy
Feces C:N 12.0 mol / mol No direct source
Feces → suspended fraction 0.10 fraction 90% settles
Death → suspended fraction 0.05 fraction Shells + tissue settle
Starvation m_max 0.03/24 /h Can weather starvation
K_crowding,feeding (areal) 2.3e-7 mol N / cm² Brown, Carman & Inchausty (1994, Oecologia 99:158) — per-capita grazing halves above ~4 Physella/25 cm²; 4×0.02 mg N / 25 cm². Self-limitation acts on FEEDING (interference), not survival → boom-then-plateau
Crowding feeding Hill n 1.5 Interference steepness (calibrated)
Crowds over full surface true Pulmonate crawls glass/hardscape/plants, not just floor
Density-dependent mortality disabled Replaced by feeding interference above (was 0.08/24 /h crowding-death, K 1.0e-6 — killed snails at hobby density instead of plateauing)
m_total,max 0.50 /h Cap

Detrital shredding / facilitation

Symbol Value Units Source / Rationale
Shred rate 0.0010 /h per mol snail C Settled→suspended detritus fragmentation; subsidises collector-grazers (shrimp). Shredder→collector facilitation (Ecol. Res. 2001); cross-species coprophagy of snail-conditioned egesta (Aquat. Sci. 2022). Gentler than amphipod (0.0028) — snails rasp, not tear
K_shred (settled det.) 1.5e-5 mol C/L Half-sat on settled-detritus availability (matches amphipod)

Shell / Ca stoichiometry

Symbol Value Units Source / Rationale
Shell TA per C 0.05 mol TA / mol C CaCO₃ stoichiometry: −2 TA per mol CaCO₃
Shell Ca per C 0.025 mol Ca / mol C −1 Ca²⁺ per mol CaCO₃ = shell_TA/2
Shell Ca stress threshold 5.0e-4 mol/L ~2.8 °dGH soft-water threshold
Shell low-Ca growth factor 0.5 × Growth halved under soft-water stress
Shell Ca per body C (on death) 0.025 mol Ca / mol C Ca routed to CACO3_SUBSTRATE on death

Ramshorn snail

Larger planorbid surface-grazer in the bladder-snail mould, set apart by haemoglobin-borne hypoxia tolerance (the "last snail standing" in low-O₂ water) and a bigger, more Ca-demanding flat planispiral shell. Reuses the Physa surface-crawler kinematics — feeding-interference crowding, detrital shredding, shell stoichiometry — with calibrated offsets on the three real distinctions.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 1.0 cm ~1 cm population mean (adult shell ~1–2 cm); ~2× Physa
Imax 0.011 /h Between Physa (0.012) and MTS (0.010) — larger, methodical, but a strong scraper
K_C 1.3e-5 mol C/L Between Physa (1.2e-5) and MTS (1.5e-5); lower mass-specific encounter than Physa
SDA fraction 0.15 fraction Lower than copepods — simpler digestion
Nocturnal feeding fraction 0.85 fraction Active day and night — grazes openly in daylight (Physa 0.9)
Water-change removal fraction 0.0 fraction Benthic crawler

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol Protein-rich mollusc body
N:P 20.0 mol / mol P-rich due to shell

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0003 /h Low ectotherm basal
K_O2 (respiration) 1.2e-5 mol/L Tightest O2 affinity of the snails — haemoglobin

Hypoxia — haemoglobin tolerance

Symbol Value Units Source / Rationale
K_O2 (activity) 1.2e-5 mol/L Best O2 affinity of the snails (Physa 2.5e-5, MTS 1.5e-5)
O2 stress 2.5e-5 mol/L ~0.8 mg/L (Physa 1.5, MTS 1.0 mg/L) — planorbid haemoglobin (Jones 1961)
O2 lethal 3.1e-6 mol/L ~0.1 mg/L (Physa 0.3, MTS 0.15 mg/L)
m_hypoxia,max 0.02 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.2 / 2.2 / 1.6 No direct source
T_stress (low / high) 14.8 / 33.0 °C Derived — published range 17.8–30.0 °C ±3.0. The page resolves to Gyraulus sp., a planorbid but not this class's Planorbella duryi, so the band is a family-level claim about a ramshorn
T_lethal (low / high) 9.8 / 36.0 °C Derived — stress −5.0 / +3.0
m_thermal,max 0.02 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.3 PSU Freshwater
σ_S 3.0 PSU No direct source
S_stress (low / high) 0.0 / 4.0 PSU No direct source
S_lethal (low / high) 0.0 / 8.0 PSU No direct source
m_salinity,max 0.20 /h No direct source
Osmoregulation cost 0.003 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.25 / 8.75 Derived — published range 7.0–8.0, under MIN_PH_WIDTH (1.5) so widened about its midpoint to 6.75–8.25 first, then ±0.5. Narrower than the hand-set 6.5 / 9.0: the published range declines to back "fine at pH 9"
pH lethal (low / high) 5.25 / 9.55 Derived — stress −1.0 / +0.8
m_pH,max 0.05 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 5.0e-6 mol/L No direct source
NH3 lethal 1.0e-4 mol/L No direct source
m_NH3,max 0.06 /h No direct source
NO2 stress 1.4e-4 mol/L 2 mg N/L — hardy "pest" snail like Physa
NO2 lethal 1.4e-3 mol/L 20 mg N/L
m_NO2,max 0.04 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 4.7e-7 mol/L ~30 µg Cu/L; same gastropod-class sensitivity as Physa/MTS
K_H2S,tox 2.0e-6 mol/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.00015 /h ~0.36%/day; hardy (between Physa 0.0002 and MTS 0.00012)
Feces C:N 12.0 mol / mol No direct source
Feces → suspended fraction 0.10 fraction 90% settles
Death → suspended fraction 0.05 fraction Shells + tissue settle
Starvation m_max 0.025/24 /h Larger reserves than Physa — weathers a fast slightly better
K_crowding,feeding (areal) 8.0e-7 mol N / cm² Larger snail: feeding interference at ~2 snails/25 cm² (vs Physa's ~4), scaled by the larger per-individual mass (~0.15 mg N) → higher areal-biomass threshold. Self-limitation acts on FEEDING → boom-then-plateau
Crowding feeding Hill n 1.5 Interference steepness (matches Physa)
Crowds over full surface true Pulmonate crawls glass/hardscape/plants, not just floor
Density-dependent mortality disabled Replaced by feeding interference above (matches Physa)
m_total,max 0.50 /h Cap

Detrital shredding / facilitation

Symbol Value Units Source / Rationale
Shred rate 0.0012 /h per mol snail C Settled→suspended detritus fragmentation subsidising collector-grazers. Slightly above Physa (0.0010) — bigger radula — but gentler than the amphipod (0.0028)
K_shred (settled det.) 1.5e-5 mol C/L Half-sat on settled-detritus availability (matches Physa/amphipod)

Shell / Ca stoichiometry

Symbol Value Units Source / Rationale
Shell TA per C 0.06 mol TA / mol C Larger, flatter planispiral shell → more CaCO₃ per body C than Physa (0.05)
Shell Ca per C 0.030 mol Ca / mol C −1 Ca²⁺ per mol CaCO₃ = shell_TA/2
Shell Ca stress threshold 6.0e-4 mol/L ~3.4 °dGH — more Ca-hungry than Physa (5.0e-4 / 2.8 °dGH); planorbid shells pit in soft water
Shell low-Ca growth factor 0.5 × Growth halved under soft-water stress
Shell Ca per body C (on death) 0.030 mol Ca / mol C Ca routed to CACO3_SUBSTRATE on death

Malaysian trumpet snail

Burrowing tropical operculate snail — drives the first bioturbation kernel; tighter O2 affinity and broader NO₂ tolerance than Physella.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 1.5 cm Population mean (juveniles + adult ~2–3 cm)
Imax 0.010 /h Slightly slower than Physa per unit C
K_C 1.5e-5 mol C/L Raised vs Physa — buried particle encounter
SDA fraction 0.15 fraction No direct source
Nocturnal feeding fraction 0.95 fraction Markedly nocturnal — surfaces at night
Water-change removal fraction 0.0 fraction Burrower

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol No direct source
N:P 20.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0003 /h No direct source
K_O2 (respiration) 1.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 1.5e-5 mol/L Tighter than Physa — efficient at low O2
O2 stress 3.13e-5 mol/L 1.0 mg/L
O2 lethal 4.69e-6 mol/L 0.15 mg/L
m_hypoxia,max 0.02 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.2 / 2.2 / 1.6 No direct source
T_stress (low / high) 15.0 / 33.0 °C Derived — published range 18.0–30.0 °C ±3.0. Tropical / subtropical native. The closest agreement of the four regenerated snails — every bound moves ≤3 °C
T_lethal (low / high) 10.0 / 36.0 °C Derived — stress −5.0 / +3.0
m_thermal,max 0.02 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Tolerates up to ~15 PSU — invasive in brackish
σ_S 6.0 PSU No direct source
S_stress (low / high) 0.0 / 12.0 PSU No direct source
S_lethal (low / high) 0.0 / 18.0 PSU No direct source
m_salinity,max 0.10 /h No direct source
Osmoregulation cost 0.002 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.25 / 8.75 Derived — published range 7.0–8.0, widened to MIN_PH_WIDTH first, then ±0.5. Native to calcareous tropical streams, but the published range does not carry the hand-set 9.5 high-pH tolerance
pH lethal (low / high) 5.25 / 9.55 Derived — stress −1.0 / +0.8
m_pH,max 0.04 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 5.0e-6 mol/L No direct source
NH3 lethal 1.5e-4 mol/L No direct source
m_NH3,max 0.05 /h No direct source
NO2 stress 2.0e-4 mol/L MTS notoriously survive uncycled tanks
NO2 lethal 2.0e-3 mol/L No direct source
m_NO2,max 0.03 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 4.7e-7 mol/L Same gastropod-class as Physa
K_H2S,tox 2.0e-6 mol/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.00012 /h ~0.29%/day; hardier than Physa
Feces C:N 12.0 mol / mol No direct source
Feces → suspended fraction 0.05 fraction Deep deposition
Death → suspended fraction 0.02 fraction Sinks immediately
Starvation m_max 0.02/24 /h Weathers long fasts
Crowding m_max 0.10/24 /h No direct source
K_crowding (benthic areal) 3.0e-6 mol N / cm² Higher than Physa — 3D substrate use
Bare-bottom crowding multiplier 5.0 × Amplified crowding on bare glass / ceramic — obligate burrower
m_total,max 0.50 /h Cap

Shell / Ca stoichiometry & bioturbation

Symbol Value Units Source / Rationale
Shell TA per C 0.06 mol TA / mol C Thicker shell than Physa
Shell Ca per C 0.030 mol Ca / mol C TA/2
Shell Ca stress threshold 5.0e-4 mol/L ~2.8 °dGH
Shell low-Ca growth factor 0.5 × No direct source
Shell Ca per body C (on death) 0.030 mol Ca / mol C Ca → CACO3_SUBSTRATE on death
K_bioturbation 5.0e-7 mol C / cm² Half-sat for bioturbation intensity tanh; tuned to 5→50 MTS arc

Neocaridina / Cherry shrimp

Detritus-grazing tropical shrimp with rich reproduction kinetics — Erlang-3 brood pipeline, NO₃-suppressed breeding, and a Ca-dependent molting cycle.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 2.5 cm ~2.5 cm adult
Imax 0.008 /h ~0.19/day; gen time ~3–4 wk (Wester 2013; Pantaleão et al. 2015)
K_C 1.0e-5 mol C/L ~0.12 mg C/L. No published functional-response half-sat for N. davidi. Lowered from 2.0e-5: a specialised biofilm scraper should not be a worse low-food feeder than the smaller co-occurring snail (K_C 1.2e-5). Viau et al. (2020, Aquac. Res.) — biofilm as SOLE diet sustains full somatic growth + reproduction → efficient feeding at modest periphyton. Calibrated to a biofilm specialist
biofilm_graze_penetration 0.35 fraction Soft-appendage (brush-tipped) grazer, not a hard radula/mandible scraper — the consumer-side EPS-penetration trait (Species base default 1.0 = full radula reference; only shrimp lowered). Raises the effective M=1 biofilm-shelter cap this grazer faces via prot_eff = prot + (1-prot)(1-0.35): a fully mature benthic-green film (cap 0.40) becomes ~0.79 sheltered from shrimp vs 0.40 from a snail radula, so shrimp keep ~21% access to the cemented mature layer (they nibble, can't crop to zero) while young/loose film stays fully grazeable. Atyid shrimp crop soft/filamentous periphyton >70% in 30 d (Zhang et al. 2019) but cannot rasp the adnate understory reachable only by radula scrapers (Steinman 1996; Dillon 2000); the green-spot-algae "shrimp pick but can't control it" rule (Aquarium Co-Op). See species/access.py::_effective_protection_cap
SDA fraction 0.12 fraction Crustacean digestion
Nocturnal feeding fraction 0.85 fraction Slightly more active at night
Water-change removal fraction 0.0 fraction Hides in substrate / plants

Stoichiometry

Symbol Value Units Source / Rationale
C:N 4.5 mol / mol Protein-rich crustacean
N:P 20.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0008 /h Moderate ectotherm basal
K_O2 (respiration) 2.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 2.0e-5 mol/L ~0.64 mg/L
O2 stress 3.13e-5 mol/L 1.0 mg/L
O2 lethal 6.25e-6 mol/L 0.2 mg/L
m_hypoxia,max 0.025 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.1 / 2.1 / 1.6 No direct source
T_stress (low / high) 19.0 / 31.0 °C DerivedNeocaridina heteropoda published range 22.0–28.0 °C ±3.0. The one invert the rule makes stricter on the cold side (was 15.0): the shrimp had been hand-written narrower than published because "shrimp are sensitive", and the rule widens instead
T_lethal (low / high) 14.0 / 34.0 °C Derived — stress −5.0 / +3.0. Moves off Decapod's 32.0 default; pinning it back would leave a 1 °C stress→lethal gap and turn the upper ramp into a cliff
m_thermal,max 0.02 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.2 PSU Pure freshwater
σ_S 2.0 PSU No direct source
S_stress (low / high) 0.0 / 3.0 PSU No direct source
S_lethal (low / high) 0.0 / 6.0 PSU No direct source
m_salinity,max 0.15 /h No direct source
Osmoregulation cost 0.003 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.9 / 8.9 Derived — published range 6.4–8.4 ±0.5. Every bound within 0.6 of the hand-set values, so range and calibration agree about this animal
pH lethal (low / high) 4.9 / 9.7 Derived — stress −1.0 / +0.8
m_pH,max 0.04 /h No direct source

NH₃ / NO₂ toxicity

Symbol Value Units Source / Rationale
NH3 stress 4.0e-6 mol/L No direct source
NH3 lethal 1.0e-4 mol/L No direct source
m_NH3,max 0.06 /h No direct source
NO2 stress 3.6e-5 mol/L ~0.5 mg N/L; sensitive onset / lower "safe" bound (Lewis & Morris 1986); haemocyanin disruption
NO2 lethal 5.7e-4 mol/L ~8 mg N/L; near M. rosenbergii larvae 96 h LC50 8.6 (Armstrong et al. 1976)
m_NO2,max 0.021 /h Anchored so the linear ramp passes through ln(2)/96h = 0.0072/h at the M. malcolmsonii 96 h LC50 of 3.14 mg NO2-N/L. Was 0.05 (unsourced): gave ~0.029/h (70 %/day) at that LC50 (~4× too steep), wiping shrimp out at the literature-"safe" 1–1.5 mg-N/L band

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 1.9e-7 mol/L ~12 µg Cu/L; 96-h LC50 ~15 µg/L (Lauer et al. 2012)
K_H2S,tox 3.0e-7 mol/L No direct source

Allelochemical sensitivity

Symbol Value Units Source / Rationale
K_allelo,cyanotoxin 2.0e-5 mol C/L Larger body dilutes toxin (Lürling 2003)
K_allelo,cyanotoxin,feeding 8.0e-6 mol C/L No direct source

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 1.4e-4 /h ~0.33%/day; ~1.5-yr lifespan
Feces C:N 12.0 mol / mol No direct source
Feces → suspended fraction 0.05 fraction 95% settles
Death → suspended fraction 0.05 fraction Exuvia + carcass settle
Starvation m_max 0.03/24 /h ~1 wk tolerance
K_crowding,feeding (areal) 4.0e-6 mol N / cm² Half-feeding density over the full crawlable surface. No published carrying-capacity constant for N. davidi; calibrated to a hobby-realistic plateau (~2–5/L). Self-limitation acts on FEEDING (Brown et al. 1994 mechanism), not survival
Crowding feeding Hill n 1.5 Interference steepness (calibrated)
Crowds over full surface true Shrimp crawl glass/hardscape/plants, not just floor
Density-dependent mortality disabled Replaced by feeding interference above. The old areal crowding-DEATH kernel (0.05/24 /h, K 1.0e-6, benthic-FLOOR only) killed adults at normal hobby stocking — e.g. 8 shrimp in a 600 cm² footprint sat at the half-saturation density — driving spurious extinction
m_total,max 0.50 /h Cap

Reproduction (Erlang-3 brood pipeline)

Symbol Value Units Source / Rationale
t_mature 92.0 days Sexual maturity 4–5 mo (Pantaleão et al. 2015; Wester 2013); erlang3 mode separates 28-d brood
Initial / introduction adult fraction 1.0 / 1.0 fraction Hobbyist purchases adults
Reproduction mode "erlang3" str Gamma(3) smoothed delay through 3-cohort brood pipeline
τ_brood 28.0 days Mean berried period (Wester 2013)
Brood cap fraction 0.50 fraction Cap on berried biomass per adult
NO3 repro onset 3.23e-4 mol N/L 20 ppm — reproduction suppression begins
NO3 repro zero 6.45e-4 mol N/L 40 ppm — full suppression
pH repro (low / high) 6.5 / 8.8 Below / above → reduced breeding (Wester 2013, hobby consensus 6.5–8.5)
T repro (low / high) 18.0 / 27.0 °C Outside → reduced breeding
NH3 repro threshold 3.0e-6 mol/L ~0.05 ppm NH3 → breeding stops
Repro maturity threshold (M) 0.30 fraction Biofilm-maturity threshold for full reproduction
Repro maturity Hill exponent 2.0 Hill exponent on M ramp

Molting & shell

Symbol Value Units Source / Rationale
Molt rate (ref) 1/(21·24) /h One molt per 21 d at T_ref,molt
T_ref (molt) 22.0 °C No direct source
Q10,molt 2.0 No direct source
Molt Ca per C 0.010 mol Ca / mol C / molt No direct source
Molt mortality 0.005 /h Soft-shell vulnerability
Molt Ca stress threshold 3.6e-4 mol/L ~2 °dGH
Molt Ca-stress rate factor 0.5 × No direct source
Molt Ca-stress mortality factor 2.0 × No direct source
Shell Ca per body C (on death) 0.010 mol Ca / mol C Ca → CACO3_SUBSTRATE on death

The invertebrate roster — GENERATED (one species per planner invertebrate)

The five sections above are hand-written and stay that way. Beside them the engine now carries 35 generated invertebrates, one per planner Chart cell that the water ladder can rate, emitted by stocking.invert_roster from a single uniform rule (internal_docs/planning/invert_roster_expansion.md §I4). As with the fish, 35 species cannot each get a hand section, so the live per-species numbers and their provenance live in a separate generated table, parameter_reference_generated_inverts.md.

The five hand-written invertebrates are NOT generated, and that is the one place this roster departs from the fish precedent. Their thermal and pH envelopes were regenerated in §I3 (identity pinned, values free), but the other ~23 numbers on each leaf are hand-calibrated against species-specific literature no rule can reach — the ramshorn's haemoglobin O₂ affinity (Jones 1961), the cherry shrimp's LC50-anchored nitrite band, the MTS burrowing-establishment override, the scud's shredding rate. A fish is the ~18 numbers its rule derives, so the five hand fish had nothing to lose; a snail is not. The five stay hand-written, their SPECIES_TYPEs are reserved against collision, and they serve as the roster's accuracy-validation set — every allometry below is scored against them by python -m stocking.invert_roster report.

Four allometries, each fitted on those five. None is a measurement; each is reported with its residuals.

The mass law is no longer one of them. It was individual_N_mg = 0.139·L³ over all five, and its real defect was not the coefficient but L: the wiki's maximum length, under whichever of five incomparable dimensions that page recorded — a snail's shell height, a shrimp's rostrum-to-telson total, a crab's carapace width, and for Procambarus clarkii a 12-inch claw span. Cubed, the crayfish alone was 21× out and a 7.6 cm ghost shrimp weighed 2.8 g wet. 43 of the 44 generated animals sat outside the 0.5–2.5 cm range the donors covered. It now lives in stocking/invert_mass.py, which normalises the length first and then applies K_plan · Φ(shape) · L³; see the table below and that module's docstring for the two routes that were measured and rejected.

And normalising a wrong number still gives a wrong number. Held against published sources, the wiki's invertebrate lengths run 0.69× to 2.02× of the real animal, in both directions — a range that is an 8× spread in mass. Sixteen binomials were re-sourced against the same bar water_corrections.json uses (two independent references naming the binomial, in the body plan's own convention, agreeing against the page). Eight were overruled and eight held, which is the honest headline: the wiki is not systematically wrong about size, it is unreliable about size, and the two are different problems. The records, their citations and the disagreements they rest on are in stocking/data/size_corrections.json; read its _readme before adding one.

Two findings from that pass are worth stating here rather than only in the file:

  • The chela factor is a species calibration wearing a family's name. 0.55 was read off Procambarus clarkii, whose page really does quote a 12-inch claw span. Cambarellus patzcuarensis is the same family and its page quotes 1.5–2 inches of body — so the family rule turned a 4 cm dwarf crayfish into a 2.4 cm one, a 5.4× mass error in the opposite direction to the one the factor was written to fix. Corrections carry a chela_inclusive flag that bypasses it per record.
  • The mass law itself came out well. Atya gabonensis has no calibration anchor near it in body plan or size, and at the wiki's (upheld) 12.7 cm the law puts it at 24.5 g wet against an independently measured population mean of 30.3 ± 18.7 g. 0.81× on an extrapolation three plans out is better than the law claims for itself.

Five Chart cells cannot be corrected and are not — fairy shrimp, purple zebra shrimp, ghost dwarf crab, rabbit snail, triangle rabbit snail carry no binomial, so there is nothing to look up and any number entered would be a guess wearing a citation. They stay on their group median. "Every invertebrate" tops out at 39.

Symbol Value Units Source / Rationale
Chela-inclusive length factor 0.55 Cambaridae / Parastacidae only. The hobby quotes a crayfish claw-tip to tail; the mass law wants body length. Keyed on family, not Chart group — the Chart files the Amano shrimp (Caridina multidentata, an atyid measured the ordinary way) under "Crayfish", and a group-keyed rule would shrink a shrimp by 45% for its filing cabinet. 🔒 It is nonetheless a species calibration: it is right for Procambarus and wrong for Cambarellus, whose page is already a body length. A size_corrections.json record can bypass it (chela_inclusive: false), and all three crayfish records do. The footprint still divides by it, because 0.55 is wrong as a reading of a page and right as geometry — both genera really do span ~1.6–1.8× their body, which is also what invert_shape's Cambaridae chela of 1.05 gives
Mass constant K — gastropod / bivalve 0.1287 mg N / cm³ individual_N_mg = K·Φ·L³ with Φ = 1: no per-family shape term for a shell. Fitted on the three pulmonate/thiarid anchors, log-RMSE 0.228 over all four (was 0.505). 🔒 Φ = 1 is a recorded finding, not an oversight — the Raup (1966) coiling route was built and rejected at a 2.7× spread (K solving to 4.57 / 1.05 / 2.08), because invert_shape's W/T/whorls were authored to draw a silhouette rather than measure one. The bivalve borrows the gastropod constant; it has no anchor
Mass constant K — decapod / brachyuran 8.1914 mg N / cm³ Same law, with Φ derived from the plan's own proportions (abdomen_fraction, carapace_depth, chela; carapace aspect and leg span for a crab). One constant cannot span an atyid and a crayfish carrying claws longer than its carapace — without Φ an 11.9 cm P. clarkii came out at 5.8 g wet against a real ~35 g. Φ carries the crayfish/shrimp volume ratio to 4.3× against the ~6× the gap wants. 🔒 Fitted on one anchor (the cherry shrimp), so its residual is zero by construction and is not evidence; the crab borrows it
Plausible adult length 16 / 20 / 12 / 22 cm Per body plan (gastropod / decapod / brachyuran / bivalve). A guard, not a clamp: emit fails rather than shipping a violation. A clamp would have quietly turned the 12-inch crayfish into a 20 cm one and nobody would have looked again
Ingestion coefficient / exponent 0.0101 / −0.17 /h per mol C, — Imax = 0.0101·L^−0.17. Mass-specific ingestion falls weakly with body length (0.012 at 0.5 cm to 0.008 at 2.5 cm); log-RMSE 0.085, largest residual 14%. The weakness is the point — most of what separates these animals is the diet block, not the kinetics
Crowding coefficient / exponent 3.33e-6 / 0.698 mol N/cm², — K_crowding,feeding = 3.33e-6·(mg N)^0.698. Three points (the two pulmonates and the shrimp; the interference kernel is off on the other two), log-RMSE 0.075. Encodes Brown et al. (1994) read as areal biomass rather than areal count: a big snail interferes at a lower number density and a higher mass per cm²
Base-mortality factor 1.4 base_mort = 1.4/(lifespan_y·8766 h) from the wiki's published lifespan, clamped to 5e-5…1e-3 /h. Above 1 because base mortality is a background hazard on top of the starvation / hypoxia / toxicity kernels rather than the whole hazard
Moult-interval coefficient / exponent 16.66 / 0.252 days, — interval_d = 16.66·L^0.252. Two points, so an interpolation and not a fit — it passes through the scud (0.5 cm / 14 d) and the cherry shrimp (2.5 cm / 21 d) by construction. An 8.8 cm crayfish extrapolates to 29 days, which is short for an adult crayfish and is the first row to revisit if a large crayfish reads wrong
Unionid clearance 26.7 L h⁻¹ (mol C)⁻¹ Kryger & Riisgård (1988) Oecologia 77:34–38 measured Anodonta anatina at ~1 L/h per animal; converted through ~1 g dry tissue ≈ 0.45 g C. This replaces the allometry for the obligate suspension feeder, because Holling-II at low food is clearance (I ≈ (Imax/K_C)·C) and clearance is a published quantity

Seven feeding archetypes. §5.2 named six; the seventh is a split of filter_feeder, made on measurement rather than taste. An 8 cm Atyopsis — the size the roster now ships, the wiki's 10–12 cm having been overruled — would have to clear ~7 L/h to meet maintenance on the 0.05 mg C/L of suspended food a tank actually carries; the published clearance above gives it 1.1 L/h, short by a factor of six. 🔒 The factor is invariant to the animal's size and only the two absolute rates move with it: required and available clearance are both proportional to body carbon. Correcting the bamboo shrimp's length therefore does not reopen the archetype split. So the atyid fan shrimp ship as fan_filterer — suspension foods at top preference plus the scraping route Atya and Atyopsis use when there is no current, which is why keepers are told to target-feed them — and the one bivalve ships as obligate filter_feeder and is food-limited in an aquarium, which is the correct answer for a freshwater mussel.

Archetype Cells K_C (mol C/L) Shred rate (/h per mol C) Notes
omnivore_scavenger 15 1.2e-5 0.0018 The neocaridina surface-access vector
macrophyte_herbivore 7 1.3e-5 0.0011 Rasper base plus living macrophyte tissue
fan_filterer 5 4.0e-6 0.0 Suspension primary, facultative scrape behind it
biofilm_rasper 3 1.3e-5 0.0011 The ramshorn / bladder vector, verbatim
deposit_feeder 3 1.5e-5 0.0 The MTS vector: glass-low, sand-high
snail_predator 1 1.2e-5 0.0 Scavenger base plus a typed prey list
filter_feeder 1 5.0e-5 0.0 Obligate suspension; Imax from the clearance rate above

Per-surface access is a property of the archetype, not the species: the two hand-written raspers were authored independently and converged on the same six numbers, and no single scalar reconciles a deposit feeder with them (best-fit residual 0.43). The four vectors are copied from the hand-written animals rather than invented.

Guild defaults a generated leaf writes down. No existing number moved: the five hand-written animals keep their own values and nothing was hoisted onto Gastropod / Decapod. These are what a generated leaf declares, and each is the mid-point of the engine's calibrated animals in that guild.

Guild Symbol Value Units Source / Rationale
Gastropod O₂ stress / lethal 4.69e-5 / 9.38e-6 mol/L 1.5 / 0.3 mg/L — the bladder snail's envelope, the generic pulmonate. The ramshorn's is a haemoglobin trait with its own paper and is not a guild default
Gastropod K_NH3,tox (lethal) 1.0e-4 mol/L Bladder and ramshorn agree; MTS reads 1.5e-4
Gastropod K_NO2,tox (stress / lethal) 1.4e-4 / 1.4e-3 mol/L ~2.0 / 20 mg NO₂-N/L. The mollusc half of the split §I1 confirmed: snails sit ~4× above the crustaceans
Gastropod Shell TA / Ca per mol C 0.055 / 0.0275 mol/mol The three calibrated snails span 0.05–0.06; Ca = TA/2 is the CaCO₃ stoichiometry
Gastropod Shell Ca stress 5.0e-4 mol/L ~2.8 °dGH
Decapod O₂ stress / lethal 6.25e-5 / 1.56e-5 mol/L 2.0 / 0.5 mg/L — the mid-point of the two calibrated crustaceans (the cherry shrimp gulps at the surface and is unusually tolerant; the scud is not)
Decapod Body C:N / N:P 4.8 / 21.0 mol/mol Mid-point of shrimp and scud
Decapod K_NH3,tox (stress / lethal) 4.5e-6 / 1.2e-4 mol/L Mid-point
Decapod K_Cu,tox / K_H2S,tox 1.7e-7 / 2.7e-7 mol/L Decapod itself carries an empty element_half_sat, so without this every generated shrimp, crayfish and crab would be immune to copper — the one chemical the hobby knows kills invertebrates. The two calibrated leaves agree to within 25% and keep their own values; this is their mid-point, written onto the generated leaf rather than hoisted, so no existing number moves
Decapod Molt Ca per C (shrimp / crayfish & crabs) 0.010 / 0.015 mol Ca / mol C A caridean's cuticle is ~3× as mineralised as a scud's; a crayfish or crab is more heavily calcified again
Decapod Molt Ca stress (shrimp / crayfish & crabs) 3.6e-4 / 5.0e-4 mol/L Heavier calcification means soft-water moult stress begins at a higher hardness

Attribution. The generated bands, sizes and lifespans derive from The Aquarium Wiki (CC BY-SA 3.0); see stocking/data/ATTRIBUTION.md.

Hydra

Sit-and-wait gape-limited cnidarian — first invertebrate predator; lowest Cu tolerance in the codebase; targets juvenile daphnia/copepod.

Ingestion & assimilation

Symbol Value Units Source / Rationale
Body size 0.6 cm Polyp ~5–15 mm extended
Imax 0.025 /h ~0.6/day; population doubling 2–4 d (Bossert & Galliot 2012)
K_C 1.5e-5 mol C/L Encounter-limited, not filter-limited
SDA fraction 0.18 fraction No direct source
Nocturnal feeding fraction 1.0 fraction Tentacles deployed continuously

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol No direct source
N:P 17.0 mol / mol No direct source

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0025 /h No direct source
K_O2 (respiration) 3.0e-5 mol/L No direct source

Hypoxia

Symbol Value Units Source / Rationale
K_O2 (activity) 4.5e-5 mol/L No direct source
O2 stress 5.0e-5 mol/L No direct source
O2 lethal 2.0e-5 mol/L No direct source
m_hypoxia,max 0.07 /h No direct source

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 25 °C T_REF_C
Q10,ingestion / resp / mort 2.2 / 2.0 / 1.8 No direct source
T_stress (low / high) 6.0 / 28.0 °C Brown / common hydra collapse > 28 °C (Slobodkin & Bossert 1991)
T_lethal (low / high) 1.0 / 33.0 °C No direct source
m_thermal,max 0.05 /h No direct source

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.1 PSU Strictly freshwater
σ_S 1.5 PSU No direct source
S_stress (low / high) 0.0 / 2.0 PSU No direct source
S_lethal (low / high) 0.0 / 5.0 PSU No direct source
m_salinity,max 0.30 /h No direct source
Osmoregulation cost 0.006 × maint No direct source

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 No direct source
pH lethal (low / high) 5.0 / 10.0 No direct source
m_pH,max 0.05 /h No direct source

NH₃ toxicity

Symbol Value Units Source / Rationale
NH3 stress 2.0e-6 mol/L Comparable to / tighter than Daphnia (Karntanut & Pascoe 2002)
NH3 lethal 4.0e-5 mol/L No direct source
m_NH3,max 0.10 /h No direct source

Cu / H₂S toxicity

Symbol Value Units Source / Rationale
K_Cu,tox 1.0e-7 mol/L Lowest in codebase; 96-h LC50 ~13 µg/L (Karntanut & Pascoe 2002; Holdway 2001)
K_H2S,tox 8.0e-7 mol/L Mirrors copepod

Mortality, feces, density-dependence

Symbol Value Units Source / Rationale
m_base 0.015/24 /h Long-lived under good conditions (Martinez 1998)
Feces C:N 9.0 mol / mol No direct source
Feces → suspended fraction 0.40 fraction Compact regurgitation pellets
Death → suspended fraction 0.30 fraction Detached sinking polyps
Starvation m_max 0.08/24 /h No direct source
Crowding m_max 0.05/24 /h Sessile, contact-mediated; budding rate drops
K_crowding 1.0e-4 mol/L No direct source
m_total,max 0.50 /h Cap

Fish

Fish biomass is a bioenergetic condition state on discrete cohort slots (V2; see docs/consumers/fish_and_feeding.md and internal_docs/planning/fish_realism_v2_spec.md). A population is K = min(N₀, K_max) slots, each carrying its own C/N/P biomass and a structural target W*ⱼ = mⱼ·w* (per-capita adult size × the count the slot stands for). The Wisconsin/DEB-lite balance A_net = assim − maint − SDA drives growth (gated toward target, with a reserve buffer), wasting (soma catabolised under deficit), and death (acute via the health gauge, or chronic wasting below c_death). The ecosystem-facing output is still bioload (an O₂ sink + NH₄/CO₂/PO₄ source); the fish-facing outputs are the continuous health gauge ∈ [0, 1] (fast water-quality axis) and the condition c = W/W* (slow nutritional/survival axis). FishSpecies subclasses Consumer to reuse the feeding/respiration/tolerance pipeline and overrides the biomass-change, feeding-suppression, and mortality stages; the base computes aggregate feeding/respiration/acute-mortality on the summed slot biomass and the overrides redistribute across slots (the neocaridina stage-structured precedent).

Status (June 2026): V2 P1 + P2 shipped. P1 = condition + slots + wasting death (retires V1's fixed-biomass all-C→DIC override). P2 = heterogeneity — each slot now carries its OWN health gauge plus a deterministic robustness offset that shifts its water-quality stress thresholds (V2-D4), and the shared ration is split dominance-weighted across slots under feed scarcity (V2-D5). Together these make deaths stagger by individual: a toxic spike picks off the least-robust slot first while the hardy ones survive the same water ("one died, one lived"); scarce feed starves the most-subordinate slot in otherwise-clean water (the runt). The base bioenergetic / health-ODE / mortality constants below are hand-tuned estimates calibrated so a fish behaves the way a hobbyist expects: holds weight on a normal ration, regrows when underfed-then-fed, wastes to death over ~3–4 weeks unfed (R2), and gets sick-fast / recover-slow through the health gauge. The per-species tolerance thresholds (NH₃ / NO₂ / O₂ / T / pH bands) were calibrated in P3 against species or congener LC50 / tolerance literature where it exists, flagged "hand-tuned" otherwise. The acute-kernel rates (*_mort_max) are kept uniform and gentle across the roster: the health gauge is the primary acute-stress integrator, so the fragile↔hardy spread comes from the thresholds feeding the health blend, not per-species kernel rates. The classic energy-deficit starvation m_max stays 0 — under-feeding manifests mechanistically as condition wasting (W shrinks → c falls → the c_death wasting pathway), not an instantaneous energy-ratio kernel.

Fish symbol glossary

Symbol Meaning
H Health gauge, a per-population ODE state ∈ [0, 1] (1 = perfectly healthy, 0 = dead). Non-mass scalar slot (the biofilm-maturity precedent), excluded from mass balance.
stress(t) Max over normalized water-quality stressor intensities (NH₃/NO₂/O₂/T/pH/Cu/H₂S), each 0 at comfort → 1 at that species' lethal threshold (reuses the biology.py kernel thresholds).
comfort(t) 1 − stress(t).

Fish base — health ODE

dH/dt = k_recover·(1−H)·comfort − (k_damage·stress + k_acute·relu(stress − s_lethal))·H. The asymmetry (k_damage > k_recover) is the point: a fish gets sick fast and recovers slowly, staying sick for days after a spike clears (chronic memory). Health drives an added mortality term ramping as H falls below the onset. V2 P2: this is now a per-slot gauge — each cohort slot integrates its OWN stress, computed against that slot's robustness-shifted thresholds (the heterogeneity table below), so the weak slot's health collapses first under a shared toxic insult. The reported {id}_health_0_1 / fish_health_min_0_1 columns are the worst-off LIVING slot (a dead slot is excluded, mirroring {id}_condition). Every loss term is scaled by H (recovery by 1−H), so the derivative vanishes at both ends and the gauge stays in [0, 1] by construction — under lethal water H asymptotes toward 0 (a ~5 h half-life collapse) instead of being driven through it. That smooth landing is also a numerical necessity: a derivative that stayed strongly negative at H = 0 collided with the rhs non-negativity floor guard, creating a step discontinuity at the H = 0 surface that LSODA chatters across (step size collapses → the sim appears to freeze). This bit sealed high-bioload tanks the moment bulk O₂ went lethal; open-top tanks never reach lethal O₂, so health never touches the boundary.

Symbol Value Units Source / Rationale
k_recover 0.006 /h Recovery t½ ≈ 5 d in full comfort; estimate
k_damage 0.070 /h ~12× faster than recovery (sick-fast). Calibrated (Jun 2026) so the gauge faithfully displays condition: the equilibrium under a sustained stress s, H* = k_recover·(1−s)/(k_recover·(1−s)+k_damage·s), maps a slow ammonia die-off (~0.18 normalized stress, e.g. betta_bowl) into the "stressed" band (~0.4) rather than reading mid-"healthy" through a 30 %-biomass decline. Display recalibration — paired with the lowered onset below it leaves the mortality model neutral
k_acute 0.50 /h Near-instant collapse past s_lethal (hours); estimate
s_lethal 0.75 Normalized-stress threshold engaging the acute term (approaching lethal water); estimate
m_health,max 0.05 /h Health-driven mortality as H→0 (~120%/day, enables die-off); estimate
Health-mortality onset 0.13 H above this → ~no health mortality; quadratic ramp below. Lowered 0.35→0.13 (Jun 2026) in lock-step with the steeper k_damage so the coupling engages at the same stress severity (s≈0.36) as before — mortality-neutral by construction, while freeing the gauge to display "stressed" under chronic sublethal load without spuriously adding mortality
Appetite floor 0.15 fraction Ration multiplier as H→0 (a sick fish eats less → slower recovery feedback); estimate
Aerial O₂ access 0.0 fraction Labyrinth-organ efficiency for breathing the surface gas phase (air-breathers > 0; Betta ≈ 0.9). Sets the fish's effective O₂ = max(dissolved O₂, this·O₂-equiv-of-the-accessible-gas), which gates BOTH the health-gauge low-oxygen stressor AND the direct hypoxia mortality kernel. Accessible gas = open atmosphere (fixed pO₂, infinite) for an open top, or the finite/depletable O2_HEAD headspace for a sealed jar (so the air-breather is decoupled from dissolved-O₂ hypoxia while the surface gas holds O₂, but not immune to a genuinely anoxic sealed jar). 0 = byte-neutral (water-only breather)

Fish base — body, ingestion, metabolism

Symbol Value Units Source / Rationale
C:N 5.5 mol / mol Fish body C:N 5–6 (Sterner & Elser 2002); estimate
N:P 20.0 mol / mol Fish body N:P 15–25 (Sterner & Elser 2002); estimate
Imax 0.020 /h Lower per-mass turnover than zooplankton; estimate
K_C 1.0e-5 mol C/L Holling-II half-saturation (~0.12 mg C/L). Lowered 8e-5→1e-5 for V2: fish target and avidly consume prepared feed, so the response must saturate at the modest concentrations a daily ration pulses to — at 8e-5 the fish sat in the linear regime and captured only ~25 % of a ration before the uneaten remainder decayed, so net assimilate fell below maintenance and a fed fish starved
R_maint 0.0009 /h Maintenance respiration (~2.2 %/day body C). Lowered 0.0020→0.0009 for V2: now an energy term (biomass holds only when net assimilate ≥ maintenance), so it must be allometrically sane — a fish (large) sits BELOW the cherry-shrimp's 0.0008, not above it. The old 0.0020 (a zooplankton-scale rate, inherited unexamined when fish were fixed-biomass and maintenance only set the O₂ draw) burned more than a normal ration delivers, starving every fed fish. Gives a comfortable surplus at a normal ration and a realistic unfed-starvation timescale (R2): a hardy danio survives a holiday-length fast easily — only lightly thinned (condition c≈0.8) after 2 weeks, c≈0.7 at 3 weeks — and only crosses the c_death floor at ~6 weeks, where it dies (verified in scenarios/fish_v2_wasting.yaml, a pure-starvation oracle). The timescale is per-mass identical across the roster (only body size individual_N_mg differs); true allometric species-dependence — small tetras starving faster than a cory — is a deliberate deferral, not modelled
SDA fraction 0.15 fraction Heat increment of feeding, fish ~15% (Jobling 1981); estimate
Nocturnal feeding fraction 0.5 fraction Most community fish are diurnal; estimate

Fish base — bioenergetic condition & slots (V2)

Biomass is K_max discrete cohort slots (named locations slot_0..slot_{K-1}). Per slot the net assimilate after respiration A_netⱼ = net_C_gain·frac_foodⱼ − maint·frac_bioⱼ drives growth gated by condition, with surplus excreted/respired and a deficit catabolising soma. Maintenance is paid ∝ each slot's biomass; the captured ration is split dominance-weighted (V2-D5, below). Conservation is exact: both fracs sum to 1, so the per-slot split only redistributes who grows vs. starves, never the aggregate totals; the only change vs the base Consumer is that un-stored surplus moves from tissue to DIC/NH₄/PO₄ (tracked→tracked), and the carbon→DIC is an RQ-independent residual (assim − growth − O2-excess), not the RQ-scaled CO2_resp — which is the bug V1's all-C→DIC override masked. At/above the reserve cap with no growth this recovers V1's "all assimilated C → DIC".

Symbol Value Units Source / Rationale
K_max (slots) 12 count Bounds the per-population state count; slot = individual when N₀ ≤ 12, else a cohort of ~N₀/12 (multiplicity mⱼ, school binning)
w* (per-capita target) individual_N_mg × cn mol C Adult structural target; condition c = W/W* = 1 at adult size. Per species via individual_N_mg (danio 14 mg N, etc.)
c_death 0.5 Wasting-death threshold (die at ~50 % structural-mass loss; fish survive ~30–50 %: Madenjian et al. 2000; Hartman & Brandt 1995). Per-species override allowed
c_max_store 1.2 Energy-reserve ceiling (a well-fed fish carries ~20 % over structural mass as reserve). The minimal "fat reserve" the spec (§11) anticipated R2 would need: without it a fish on an intermittent ration (feed decays t½≈4 h → daily feast + long fast) would dump the feast surplus via the growth gate and waste during the fast, so a fed fish could never hold weight. With it the fish banks the feast and draws it down across the fast
m_waste,max 0.015 /h Terminal wasting mortality once past c_death, ramped from 0 at c_death to this max over the narrow band wasting_lethal_band·c_death (then held). ln 2/~2 d → a fish that has wasted past the survival floor dies over ~5–8 d as a ~half-mass carcass, rather than catabolising itself down toward ~1 % over ~30 d while a slow death rate caught up. Raised 0.0072→0.015 + steep ramp (June 2026): the old full-range linear ramp was near-zero just below c_death, so the living fish out-wasted its own death (excreting ~90 % of its body before the slot emptied — unrealistic, and exposed once dead fish became a tracked carcass export rather than decomposing). Applied as rate × Wⱼ → smooth landing (slot asymptotes to 0, the freeze-lesson)
wasting_lethal_band 0.3 Condition band below c_death (as a fraction of c_death) over which m_waste ramps 0→max, then saturates: full rate by c = 0.7·c_death (≈0.35). Makes death win over continued catabolism right below the floor (a fish a little past the floor is already dying fast, not lingering)
w_alive_eps 1e-4 fraction Per-capita floor below which a slot is treated as empty (numerical)

Fish base — heterogeneity: robustness spread & dominance feeding (V2 P2)

The W2 "one died, one lived" behaviour. At seeding each of the K = min(N₀, K_max) active slots is assigned a deterministic standardized quantile zⱼ = Φ⁻¹((j+0.5)/K) (no RNG → reproducible; slot 0 weakest, ascending). zⱼ enters each slot's water-quality stress response through a mixed model matched to the physics of each stressor — individual variation means different things for an acute poison than for a physiological window:

  • One-sided toxicants + O₂ (NH₃, NO₂, Cu, H₂S, low-O₂) → a threshold shift (tolⱼ = 1 + σ_robust·zⱼ; toxicants ×tol, O₂ floor ÷tol). A hardier slot genuinely tolerates a higher dose — the textbook toxicological picture, where an LC50-with-slope is a distribution of tolerated doses across individuals and a hardy fish can persist at a chronic sublethal level a sensitive one dies at.
  • Two-sided physiological windows (temperature, pH) → a response gain (gainⱼ = 1 − σ_robust_resp·zⱼ on the severity), NOT a threshold shift. The comfort band is identical for every slot (within-species pH/T tolerance is a near-uniform gill/enzyme limit, not a detox dose-response); robustness scales only how hard the slot is damaged once already outside the band. Because gain×0 = 0 inside the band, this can never make a slot feel pH/T stress the nominal individual doesn't — the fix for the old two-sided threshold-narrowing spuriously killing the weakest fish in an ordinary hard-water (pH ≈ 8.3) or CO₂-injected (pH ≈ 6.6) tank.

Either way the weakest slot is worst-off under a genuine insult → its per-slot health collapses first and it dies first. zⱼ also sets a dominance weight for the feed split (V2-D5: ration ∝ size · health · dom(zⱼ)). A solo fish (K=1 → z=0) gets no spread — it is exactly the nominal individual (so single-fish scenarios are byte-unchanged).

Symbol Value Units Source / Rationale
σ_robust 0.30 Threshold-shift spread for the one-sided toxicant/O₂ axes only: slot j's thresholds scale by tolⱼ = 1 + σ_robust·zⱼ (toxicants ×tol, O₂ floor ÷tol). 0.30 = ±~20 % between the K=2 quantiles (z≈±0.674), within the real inter-individual variation in fish acute-toxin LC50s (often ±20–30 %); enough to give a hardy slot a clear survival margin where the weak one crosses lethal, small enough that the larger fish-in cycling scenarios' aggregate die-off fractions are preserved. Hand-tuned; per-species override allowed
σ_robust_resp 0.30 Response-gain spread for the two-sided pH/T axes: severity ×gainⱼ = 1 − σ_robust_resp·zⱼ once a slot is inside its (nominal) stress band. Reuses the σ_robust magnitude, but is far gentler because it acts only inside the band — it is the direction (weak slots damaged harder, not sooner) that carries the realism. 0 → pH/T robustness-blind. Hand-tuned; per-species override allowed
dominance_spread (β) 0.5 Feed-hierarchy strength: dom(zⱼ) = exp(β·zⱼ). β=0.5 gives the top slot ~e^(β·z) ≈ 4–5× the bottom's per-size pull across an 8-slot school. The split only bites under aggregate feed deficit (net assimilate < maintenance demand); under a surplus it relaxes to the proportional biomass split. It is scarcity-gated and therefore self-limiting: chronic underfeeding in clean water settles the shoal to a lean, size-diverged equilibrium (dominants heavier, subordinates leaner) rather than starving a subordinate to death — fish are starvation-tolerant and a genuine subordinate death is contest/social-stress driven (deferred R9), not pure energy balance. Hand-tuned

Fish base — O₂, thermal, salinity, pH, toxicity

In the fish model the health gauge is the primary integrator of sublethal stress and the primary chronic-mortality driver; the direct biology.py acute kernels are retained (an acute lethal slug still kills directly) but tuned gentle so a hardy fish is not killed by a routine cycling spike — fast death near/above lethal comes through the health pathway (stress → acute collapse → health mortality). The *_mort_max values are therefore deliberately low.

Symbol Value Units Source / Rationale
K_O2 (activity) 9.0e-5 mol/L Fish need more O₂ than inverts; estimate
K_O2 (respiration) 6.0e-5 mol/L estimate
O2 stress / lethal 1.25e-4 / 6.25e-5 mol/L ~4 / ~2 mg/L; estimate
m_hypoxia,max 0.02 /h Gentle (health-led); estimate
T_ref 25 °C T_REF_C
Q10 ingestion / resp / mort 2.0 / 2.0 / 2.0 estimate
T_stress (low / high) 18 / 28 °C estimate (overridden per species)
T_lethal (low / high) 10 / 36 °C estimate (overridden per species)
m_thermal,max 0.02 /h Gentle (health-led); estimate
S_opt / σ_S 0.3 / 2.5 PSU Freshwater; estimate
S_stress (low / high) 0.0 / 3.0 PSU estimate
S_lethal (low / high) 0.0 / 12.0 PSU estimate
m_salinity,max 0.10 /h estimate
Osmoregulation cost 0.004 × maint estimate
pH stress (low / high) 6.0 / 8.5 estimate
pH lethal (low / high) 4.5 / 9.5 estimate
m_pH,max 0.02 /h Gentle (health-led); estimate
NH3 stress / lethal 4.3e-6 / 2.9e-5 mol/L ~0.06 / ~0.4 mg NH₃-N/L; estimate (overridden per species)
m_NH3,max 0.008 /h Gentle (health-led); estimate
NO2 stress / lethal 7.1e-5 / 7.1e-4 mol/L ~1 / ~10 mg NO₂-N/L; looser than inverts (Cl⁻ protective); estimate
m_NO2,max 0.005 /h Gentle (health-led); estimate

Fish base — mortality & routing

Symbol Value Units Source / Rationale
m_base 0.0005/24 /h Fish are long-lived (years), ~0.05%/day; estimate
Starvation m_max 0.0 /h Classic energy-deficit kernel stays OFF — under-feeding is mechanistic in V2 (condition wasting → the c_death pathway, see the condition table above), so an instantaneous energy-ratio kernel would double-count
m_total,max 0.50 /h Cap
Feces → suspended fraction 0.10 fraction Fish feces sink; mostly settled detritus. Still active — feces/egestion from living fish is the real fish-in-cycling bioload
Carcass routing export A dead fish is netted out by the keeper, NOT left to decompose: its carcass biomass is exported from the system (booked to the fish_removed_{C,N,P} ledgers, mass-balance credits "− removed"), releasing zero nutrients — instead of routing to detritus to mineralise back into ammonia. The acute case (toxin/hypoxia kill) exports a near-full carcass; a starvation death exports a ~half-mass carcass (the fish metabolised the other half to NH₄ while alive). death_to_suspended_frac is therefore vestigial for fish
Water-change removal fraction 0.0 fraction Fish are not netted out during a water change

The fish roster — GENERATED (one species per planner fish)

The fish roster is no longer five hand-written species. It is generated: one FishSpecies per planner fish (982 of them), emitted by stocking.fish_roster from a single uniform rule composing S1 bands, S2 size/shape and the S3 toxicology ladder (internal_docs/planning/fish_roster_expansion.md). Per CLAUDE.md, 982 species cannot each get a hand-written section, so the live per-species numbers with their provenance live in a separate generated table, parameter_reference_generated_fish.md, kept apart from the hand-written, literature-cited sections here.

The five formerly hand-calibrated fish (neon tetra, zebra danio, betta, guppy, corydoras) are generated by that same pipeline — no overrides (programme §4.2, 2026-07-23) — so their values now come from the rule and differ from the tables that used to sit here. They are retained as the accuracy-validation set: the only fish whose right answer is known from literature, scored against these anchors in internal_docs/planning/fish_roster_generator_accuracy.md.

Ammonia thresholds come from published LC50s where one exists (rung 1). Since 2026-08-01 the generator reads a committed table of 96-h LC50s keyed by binomial (stocking/ammonia_lc50.py) before falling back to the habitat-acidity map. One conversion, the one the hand roster already obeyed:

NH3_lethal = 0.7 × LC50          NH3_stress = NH3_lethal / 7.5 = 0.0933 × LC50

clamped to [0.020, 0.120] mg NH₃-N/L. The floor says nothing is more sensitive than the most sensitive fish ever measured. The ceiling is a model limit, not a claim about the fish — the health kernel is calibrated over the range the five span, and a betta generated at its literal 6.33 mg NH₃-N/L cannot be harmed in any tank a keeper would build.

fish 96-h LC50 (mg NH₃-N/L) live NH3_stress source
Neon tetra (Paracheirodon innesi) 0.218, via the congeneric cardinal (most sensitive of eleven) 0.0203 Souza-Bastos, Val & Wood (2017) Hydrobiologia 789:143–155 — the ammonia anchor, not Oliveira (S3 §3.3a)
— its nitrite / pH / temperature NO₂ LC50 ~1.1 mg/L, pH 2.9–8.8, survival < ~19.6 °C Oliveira et al. (2008) Acta Amazonica 38(4):773–780, which judged the same cardinal tolerant to ammonia (0.443 mg NH₃-N/L speciated) — a ~6× test-water disagreement, and the reason this row is curated rather than pooled
Zebra danio (Danio rerio) 0.732, median of three 0.0683 Jeffries et al. (2014) Environ. Toxicol. Chem. 33:2584–2594 (embryo, 0.938); Alsop & Wood (2013) Aquat. Toxicol. 140/141:257–267 (larva, 0.507); Mondal, Kaur & Ghosh (2025) Discover Toxicology 2:13 (adult, 0.732)
Guppy / Endler (Poecilia reticulata) 1.10, median of two 0.1027 Frances et al. (2023) Acta Biológica Colombiana 28(1):57–64 (1.17); Rubin & Elmaraghy (1977) Water Res. 11:927–935 (1.020)
Corydoras (Corydoras aeneus) 1.90 (congener C. schwartzi), most tolerant of eleven, via facultative air-breathing 0.120 (ceiling) Souza-Bastos et al. (2017). Corrects the hand roster, which had the corydoras 6.3× below its own measurement (S3 §3.3b)
Betta (Betta splendens) 6.33 (123.4 mM TAN); NO₂ LC50 ~344 mg/L 0.120 (ceiling) Anh et al. (2023) BMC Zoology 10:60

Six more roster species (angelfish, koi, fathead minnow, bluegill, golden shiner, red shiner, both bass) take their value straight from the EPA ECOTOX Knowledgebase median without a curated row, because nothing about them needed deciding. 13 of 982 species are literature-anchored; the rest still ride the habitat-acidity map.

What the map is worth, measured. The map's 0.52/pH slope was fitted to two LC50s from two different labs. Joining ECOTOX onto the roster gives 11 independent points (python -m stocking.ecotox_sync audit), the first set large enough to score it: the fitted slope is 0.256/pH with a 95 % CI of [−0.004, 0.517], so the shipped 0.52 is not rejected but barely supported, and out-of-sample the map buys 1.47× against 1.60× for a flat constant. Band width — the "is this fish an acidic specialist or a wide-band generalist" hypothesis — is worse than a constant (1.76×, and the sign points the wrong way). The map is kept as shipped; the honest reading is that it is a weak prior, which is why rung 1 exists.

Attribution. The generated bands and sizes derive from The Aquarium Wiki (CC BY-SA 3.0) and FISHMORPH (Brosse et al. 2021, CC BY 4.0), so that credit is owed here as well as on the stocking pages (stocking/data/ATTRIBUTION.md). The LC50 table is built from the US EPA ECOTOX Knowledgebase (public domain; Olker et al. 2022, Environ. Toxicol. Chem. 41:1520–1539) plus the primary literature cited above.

One correction to a wrong published band. Danio rerio's Aquarium Wiki page gives pH 6.0–7.5 and 18.3–23.9 °C — a keeping band, and one the wiki contradicts on its own GloFish page for the same species (pH 7.0–8.0, 21.7–26.7 °C). Two husbandry standards written for the species by name put the entire routine maintenance range above that temperature ceiling and reach pH 8.0: Aleström et al. (2020) Laboratory Animals 54(3):213–224 (24–29 °C, pH 6.5–8.0) and Westerfield (2007) The Zebrafish Book 5th ed. (24–31 °C, standard 28.5 °C); Lawrence (2007) Aquaculture 269:1–20 adds that the Ganges-drainage water the species comes from is "typically alkaline, with an average pH in excess of 8.0". The corrected keeping bands are 18.0–29.0 °C and pH 6.5–8.0, recorded in stocking/data/water_corrections.json with the full disagreement. This mattered: under the uncorrected pH band the danio took continuous pH damage in a seeded tank holding 0.028 mg/L ammonia, because soft tap water degasses to ~8.1 and stays there.

The base-class Fish sections above (health ODE, body, metabolism, toxicity defaults) are unchanged and still describe the shared mechanism every generated fish inherits.

Fish feeding (Phase 2) — external feed & bioload

External feed is the model's only organic input. A feed event (feeding: scenario block) adds dry food of fixed C:N:P stoichiometry to the transient fish_feed pool; fish graze it (high preference, fast), and uneaten feed decays to suspended detritus. Because fish are a fixed-biomass boundary condition with no growth sink, every feed-N atom becomes ammonia (assimilated N excreted ammonotelically + egested N → detritus → mineralised), reproducing the empirical RAS bioload factor (~25–35 g TAN/kg feed/day; Merino 2007) mechanistically rather than by fiat. Constants live in engine/dosing.py; the decay process in processes/fish_feed.py. See docs/consumers/fish_and_feeding.md.

Symbol Value Units Source / Rationale
Feed C:N:P (molar) 9 : 1.6 : 0.1 mol/mol Default dry prepared food ≈ 45 % protein; N:C 0.18 molar, C:P ~90 (≈ 9 % N, ~1 % P by dry mass). Roberts 2018 feed tables; overridable per scenario (cnp_molar)
Feed C fraction (dry) 0.45 g C / g dry Carbon mass fraction of dry prepared food (high-protein organic matter); with the C:N:P ratio fixes the N/P mass fractions and hence the RAS factor. Hand-tuned anchor
k_feed_decay 0.173 /h Uneaten feed → suspended detritus; ~4 h half-life (flake/pellet saturates and fragments within hours). Second-order knob — all routes lead to the same detritus → NH4 fate, only the lag differs
Auto feed rate 1.5 % fish wet mass / day Maintenance ration for adult community fish at ~24 °C (auto.pct_fish_biomass_per_day); the hobbyist default when grams are not given
Fish wet mass per body N 0.05 g wet / mg N From the §5 anchor (individual_N_mg = wet_g × 20); converts a fish stocking (tracked in mg N) into the wet mass the auto rate scales against
Danio fish_feed preference 1.0 Prepared food taken avidly; not a refuge-protected prey (interactions.yaml)
Danio fish_feed assimilation 0.80 fraction Prepared food is highly digestible (NRC 2011 fish nutrition); assimilated → NH4, egested 20 % → feces/detritus
Danio fish_feed access 1.0 fraction Fully accessible (formulated food, no refuge)

(Starvation mortality stays 0 in P2 — a fixed-biomass boundary condition does not starve to lose mass; under-feeding instead manifests through reduced appetite and the health gauge. True nutrition→condition coupling is future work.)

Botanicals — dried leaf litter

The second external organic input. A botanicals: block adds dried plant material (catappa/Indian almond leaves, oak leaves, alder cones, guava leaves) on a cadence, released continuously across the interval rather than dumped, because a leaf takes 2–4 months to break down and a topped-up litter bed sits at quasi-steady state. No new state pools: the dry mass is partitioned at dose time across settled detritus (the CPOM leaf body), labile and refractory DOM (the leachate), and the bioactive polyphenol tracer. Each element is routed as fractions of its own total with the detritus slot taking the remainder, so C/N/P conserve by construction (scenarios/botanicals_mass_balance_sealed.yaml reads 0.00 % drift on all three). Constants live in engine/botanicals.py; the dose spec and schedule in engine/dosing.py. See docs/nutrient_cycling/botanicals.md.

Shared leachate partition — the same for every botanical, because the early leachate of any broadleaf litter is DOC-rich and N-poor.

Symbol Value Units Source / Rationale
Polyphenol C fraction 0.50 g C / g phenolic Gallic acid (C₇H₆O₅) is 49.4 % C, tannic acid ~51.6 %; round midpoint. Converts a phenolic mass fraction into the pure-C polyphenol tracer
Polyphenol leachable fraction 0.60 fraction of total phenolics Hydrolysable tannins (punicalagin/punicalin in catappa; Lin et al. 1997) are highly water-soluble; cell-wall-bound condensed tannins are not. Salminen & Karonen 2011 for the solubility split. Calibrated, not measured
Polyphenol bioactive fraction 0.10 fraction of leached phenolic C Share entering allelopathy:polyphenol; the remaining 90 % books as refractory DOM (polymeric tannin + humic complexes — also the fraction that tints and shades). The free low-molecular-weight share: Nakai et al. (2000) isolated their active material as the water-soluble fraction below 1000 Da by assay-directed fractionation, while a dried brown leaf's leachate is dominated by 500–3000+ Da hydrolysable/condensed tannin that Folin-Ciocalteu still counts as GAE (Maie et al. 2008). Order-of-magnitude, and generous for a hard-water tank — polyphenol efficacy falls further with rising pH as monomers polymerise (Laue et al. 2014). 0.02 → 0.10 on 2026-08-02: the old value was also absorbing half-saturations keyed 20× below the published pure-compound EC50s. Those have been rebased, so the correction is applied once, here
Soluble C fraction 0.45 g C / g non-phenolic leachate Standard organic-carbon figure for carbohydrates/amino acids; below whole-leaf C because leachate carries more O per C than lignified tissue
Soluble labile fraction 0.70 fraction of non-phenolic leachate C Mirrors Decomposition.frac_DOM_labile_susp — fresh material yields mostly labile DOM. Remainder → refractory
N leached → labile DOM 0.10 fraction of leaf N Litter leaching mobilises ~10–20 % of leaf N (Petersen & Cummins 1974); low end because senesced leaves have already resorbed their soluble N
N leached → refractory DOM 0.03 fraction of leaf N Humic-bound N in the leachate
P leached → labile DOM 0.25 fraction of leaf P P leaves litter faster and more completely than N — largely soluble orthophosphate and labile phosphomonoesters rather than structural protein (Webster & Benfield 1986)
P leached → refractory DOM 0.03 fraction of leaf P Humic-complexed P
Default interval 21 days Hobbyist practice: a fresh handful every 2–4 weeks as the last lot breaks down

Per-botanical composition — oven-dry mass fractions plus the typical weight of one piece. Composition sources: Ostrofsky 1997 (litter C/N/tannin ranges across 23 broadleaf species), Aerts 1997 (senesced-litter N after resorption), Webster & Benfield 1986 (litter N:P), Chyau et al. 2002 (catappa total phenolics). Piece masses are hobby-scale observations, not literature.

Botanical g dry/piece C N P Total phenolics Leachate (72 h) ⇒ detritus C:N (molar)
indian_almond (Terminalia catappa) 2.0 0.46 0.0090 0.00050 0.09 0.18 56
oak_leaf (Quercus spp.) 1.0 0.48 0.0080 0.00040 0.10 0.12 71
alder_cone (Alnus glutinosa) 0.3 0.47 0.0110 0.00060 0.14 0.10 51
guava_leaf (Psidium guajava) 1.2 0.45 0.0120 0.00070 0.05 0.20 40

Alder is the nitrogen-fixer, hence the highest litter N of the four, and the most tannic per gram. Oak's C:N of 71 sits above the 40–65 band typical of most litter, which is correct for Quercus (Ostrofsky 1997 reports up to ~90) and is why oak immobilises the most nitrogen per gram. The four types share one settled-detritus pool, so they do not differ in breakdown rate — oak really is slower than guava in a real tank and that is not captured.

Deferred, not modelled: organic (humic/fulvic) acidity. chemistry.py solves pH from TA + DIC only, so tannic acid's direct pH effect would need a third acid-base system in the solver. All pH movement from botanicals in this model is via the CO₂ their carbon respires to.


Microbes

Microbes — nitrifiers, the heterotrophic-bacteria pool, the diagenetic-ladder anaerobes (denitrifier, DNRA, Fe-reducer, sulfate-reducer, methanogen), and aquatic fungi — share a μ_max / Monod-substrate / O₂-gated growth skeleton, layered with terminal-electron-acceptor ladder inhibition, biofilm protection from grazing, and (for nitrifiers, sediment anaerobes) a bulk-vs-pore biomass split.

Microbe symbol glossary

Symbol Meaning
μ_max Maximum specific growth rate (per h)
K_X Monod half-saturation for substrate X (NH₄, NO₂, DOM, settled detritus, soil OM…)
K_O2 O₂ Monod half-sat for growth (separate K_O2 for respiration)
BGE (Y_C/X) Bacterial growth efficiency — mol cell C per mol substrate processed
O₂:X Mol O₂ consumed per mol substrate oxidised
TA:X TA change per mol substrate (negative releases H⁺, positive consumes H⁺)
Acceptor:C Mol terminal electron acceptor reduced per mol C oxidised (NO₃, Fe(III), SO₄, CO₂)
TA:C TA change per mol C oxidised through the ladder reaction
Pore fraction Biomass share resident in soil pore-water zone (vs bulk) — drives substrate access
K_NH3,inhib / K_HNO2,inhib Free-ammonia / nitrous-acid inhibition Hill K for NOB/Comammox (Anthonisen 1976; Vadivelu 2006/2007)
K_NO3,inhib Cascade gate disabling lower-rung anaerobes while NO₃ is available
K_oxide,inhib (pore) Cascade gate disabling SR while reducible Fe(III) is available (pore-concentration basis)
K_pore SO4,inhib Cascade gate disabling methanogens while pore SO₄ is available
Biofilm predation protection Maximum M-modifier — fraction of biomass unreachable to grazers at full biofilm maturity (Schramm 1996; Matz & Kjelleberg 2005)
Geometric predation shield M=0 floor for the same kernel — roughness-scaled shelter even on immature surfaces
Biofilm light attenuation M=1 light shading factor for nitrifier biofilm
Induction lag Enzyme-induction delay for fresh inoculum (h)
K_viral, m_viral,max Density half-sat and max rate for phage / NCLDV lysis kernel
Settlement / detachment rate First-order kinetics for biofilm colonisation and detachment

Nitrifier base

Shared base for AOB / NOB / Comammox — pore-attached chemoautotrophs with explicit biofilm light attenuation, predation protection, and an induction-lag floor. Refs: Prosser 1989, Daims 2015, Schramm 1996.

Growth & stoichiometry (base defaults — overridden per subclass)

Symbol Value Units Source / Rationale
Pore fraction 0.0 fraction Phase 3 sediment realism: biomass share in soil pore zone. Auto-injected to ~0.5–0.7 in soil scenarios (textbook: ~80% of aquarium nitrification in substrate biofilm)
O₂:X (base) 2.0 mol O₂ / mol N Sum of AOB+NOB half-reactions (1.5 + 0.5)
TA:X (base) −2.0 eq TA / mol N Full NH₄→NO₃ releases 2 H⁺
Body size 0.0001 cm ~1 µm nitrifier cell
μ_max (base) 0.55/24 /h Overridden per subclass
K_substrate (base) 2.5e-5 mol/L Overridden per subclass
K_O2 3.0e-5 mol/L ~1 mg O2/L; AMO/NXR aerobic affinity
K_Fe (AMO) 5.0e-9 mol/L Wagner et al. 2002; Ensign 1993 — purified AMO/NXR Fe affinity 1–5 nM midpoint; nitrifiers tighter than producer baseline due to higher Fe-S cluster load
BGE (base) 0.08 mol C / mol N Prosser 1989 AOB default; overridden per subclass
C:N 5.0 mol / mol Bacterial C:N
N:P 16.0 mol / mol Redfield-style N:P

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 5.0e-5 mol Fe / mol C AMO di-iron + electron transport Fe-S clusters
Mo:C 1.0e-8 mol Mo / mol C Universal anchor (base; NOB/Comammox elevate)
Zn:C 4.0e-7 mol Zn / mol C Universal anchor
Cu:C 2.0e-7 mol Cu / mol C AOB AMO Cu; overridden per subclass
Ni:C 1.0e-7 mol Ni / mol C Universal anchor
Co:C 5.0e-9 mol Co / mol C Universal anchor
B:C 5.0e-6 mol B / mol C Universal anchor
S:C 5.0e-3 mol S / mol C Universal anchor

Inhibition (sentinels; subclasses opt in)

Symbol Value Units Source / Rationale
K_NH3,inhib (base) 0.0 mol/L Sentinel disables; only NOB/Comammox opt in (Anthonisen 1976)
K_HNO2,inhib (base) 0.0 mol/L Sentinel; NOB activates

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0005 mol O₂ / mol C / h Low maintenance for chemoautotroph
K_O2 (respiration) 1e-5 mol/L High maintenance O2 affinity (~0.3 mg/L)

Thermal envelope

Symbol Value Units Source / Rationale
T_ref T_REF_C (25) °C Standard reference
Q10,growth 2.5 Nitrifier literature midrange (sub-optimal limb)
T_opt,growth 30.0 °C Growth thermal optimum; below it the factor is identical to the bare Q10, above it the rate declines linearly to 0 at T_max (asymmetric curve, R6). Community/aquarium optimum ~28–30 °C; pure-culture Nitrosomonas ~35 (Grunditz & Dalhammar 2001; EPA Nitrification)
T_max,growth 49.0 °C Temperature where growth rate reaches 0 (audit §9.4 anchor ~49 °C). Respiration/maintenance keep the plain monotonic Q10, so the growth–maintenance gap above the optimum drives the hot-tank stall
Q10,resp 2.0 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 10.0 / 38.0 °C Wide tolerance
T_lethal (low / high) 0.0 / 45.0 °C Wide tolerance
m_thermal,max 0.02 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 20.0 PSU Brackish-tolerant
σ_S 30.0 PSU Wide Gaussian
S_stress (low / high) 0.0 / 50.0 PSU Wide tolerance
S_lethal (low / high) 0.0 / 150.0 PSU Wide tolerance
m_salinity,max 0.05 /h Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.0 / 9.0 Standard nitrifier band
pH lethal (low / high) 5.0 / 10.0 Standard
m_pH,max 0.03 /h Standard

pH–rate activity curve (pH_activity_points)

Direct pH dependence of the nitrification rate — distinct from the pH stress/mortality band above, which only kills at the extremes. Free NH3 (not NH4⁺) is the AMO substrate, and the NH3 fraction falls ~10× per pH unit, so the AOB/comammox step starves at low pH even when total ammonia is high; NOB physiology slows in acid too. Applied as a piecewise-linear multiplier on µ for all three guilds. Curve calibrated to the consistent literature/extension consensus (EPA Nitrification; OSU aquaponics; Fritz Aquatics): optimal pH 7.5–8.5, significant decline <6.8, severe inhibition <6.5, ceases ~6.0. High-pH limb deliberately gentle (free-NH3 toxicity to NOB is handled by the separate K_NH3_inhib kernel; penalising it twice would wrongly slow hard alkaline tanks that cycle fast in practice). Set pH_activity_enabled = False to disable.

pH 6.0 6.5 7.0 7.5 8.5 9.0 9.5 10.0
µ multiplier 0.0 0.20 0.50 1.0 1.0 0.85 0.55 0.30

Hypoxia

Symbol Value Units Source / Rationale
O2 stress 6.0e-5 mol/L ~2 mg O2/L; aerobe stress threshold
O2 lethal 1.5e-5 mol/L ~0.5 mg O2/L
m_hypoxia,max 0.06 /h Aerobe sensitivity

Light suppression

Symbol Value Units Source / Rationale
K_light (inhibition) 500.0 µmol m⁻² s⁻¹ AOB/Nitrosomonas photoinhibition half-response (hyperbolic 1/(1+I/K)). 50 % inhibition at ~500 µmol; unaffected ≤15, ~11 % down at 60, tolerate ~200 (Merbt et al. 2012, FEMS Microbiol Lett 327:41; Vergara et al. 2016; algal-bacterial photobioreactor studies). NOB/comammox override tighter (their sections). Was 2.0 — implied 50 % inhibition at a near-dark 2 µmol (dimmer than a shaded substrate), leaving nitrifiers no oxic-lit niche and stalling planted-tank nitrite clearance for months.
Biofilm light attenuation 0.10 M=1 mature EPS light attenuation
Geometric light shield scale 0.90 Roughness-scaled light shelter
Pore-zone O2 source bulk O2 Pore-resident (pore_fraction) nitrifiers breathe bulk-water O2, not lumped anoxic PORE_O2 — they occupy the thin oxic sediment-surface microzone fed by the overlying water (Jensen et al. 1994 L&O 39:573; Risgaard-Petersen & Jensen 1997 L&O 42:529). Keeps the in-situ pore NO3/NO2 they produce (denitrifier feed) while preventing the pore fraction from suffocating.
PORE_FRACTION_SOIL_DEFAULT 0.6 Share of biomass placed in the soil pore zone (soil tanks; config.py auto-injection per class). AOB / comammox 0.6 — their NH4 substrate concentrates in the pore (Schramm 1996). NOB overrides to 0.2 (its section) — NO2 is a transient intermediate that is not pore-stable.
pore_oxic_cap_frac 0.10 Share of the pore-resident (pore_fraction) biomass that sits in the thin oxic cap and actually nitrifies; the anoxic remainder idles (only mortality booked). Oxic O₂ penetration into organic-rich freshwater sediment is ~1–4 mm (Revsbech et al. 1980; Jensen et al. 1994) of a ~40 mm bed → ~0.05–0.10; 0.10 = upper end since cap biomass concentrates areally at the interface. Bounds in-sediment nitrification to the oxic cap so the deep pore ammonia diffuses up as the new-tank spike instead of being intercepted in-pore (cycling-matrix F5-1/F5-2; audit §9.17). 1.0 = pre-fix (whole pore fraction active). Inert when pore_fraction = 0 / no pore.

Mortality & viral lysis

Symbol Value Units Source / Rationale
m_base 0.01/24 /h ~1%/day persistent guild
m_viral,max 0.005 /h Density-dependent lysis cap
K_viral 2e-5 mol/L Half-sat on biomass density
m_total,max 0.50 /h Hard cap
Death → suspended fraction 0.8 fraction Most planktonic mortality stays suspended
Surface death → settled fraction 0.9 fraction Surface-attached mortality mostly settles

Biofilm dynamics & predation protection

Symbol Value Units Source / Rationale
Settlement rate 0.002 /h Biofilm colonisation rate
Detachment rate 0.0002 /h 10× slower than settlement
Induction lag 48.0 h Enzyme-induction lag for fresh inoculum
Induction lag min factor 0.10 fraction Floor activity at t=0
Biofilm predation protection 0.90 fraction Schramm 1996 / Matz & Kjelleberg 2005 — 90% biomass unreachable to grazers at full biofilm maturity
Geometric predation shield scale 0.70 M=0 floor — calibrated against skeptic_overstocked_nano scenario
GRAZING_SUBSTRATE_REFUGE_SOIL 0.85 fraction Burial-refuge ceiling: max share of nitrifier biomass that can sit below the grazed surface skin (substrate interstitial biofilm + EPS basal layers), inaccessible to metazoan grazers (snails, shrimp, copepods, ostracods). Applied SYMMETRICALLY to AOB / NOB / comammox — they co-aggregate microns apart in the same nitrifying biofilm (Schramm et al. 1996 AEM 62:4641), so grazing exposure is guild-symmetric, unlike the kinetic pore_fraction. Scaled per-surface by benthic_fraction: the effective refuge on a surface is 0.85 × benthic_fraction, so sand/gravel floor (benthic_fraction 1.0) gets the full 0.85, bare glass walls (0.0) get none (only their EPS shelter), and leaves (~0.3) get partial credit — burial is only possible where there is floor substrate to bury into. Auto-injected by config.py: 0.85 in soil tanks, 0.0 bare-bottom. Scales the grazing access modifier only (species/access.py modifier_coeffs/effective_access); the self-mortality path (surface_protection) is unscaled because base/viral mortality reaches buried cells. Stacks multiplicatively with the M-dependent EPS shelter: total protection = r_eff + (1−r_eff)·P_biofilm. Without it, a maturing invertebrate community grazes all three nitrifier guilds — including NOB, the sole NO2 sink — to local extinction, freezing a spurious ~0.17 mg-N/L residual nitrite in established planted tanks; with it the mature tank reaches kit-undetectable NO2 (~0.05 mg-N/L), the surviving nitrification concentrated on the protected substrate surface.
GRAZING_SUBSTRATE_REFUGE_SAND 0.85 fraction Inert-substrate (no soil block) burial ceiling for an inert silica/quartz sand bed. Same physical burial credit as a soil tank's sand cap — fine grains pack tightly and most of the nitrifying biofilm sits in interstitial pore space / EPS basal layers below the grazed skin (same Schramm 1996/1999 depth-profile family as _SOIL). Auto-injected by config.py only when the scenario's top-level substrate_type == "sand" (the inert-substrate marker); legacy tanks that merely carry an incidental sand surface but no marker keep 0.0, so the feature is purely additive. Scaled per-surface by benthic_fraction (sand floor 1.0) exactly like _SOIL.
GRAZING_SUBSTRATE_REFUGE_GRAVEL 0.75 fraction Inert-substrate burial ceiling for an inert aquarium gravel bed. Lower than sand/soil (0.85): coarse gravel has larger interstices that snail radulae / shrimp mouthparts can reach into, so a smaller fraction of the nitrifier biofilm is truly unreachable. Auto-injected by config.py only when substrate_type == "gravel"; otherwise 0.0 (additive). Same per-benthic_fraction scaling as _SOIL/_SAND.

Starvation dormancy (attached biomass only)

A starved nitrifying biofilm does not die, it idles — and the engine used to model it as a chemostat population that washes out below the substrate concentration where growth pays for its upkeep. These four fields bend three loss terms toward a floor as substrate saturation falls, on surface-attached biomass only. They are gated by a Hill-2 on the substrate saturation factor X_fac = S/(K+S), so a fed tank is unaffected to within a few tenths of a percent and the whole mechanism is inert during cycling. Setting all three floors to 1.0 restores the previous behaviour exactly. See Starved Biofilters and Dormancy and cycling-matrix family F21.

Symbol Value Units Source / Rationale
starvation_K_activity 0.05 – (X_fac) Hill-2 half-point, anchored at the retentostat condition income ≈ upkeep rather than fitted. A fed AOB spends m_base (0.01/d) + maintenance (0.0005/h × 24 = 0.012/d) ≈ 0.022/d simply existing, against μ_max 0.50/d, so its growth stops paying its upkeep at X_fac ≈ 0.044. The same arithmetic gives 0.049 for NOB and 0.073 for comammox; one shared 0.05 is inside the rounding for all three. Hill exponent 2 matches the codebase's other threshold kernels (allelopathy, methanogenesis anoxia) and keeps the factor > 0.995 across the whole ammonia-spike regime.
starvation_maint_floor_frac 0.15 fraction μ→0 asymptote of the maintenance coefficient. Tappe et al. 1999 (AEM 65:2471) grew Nitrosomonas europaea and Nitrobacter winogradskyi in a retentostat — complete biomass retention, so μ is driven to ~0 with the cells alive — and measured a maintenance demand three- to eightfold lower than the same organisms' chemostat steady states imply. Maintenance is not a constant; it collapses when growth stops. 0.15 ≈ the 6.7× point, mid-to-deep in that range because the retentostat's own μ never quite reached zero. NOB overrides to 0.35 (its section).
starvation_mort_floor_frac 0.15 fraction Same asymptote for base mortality. Tappe et al. 1999 reported no significant cell death across their starvation periods, which argues for a floor at or below the maintenance one; held equal rather than claiming a resolution the data does not support. NOB overrides to 0.35.
starvation_viral_floor_frac 0.10 fraction Same asymptote for the density-dependent viral lysis term — and in this engine it is the term that decides the outcome. Decomposing the decay budget of a starved biofilm on the F21 rig, one term at a time: relieving maintenance and base mortality moved the AOB half-life 21 → 28 d; relieving viral lysis moved it 36 → 95 d. ~70 % of the loss was phage, not starvation. Two independent reasons a starved biofilm does not support it. (1) Nabergoj et al. 2018 (MicrobiologyOpen 7:e558): burst size rises linearly with host growth rate — 8 PFU/cell at the slow end to 89 at the fast end for T4 on E. coli K-12 — and below a threshold growth rate replication stops entirely; lytic yield is host-biosynthesis limited. The 0.10 floor is that paper's own dynamic range, 8/89 = 0.09. (2) Melo et al. 2020 (Viruses 12:1076): the biofilm EPS matrix is a physical barrier to phage penetration, with infected cells markedly rarer where the matrix is denser. Only the yield per encounter bends; K_viral still sets how lysis scales with standing density. NOB overrides to 0.23.
— attached only The relief is passed at the call site (attached=True on the surface calls, absent on the planktonic one), not carried as a species field, because the attached/suspended split is the mechanism. Batchelor et al. 1997 (AEM 63:2281): suspensions of N. europaea starved 42 d took 153 h to resume nitrite production (8.7 h unstarved), while biofilms starved 43.2 d resumed with no measurable lag at all. The planktonic pool keeps the full chemostat treatment and washes out as it should.
— no recovery lag Deliberately absent, and the literature is why. Batchelor's biofilms had no lag after six weeks; Bollmann et al. 2005 (AEM 71:1276) recovered Nitrosospira briensis's full ammonia-oxidising activity within 30–60 min of an ammonium pulse after up to two weeks of starvation (3 d starved → ~30 min; 7 d → ~50 min). The engine's instantaneous Monod response is already correct for a biofilm, so a resuscitation kernel would model a delay that is not there. Catabolism is untouched for the same reason: a starved biofilm oxidises whatever ammonia reaches it at the full per-cell rate.

Starvation dormancy (attached biomass only)

A starved nitrifying biofilm does not die, it idles. The engine used to model it as a chemostat population that washes out below the substrate concentration where growth pays for its upkeep, which is right for cells in suspension and wrong for the EPS-embedded biofilm that holds essentially all of a tank's nitrification. The fields below bend three loss terms toward a floor as substrate limitation deepens, on surface-attached biomass only, gated by a Hill-2 (exponent 2, matching the allelopathy and methanogenesis kernels). Setting all three floors to 1.0 restores the previous behaviour exactly, which is what the F21 falsification control does. See Starved Biofilters and Dormancy, cycling-matrix family F21, and internal_docs/planning/nitrifier_dormancy.md.

Symbol Value Units Source / Rationale
starvation_K_activity 0.012 – (substrate saturation) Hill-2 half-point on S/(K_substrate + S), evaluated on the zone's real concentration. For AOB this is bulk ammonia ≈ 0.0043 mg N/L. A calibration, and the first value was wrong in an instructive way. It was originally anchored at the retentostat condition income ≈ upkeep (0.05), which is circular: at plateau every population is at income = upkeep, so that anchor selects the mature-tank operating point instead of excluding it. Cycling-matrix F19 caught it — the relief engaged at the 0.02–0.08 mg N/L residual a stocked tank holds, roughly doubled standing stock across the entire load sweep, and inverted the family's load-monotonicity check (2 mg N/L/day left less ammonia standing than 1, because lower ammonia made survival cheaper, which grew the biofilter, which lowered ammonia). The replacement criterion is operational and re-testable: inert at the residual a stocked tank plateaus at (F19 measures 0.037–0.35 mg N/L across 0.5–4 mg N/L/day) and engaged at the residual a plant-dominated or unstocked tank holds (the beta run sits at 0.002–0.006 mg N/L). 0.012 puts the half-point an order of magnitude below the former. Shared across all three guilds; comammox's 50×-tighter K_substrate means the same saturation threshold reaches it only in water where AOB is long gone.
starvation_maint_floor_frac 0.15 fraction μ→0 asymptote of the maintenance coefficient. Tappe et al. 1999 (AEM 65:2471) grew Nitrosomonas europaea and Nitrobacter winogradskyi in a retentostat — complete biomass retention, so μ is driven to ~0 with the cells alive — and measured a maintenance demand three- to eightfold lower than the same organisms' chemostat steady states imply. Maintenance is not a constant; it collapses when growth stops. 0.15 ≈ the 6.7× point, mid-to-deep in that range because the retentostat's own μ never quite reached zero. NOB overrides to 0.35 (its section).
starvation_mort_floor_frac 0.15 fraction Same asymptote for base mortality. Tappe et al. 1999 reported no significant cell death across their starvation periods, which argues for a floor at or below the maintenance one; held equal rather than claiming a resolution the data does not support. NOB overrides to 0.35.
starvation_viral_floor_frac 0.10 fraction Same asymptote for the density-dependent viral lysis term, and in this engine it is the term that decides the outcome. Decomposing the decay budget of a starved biofilm on the F21 rig one term at a time: relieving maintenance and base mortality moved the AOB half-life 21 → 28 d; relieving viral lysis moved it 36 → 95 d. ~70 % of the loss was phage, not starvation. Two independent reasons a starved biofilm does not support it. (1) Nabergoj et al. 2018 (MicrobiologyOpen 7:e558): burst size rises linearly with host growth rate — 8 PFU/cell at the slow end to 89 at the fast end for T4 on E. coli K-12 — and below a threshold growth rate replication stops entirely; lytic yield is host-biosynthesis limited. The 0.10 floor is that paper's own dynamic range, 8/89 = 0.09. (2) Melo et al. 2020 (Viruses 12:1076): the biofilm EPS matrix is a physical barrier to phage penetration, with infected cells markedly rarer where the matrix is denser and mechanical disruption improving phage killing from 0.3 to ~2 orders of magnitude. Only the yield per encounter bends; K_viral still sets how lysis scales with standing density. NOB overrides to 0.23.
— attached only Passed at the call site (attached=True on the surface calls, absent on the planktonic one) rather than carried as a species field, because the attached/suspended split is the mechanism. Batchelor et al. 1997 (AEM 63:2281): suspensions of N. europaea starved 42 d took 153 h to resume nitrite production (8.7 h unstarved), while biofilms starved 43.2 d resumed with no measurable lag at all. The planktonic pool keeps the full chemostat treatment and washes out as it should.
STARVATION_SIGNAL_TAU_H 48 h Time constant of the low-pass the relief actually reads, carried as one non-mass ODE state slot per guild (the biofilm-maturity precedent, excluded from mass balance). d(sig)/dt = (S/(K+S) − sig)/τ, bounded in [0,1] by construction, seeded fully-fed at 1.0. Why filtered at all: read instantaneously, substrate saturation cannot tell a fed tank from a starved one. A tank fed once a day sits at 0.000 mg N/L for 22 hours out of 24 at every bioload — measured on the F19 rig, the relief factor at a day's mean is 0.90 while the mean of the factor over the same day is 0.26. That gap is the bolus-dosing Jensen trap arriving in a new place, and it engaged the relief across the whole F19 load sweep, roughly doubling standing stock and inverting the family's load-monotonicity (2 mg N/L/day left less ammonia standing than 1). It is a real modelling error and not only a rig artefact: dormancy is a transcriptional state, and Bollmann et al. 2005 watched amoA mRNA decline over days of starvation. A nitrifier does not power down because the fish has not eaten since breakfast. 48 h bridges the longest feeding interval a keeper plausibly runs while still engaging within a week of a genuine stoppage, an order of magnitude below the 21–34 d activity half-life Elawwad et al. 2013 measured, so it resolves the onset of starvation rather than the decay that follows.
— read off REAL substrate The signal tracks the zone's actual bulk concentration, not the X_fac the growth kernel computes, which carries the biofilm boundary-layer enrichment cache and the forced-convection relief. Those are perceptions of rate: _flux_apply still debits the real pool, and the kernel's substrate cap still limits oxidation to what that pool holds. The first cut read the perceived value and the mechanism was silently inert in exactly the tanks it was built for — a mature planted tank's enrichment cache scores a surface AOB at a perceived saturation of ≈ 0.22 off 0.002 mg N/L of bulk ammonia. Guarded by test_biofilm_enrichment_does_not_mask_starvation.
— regime coverage What the Hill-2 does across the concentrations a tank sees, in bulk NH₄-N against AOB's 0.35 mg N/L half-saturation. 4 mg/L (mid fishless-cycle spike) → 1.00; 0.25 mg/L (the "cycled" threshold) → 1.00; 0.08 mg/L → 1.00; 0.037 mg/L (F19's lightest-load plateau) → 0.99; 0.02 mg/L → 0.96; 0.010 mg/L → 0.87; 0.005 mg/L (plant-dominated tank) → 0.64; 0.002 mg/L → 0.31; 0 → 0.15. The whole cycling regime and the whole stocked-plateau regime are untouched, which is what protects the F1–F14 and F15–F19 calibrations; the relief lives entirely below the ammonia a bioload leaves standing.
— no recovery lag Deliberately absent, and the literature is why. Batchelor's biofilms had no lag after six weeks; Bollmann et al. 2005 (AEM 71:1276) recovered Nitrosospira briensis's full ammonia-oxidising activity within 30–60 min of an ammonium pulse after up to two weeks of starvation (3 d starved → ~30 min; 7 d → ~50 min). The engine's instantaneous Monod response is already correct for a biofilm, so a resuscitation kernel would model a delay that is not there. Catabolism is untouched for the same reason: a starved biofilm oxidises whatever ammonia reaches it at the full per-cell rate.

Recruitment / immigration floor

Symbol Value Units Source / Rationale
recruitment_N_mgL_per_h 1.0e-9 mg N / L / h Continuous tiny aerial deposition + water-change inoculation + biological vectoring into the planktonic pool, C and P added at species stoichiometry. ≈ 10 cells / L / h = 240 cells / L / day, sitting at the low (indoor) end of Bowers et al. 2013's measured 10²–10⁴ aerial cells / L of settled air / day. Hovanec et al. 1998 documented that sterile new freshwater aquaria establish functional nitrification within ~21 days from this background contamination alone. Defensive insurance against numerical extinction under transient hypoxia — negligible (~8.6e-6 mg N / L / year mass injection) when biomass is healthy; seeds recovery within days when a guild bottoms out.

AOB / ammonia oxidisers — divergent only

Nitrosomonas-class first-leg nitrifier (NH₄ + 1.5 O₂ → NO₂ + 2 H⁺). Refs: Prosser 1989, Ensign 1993, Wagner 2002, Martens-Habbena 2009, Könneke 2005, Arp & Stein 2003.

Substrate & stoichiometry

Symbol Value Units Source / Rationale
Substrate / Product NH₄ / NO₂ NH₄ + 1.5 O₂ → NO₂ + 2 H⁺
O₂:X 1.5 mol O₂ / mol N Half-reaction stoichiometry
TA:X −2.0 eq TA / mol N 2 H⁺ released
μ_max 0.50/24 /h Prosser 1989: Nitrosomonas doubling 33–56 h → ~0.5/day
K_substrate 2.5e-5 mol/L NH₄ ≈0.35 mg N/L. Martens-Habbena 2009; Könneke 2005 — suspended-cell kinetics, i.e. an intrinsic half-saturation, measured on cells with no diffusion boundary layer. The engine applies it unchanged to planktonic and attached pools, so a static surface here carries no boundary-layer penalty and mass_transfer_factor compresses the constant further on filter media. (Both this file and surfaces.py previously described 0.35 mg N/L as the apparent half-saturation. It is the intrinsic one, used as an apparent one — a distinction that matters if anyone ever derives m from mass-transfer theory, because the derivation needs the intrinsic value in the numerator and a boundary-layer term in the denominator.)
K_O2 1.0e-6 mol/L ≈0.03 mg O₂/L; AMO O₂-independent above ~1 mg/L (Hunik; Laanbroek & Gerards). ~13× more O₂-affine than NOB — the basis of low-DO nitrite accumulation. Override of base 3e-5 (which made AOB ~14% O₂-limited at 6 mg/L, collapsing the AOB/NOB asymmetry to ~2×)
BGE 0.08 mol C / mol NH₄ Prosser 1989

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Cu:C 2.0e-7 mol Cu / mol C AMO Cu-monooxygenase (Ensign 1993, Arp & Stein 2003)

NOB / nitrite oxidisers — divergent only

Nitrospira-leaning second-leg nitrifier (NO₂ → NO₃) — more pH- and O₂-sensitive than AOB, with both NH₃ and HNO₂ inhibition gates. Refs: Knowles & Wakeham 1978, Daims 2015, Schramm 1996, Anthonisen 1976, Vadivelu 2006/2007, Park & Bae 2009, Pollice 2002, Sin 2008.

Substrate & stoichiometry

Symbol Value Units Source / Rationale
Substrate / Product NO₂ / NO₃ Charge-conserving redox
O₂:X 0.5 mol O₂ / mol N Half-reaction
starvation_maint_floor_frac 0.35 fraction NOB idles less cheaply than AOB, and every measurement of the two side by side says so. Tappe et al. 1999 pulsed both after starvation: N. europaea was back to 50 % of maximum within an hour after 17 d, while N. winogradskyi showed no detectable oxygen consumption for ~5 h after 35 d and needed four nitrite pulses over ~80 h to reach the same 50 %. Their own conclusion is that N. europaea "more readily recovers from starvation", and that this is why nitrite appears in the environment when ammonia returns. Elawwad et al. 2013 (Environ. Technol. 34:945) put the same asymmetry on a reactor timescale: AOB activity half-lives 21–34 d and full recovery in under a week after 97 d idle, against NOB declining faster in every arm and needing ~7 weeks. 0.35 vs AOB's 0.15 makes NOB's starved endogenous cost ~2.3× AOB's, so a long-idle filter loses its nitrite oxidiser first and rebuilds it last — which is what turns "I stocked a tank that sat empty for months" into a nitrite blip rather than an ammonia spike. Measured on F21: going from 90 d to 270 d idle raises the nitrite peak 1.26 → 2.92 mg N/L while the ammonia peak stays at 2.27.
starvation_mort_floor_frac 0.35 fraction Same 2.3× as above, same sources.
starvation_viral_floor_frac 0.23 fraction Same 2.3× applied to the base 0.10. Nabergoj's law ties lytic yield to host growth rate, so a guild that shuts down less thoroughly stays correspondingly more lysable.
starvation_maint_floor_frac 0.35 fraction NOB idles less cheaply than AOB, and every measurement of the two side by side says so. Tappe et al. 1999 pulsed both after starvation: N. europaea was back to 50 % of maximum within an hour after 17 d, while N. winogradskyi showed no detectable oxygen consumption for ~5 h after 35 d and needed four nitrite pulses over ~80 h to reach the same 50 %. Their own conclusion is that N. europaea "more readily recovers from starvation", and that this is why nitrite appears in the environment when ammonia returns. Elawwad et al. 2013 (Environ. Technol. 34:945) put the same asymmetry on a reactor timescale: AOB activity half-lives 21–34 d and full recovery in under a week after 97 d idle, against NOB declining faster in every arm and needing ~7 weeks. 0.35 vs AOB's 0.15 makes NOB's starved endogenous cost ~2.3× AOB's, so a long-idle filter loses its nitrite oxidiser first and rebuilds it last — which is what turns "I stocked a tank that sat empty for months" into a nitrite blip rather than an ammonia spike.
starvation_mort_floor_frac 0.35 fraction Same 2.3× as above, same sources.
starvation_viral_floor_frac 0.23 fraction Same 2.3× applied to the base 0.10. Nabergoj's law ties lytic yield to host growth rate, so a guild that shuts down less thoroughly stays correspondingly more lysable.
TA:X 0.0 eq TA / mol N No proton release; biomass-N assimilation handles −1 separately
Uses biofilm NH₄ enrichment False No NO2 enrichment kernel in V1
PORE_FRACTION_SOIL_DEFAULT 0.2 Far lower than AOB/comammox (0.6). Pore-residency tracks where a guild's substrate concentrates. AOB's NH4 is concentrated in the substrate pore by mineralisation; NOB's NO2 is a transient intermediate that diffuses out of the well-mixed pore (PoreWaterDiffusion) into the bulk faster than pore-NOB can consume it — so a high pore_fraction left 60 % of NOB NO2-starved (perceived-NO2 Monod factor ~0.02 vs ~0.8 in the bulk) while bulk NO2 piled up to a spurious ~0.5–0.7 mg-N/L plateau in established planted tanks. The single-pore, well-mixed model can't reproduce microscale AOB↔NOB spatial coupling (Schramm 1996/1999), so NOB are placed where their substrate effectively ends up: the bulk / oxic-surface zone. With 0.2, established planted tanks reach the realistic ~0 NO2 (plant-dominated silent cycle) and shrimp persist robustly.
μ_max 0.45/24 /h Doubling ~37 h — set just below AOB (0.50/24) so NOB trails AOB as a K-strategist, which is what now sources the new-tank NO₂ spike. Slightly slower than pure-culture Nitrospira (Nowka/Daims/Spieck 2015: 12–32 h); the gap stands in for the establishment lag (lower seed + NO₂-substrate dependency) not otherwise modelled. Was 0.85/24 (faster than AOB) — backwards for an aquarium K-strategist, which forced the model to manufacture the spike via chronic free-NH₃ poisoning (see K_NH3,inhib). Aquarium NOB is Nitrospira, not Nitrobacter (Hovanec 1998). Calibrated to the audit §9.4 target: baseline NO₂ peak 2–5 mg N/L, high-pH ≈ baseline (no inversion)
K_substrate 1.5e-5 mol/L NO₂ ≈15 µM — measured Nitrospira affinity (Nowka 2015: Km 9–27 µM). Was 5e-6, tighter than the organism modelled; drained NO₂ too aggressively
BGE 0.02 mol C / mol NO₂ Knowles & Wakeham 1978; Wagner 2002 — ~4× lower than AOB (less free energy per electron)
K_O2 1.3e-5 mol/L ≈0.43 mg O₂/L (Hunik; Laanbroek & Gerards). ~13× less O₂-affine than AOB (1e-6) → low DO throttles NOB selectively → nitrite accumulation. Was 6e-5 (~2 mg/L), only ~2× the old AOB value
T_opt,growth 32.0 °C Slightly above AOB's 30 °C — pure-culture Nitrobacter optimum (~38) sits above Nitrosomonas (~35) (Grunditz & Dalhammar 2001), scaled to community optima. Keeps NOB pace with AOB through the optimum (no warm-water nitrite pile-up) and makes very hot tanks AOB- not NOB-limited. Only the above-optimum limb differs from base, so every ≤26 °C scenario is unchanged. (Making the cold NO2 tail mechanistic via a steeper NOB cold falloff is deferred — it would shift the calibrated 18 °C run; today the cold tail comes from the establishment lag)
T_max,growth 49.0 °C Growth → 0; same ceiling as AOB

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 4.0e-5 mol Fe / mol C NXR Fe-S + ETC
Mo:C 5.0e-8 mol Mo / mol C NXR molybdopterin (~5× anchor)
Cu:C 5.0e-8 mol Cu / mol C Universal anchor (no AMO)

Inhibition

Symbol Value Units Source / Rationale
K_NH3,inhib 5.0e-5 mol/L ≈0.7 mg NH3-N/L; Anthonisen onset band. Was 5e-6 (Vadivelu enriched-culture Ki) — over-fired at hobby doses (suppressed NOB ~52% at baseline, ~82% at pH 8.5), manufacturing the NO2 spike via chronic FA poisoning and inverting high-pH tanks. Spike now comes from establishment lag + Nitrospira affinity; FA only bites at genuinely high free ammonia
K_HNO2,inhib 7.0e-7 mol/L ≈0.01 mg HNO2-N/L (Vadivelu 2007; Park & Bae 2009) — left as-is; free nitrous acid genuinely is a sharp NOB inhibitor (the "keep NO2-N < 5 mg/L" self-stall rule)
K_light (inhibition) 50.0 µmol m⁻² s⁻¹ NOB are the most light-sensitive nitrifying guild — ~80 % suppressed at ~200 µmol where AOB tolerate (Vergara et al. 2016, basis of light-driven partial nitritation; Guerrero & Jones 1996, Nitrobacter ≫ Nitrosomonas sensitivity). ~10× tighter than the AOB base (500). At a shaded substrate surface (≈3–13 µmol) NOB still run ~79–94 % so the NO₂→NO₃ step establishes in the oxic biofilm, while bright water-column light strongly throttles the lit/planktonic fraction (preserving "NO2 lingers under high light").

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 6.5 / 9.0 Tightened vs base — NOB more pH-sensitive
pH lethal (low / high) 5.5 / 10.0 Tightened
m_pH,max 0.04 /h Elevated vs base

Hypoxia

Symbol Value Units Source / Rationale
O2 stress 9.0e-5 mol/L Tightened vs base
O2 lethal 3.0e-5 mol/L Tightened
m_hypoxia,max 0.02 /h Elevated NOB O2 sensitivity but recoverable on a one-day timescale. Schramm 1996 micro-electrode work shows NOB in mature biofilm interiors tolerate brief hypoxia via micro-aggregate O2 gradients. Lowered from 0.08 (May 2026) after the prior value caused total NOB extinction during transient bulk-O2 dips in the Walstad 365d diagnostic; with no recovery pathway from sub-detection biomass, NO2 plateaued indefinitely. 0.02 = 48%/d max wipeout at full anoxia, still aggressive but allows recovery.

Comammox Nitrospira — divergent only

K-strategist single-cell complete oxidation (NH₄ → NO₃ in one cell); dominates mature aquarium biofilms. Refs: Daims 2015, van Kessel 2015, Kits 2017, Bartelme 2017, Sauder 2017, Sakoula 2021.

Substrate & stoichiometry

Symbol Value Units Source / Rationale
Substrate / Product NH₄ / NO₃ Single-cell complete oxidation
O₂:X 2.0 mol O₂ / mol N Sum of AMO+NXR
TA:X −2.0 eq TA / mol N Only NH₄→NO₂ leg releases H⁺
μ_max 0.30/24 /h Conservative ~55 h doubling; Kits 2017 reports ~24 h for N. inopinata, community estimates slower (Bartelme 2017)
K_substrate 5.0e-7 mol/L NH₄ Conservative community value (~50× tighter than AOB); Kits 2017 reports 6.3e-8 in pure culture — tuned upward to avoid day-1 dominance
K_O2 4.0e-5 mol/L Kits 2017 measured ~1 µM for N. inopinata; intermediate AOB/NOB
BGE 0.10 mol C / mol NH₄ Thermodynamic ceiling: captures both half-reactions; ≈ AOB+NOB sum (0.08+0.02)
starvation_*_floor_frac (base) fraction Deliberately not overridden — comammox takes the base class's AOB-strength floors, not a third value. Its famine advantage is already spent on K_substrate above: the whole comammox starvation literature is affinity literature (Kits 2017's 6.3e-8 mol/L; the oligotrophic-habitat surveys), and because the dormancy relief reads off substrate saturation, a 50×-tighter K already means comammox is barely starving in the water where AOB has stopped growing — a saturation of ≈ 0.4 against AOB's 0.014 at 0.005 mg N/L. A lower floor on top would count one adaptation twice, and would be invention: nobody has run the retentostat on a comammox. The beta-tester run that motivated the epic showed the model already had this right — comammox was the last guild standing, outliving AOB by ~60 d on affinity alone.
starvation_*_floor_frac (base) fraction Deliberately not overridden — comammox takes the base class's AOB-strength floors, not a third value. Its famine advantage is already spent on K_substrate above: the whole comammox starvation literature is affinity literature (Kits 2017's 6.3e-8 mol/L; the oligotrophic-habitat surveys), and because the dormancy relief reads off substrate saturation, a 50×-tighter K already means comammox is barely starving in the water where AOB has stopped growing — X_fac ≈ 0.4 against AOB's 0.014 at 0.005 mg N/L. A lower floor on top would count one adaptation twice, and would be invention: nobody has run the retentostat on a comammox. The beta-tester run that motivated the epic showed the model already had this right — comammox was the last guild standing, outliving AOB by ~60 d on affinity alone.

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Mo:C 4.0e-8 mol Mo / mol C NXR molybdopterin (near NOB level)
Cu:C 1.5e-7 mol Cu / mol C AMO Cu-monooxygenase, between AOB (2e-7) and NOB anchor

Inhibition

Symbol Value Units Source / Rationale
K_NH3,inhib 2.0e-6 mol/L Sakoula 2021 — comammox more NH3-sensitive than AOB/NOB; ~3× tighter than NOB. Mechanism: dual AMO+NXR sites compound inhibition
K_HNO2,inhib 0.0 mol/L Sentinel — substrate is NH4, HNO2 branch self-skips
K_light (inhibition) 300.0 µmol m⁻² s⁻¹ Between AOB (500) and NOB (50). Yamamoto et al. 2022 (PMC9797979): >50 % photoinhibition of N. inopinata only under acute bright/direct sun (500–800 µmol), inhibition confined to <550 nm; but the Nitrospira lineage is chronically more light-sensitive than Nitrosomonas-type AOB. Shaded substrate (≈3–13 µmol) leaves comammox near-uninhibited so it holds the mature-tank niche; bright light throttles the lit fraction

Heterotrophic bacteria

Single-pool decomposer guild — labile / refractory DOM split BGE, settled-detritus access scaling, sediment-anoxia gate, viral-shunt routing of lysed C to DOM. Refs: Azam 1983, Cole 1988, Carlson & Ducklow 1996, del Giorgio & Cole 1998, Kirchman 2012, Flemming 2016, Fuhrman 1999, Weinbauer 2004, Wainright 1990, Fenchel & Finlay 1995.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Water-change removal fraction 0.40 fraction Flemming 2016: 40–80% biofilm-associated; only free-living ~40% removed by water change
Body size 0.0001 cm ~1 µm
μ_max (substrate uptake) 0.25 /h Kirchman 2012: doubling 0.5–3 h → 0.2–1.4/h; 0.25/h mixed community
K_DOM (labile) 8e-6 mol C / L Labile DOM ~0.096 mg C/L; Carlson & Ducklow 1996, Kirchman 2012
K_DOM (refractory) 5e-7 mol C / L Refractory ~0.006 mg C/L; tighter due to enzyme specialisation
K_detritus (suspended) 2e-5 mol C / L Suspended detritus ~0.24 mg C/L
K_detritus (settled) 4e-5 mol C / L Settled higher K due to lower surface:volume ratio (Wainright 1990)
DOM (labile) preference 2.0 weight Labile prioritised 2× over suspended detritus
DOM (refractory) preference 0.1 weight Refractory ~10× less preferred (humic enzymes)
Settled-detritus preference 0.3 weight Settled ~3× less preferred (access limitation)
Settled-detritus access fraction 0.3 fraction Only benthic-associated fraction accesses sediment
BGE (labile) 0.28 fraction Carlson & Ducklow 1996; del Giorgio & Cole 1998 — 15–40% labile BGE
BGE (refractory) 0.08 fraction Refractory BGE much lower (enzyme overhead)
K_O2 (growth) 3e-5 mol/L ~1 mg/L; del Giorgio & Cole 1998, Fenchel & Finlay 1995 — high O2 affinity

C:N-driven N immobilisation — when substrate C:N exceeds bacterial C:N (~5), the shortfall is drawn from bulk DIN; if even bulk DIN is insufficient, growth becomes C-limited and unbuildable C is respired. Floater detritus (C:N ≈ 20–30) becomes a transient N sink — the canonical Walstad "tank stripping" mechanism in mature planted systems.

Symbol Value Units Source / Rationale
K_NH4,immob 3.0e-6 mol/L ~42 µg N/L; Kirchman 2012 Ch. 7, Vrede et al. 2002 AEM 68:2965 — aquatic heterotroph NH4 affinity 1–5 µM
K_NO3,immob 2.0e-5 mol/L ~280 µg N/L; ~7× K_NH4 — assimilatory NO3 reductase is energetically costly (Antia et al. 1991 Phycologia 30:1)
NO3 immobilisation preference 0.4 weight NH4 preferred over NO3 even when bulk concentrations equal
max_frac_immob_per_h 0.20 fraction Per-step pool-fraction safety cap; same pattern as nitrifier cap_n clamp

Sediment anoxia gate

Symbol Value Units Source / Rationale
Sediment type "sand" Default; anoxia gate driver
Sediment area 0.0 cm² Auto-injected from scenario
D_O2 (water) 7.2 cm²/h O₂ diffusivity in water
k_sediment,resp 0.02 /h Sediment respiration rate constant
Max O₂ penetration 10.0 cm Cap on O2 penetration depth
Q10,sediment resp 2.0 Standard

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Bacterial C:N
N:P 10.0 mol / mol Bacteria P-rich (lower N:P than Redfield)

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0008 mol O₂ / mol C / h Low maintenance
K_O2 (respiration) 1e-5 mol/L ~0.3 mg/L

Thermal envelope

Symbol Value Units Source / Rationale
T_ref T_REF_C (25) °C Standard
Q10,uptake 2.2 Strong temperature dependence
Q10,resp 2.0 Standard
Q10,mort 1.6 Standard
T_stress (low / high) 5.0 / 35.0 °C Wide tolerance — mixed community
T_lethal (low / high) 0.0 / 45.0 °C Wide
m_thermal,max 0.02 /h Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.0 Wide
pH lethal (low / high) 4.5 / 10.0 Wide
m_pH,max 0.02 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 1.0 PSU Freshwater
σ_S 8.0 PSU
S_stress (low / high) 0.0 / 10.0 PSU Freshwater band
S_lethal (low / high) 0.0 / 25.0 PSU
m_salinity,max 0.10 /h Standard

Hypoxia

Symbol Value Units Source / Rationale
O2 stress 3e-5 mol/L ~1 mg/L — facultative anaerobe tolerance
O2 lethal 5e-6 mol/L ~0.15 mg/L
m_hypoxia,max 0.04 /h Lower than aerobes

Mortality & viral lysis

Symbol Value Units Source / Rationale
m_base 0.03/24 /h ~3%/day
m_viral,max 0.02 /h Fuhrman 1999, Weinbauer 2004 — phages 10–50% mortality; max ~48%/day at saturating density
K_viral 2e-5 mol/L ~0.24 mg C/L half-sat
m_total,max 0.40 /h Hard cap
Death → DOM fraction 0.80 fraction Fuhrman 1999 — 60–95% lysed bacterial C → DOM; 80% central estimate
Death → suspended fraction 0.50 fraction Of detritus remainder, half suspended

Predation protection

Symbol Value Units Source / Rationale
Biofilm predation protection 0.50 fraction Flemming 2016 — 60–80% embedded; conservative 0.50 for lumped pool
Grazing density refugium (K, water column) 1.0e-5 mol C / L
= 6.0 × 10⁶ cells/mL
= 0.12 mg C/L
= 0.028 mg N/L
Food-type-level, set in interactions.yaml on all 11 grazers' bacteria entry, and applied to the aggregate bacteria-category density (so it also shelters AOB / NOB / comammox / denitrifier). This is the water-column half of the half-saturation, and the whole of it only in a tank with no colonisable surface — see the row below. Pinned to the observed order of magnitude by two independent lines: eutrophic Mazurian lakes hold 4.76 ± 2.08 × 10⁶ bacteria/mL (Kalinowska et al. 2013, Aquatic Biosystems 9:9) ⇒ 4.5e-6 – 1.1e-5 mol C/L at ~20 fg C/cell; and flagellate isolates could not depress prey below 1,700–7,500 cells/µL ⇒ 2.8e-6 – 1.25e-5 mol C/L (Tophøj et al. 2018, PLOS ONE 13(4):e0195935 — supporting only, a marine batch culture of one bacterium with an inducible aggregation defence). Same order as K_viral above. Calibrated, not cited
Grazing density refugium (K, biofilm) 1.0e-6 mol C / cm²
= 6.0 × 10⁸ cells/cm²
of roughness-weighted area
(= 3.9 × 10⁸ cells/cm² of the beta tank's actual surface)
Added Aug 2026. The biofilm half: K = K_water + K_biofilm × Σ(area·roughness)/V (species/access.py::effective_refugia_K). Anchored on the measured biofilm band for media, 10⁷–10⁹ cells/cm², which is the compartment the lumped pool's equilibrium actually sits in — the model's own steady state for the beta tank is 9.4 × 10⁸ cells/cm², so the refuge is ~2.4× below the stock it shelters. Weighted by roughness rather than raw area because the refuge is shelter, and roughness is already this engine's shelter proxy (it scales the geometric M=0 floor in surface_protection): bare glass 0.05 contributes almost nothing, porous foam / sintered ceramic 0.95 nearly its full area. Effect on K: unfiltered 60 L tank ×2.7, same tank with a sponge filter ×18.5, the 34.7 L beta tank ×23.8. Calibrated within a cited band, not cited — and not a gradient: at half this value the 2-leaf beta arm's bacteria cannot keep up with their carbon supply and labile DOC integrates to 18 mg C/L, while at this value the same pool sits flat at 1.0. See lumped vs per-surface bacteria §"What compartment is this number in?"
Grazing density refugium (min_frac) 0.08 fraction Residual access at vanishing density. Calibrated, no literature value exists. Near-inert at established standing crop (~10% clearance reduction at 8e-5 mol C/L) and a strong brake during collapse (~90% at 1.4e-7). Uniform across all 11 grazers deliberately — one calibrated number beats eleven invented ones. Added Aug 2026: bacteria was the only major food type with no refugium (0/11 entries vs 11/11 for surface_algae), so grazers cleared bacteria at full access all the way to extinction and the labile-DOC sink went with them. See labile DOM accumulation
(unit conversions for the two rows above) Bacterial C:N 5.0 mol/mol (cn_ratio), cell carbon ~20 fg C (literature 5–30; the order of magnitude survives the range). mg N/L → mol C/L: × 3.571e-4. mol C/L → cells/mL: × 6.0e11. cells/mL → cells/cm²: × 1000·V_L/A_cm². Quote a bacterial density in the compartment's own units or it cannot be checked against anything
Geometric predation shield scale 0.30 Lower than nitrifier (0.70) because HB is partly planktonic

Sediment anaerobe base

Shared base for IronReducer / SulfateReducer / Methanogen (and DNRA) — pore-resident obligate anaerobes. Hypoxia kernel disabled; sentinel ACCEPTOR:C / TA:C zeros are overridden per subclass to encode the ladder-position stoichiometry. Refs: Lovley & Phillips 1988, Conrad 1999, Heijnen & Roels 1981, Whiticar 1999.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Water-change removal fraction 0.40 fraction Matches denitrifier — pore-bound stays through exchange
Body size 0.0001 cm ~1 µm
μ_max (substrate uptake) 0.10 /h Base default; subclasses override
K_DOM 1.0e-5 mol C / L Half-sat on pore DOM
K_acceptor 1.0e-5 mol Default acceptor half-sat; subclasses override
BGE 0.10 fraction Anaerobic BGE — ~30% of NO3 BGE (Heijnen & Roels 1981)
Acceptor:C (sentinel) 0.0 mol / mol Subclasses override
TA:C (sentinel) 0.0 eq / mol Subclasses override
K_O2 (anoxia switch) 1.0e-5 mol/L Hill² anoxia switch; matches abiotic kernels

Sediment binding

Symbol Value Units Source / Rationale
Has soil substrate False Auto-injected per scenario
Soil anoxia factor 0.95 fraction Floor for soil pore zone — genuinely anoxic buried bulk
Sediment type "sand" Auto-injected
Sediment area 0.0 cm² Auto-injected

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Bacterial C:N
N:P 10.0 mol / mol Bacterial N:P

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0004 /h Anaerobic maintenance — runs on the catabolic acceptor

Thermal envelope

Symbol Value Units Source / Rationale
T_ref T_REF_C (25) °C Standard
Q10,uptake 2.5 Anaerobe sensitivity
Q10,resp 2.0 Standard
Q10,mort 1.6 Standard
T_stress (low / high) 5.0 / 35.0 °C Wide tolerance
T_lethal (low / high) 0.0 / 45.0 °C Wide
m_thermal,max 0.02 /h Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 5.5 / 9.0 Wide
pH lethal (low / high) 4.5 / 10.0 Wide
m_pH,max 0.02 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 1.0 PSU Freshwater V1
σ_S 8.0 PSU
S_stress (low / high) 0.0 / 10.0 PSU Freshwater band
S_lethal (low / high) 0.0 / 25.0 PSU
m_salinity,max 0.10 /h Standard

Hypoxia (disabled)

Symbol Value Units Source / Rationale
O2 stress 0.0 mol/L Sentinel — obligate anaerobes; hypoxia kernel disabled
O2 lethal 0.0 mol/L Sentinel
m_hypoxia,max 0.0 /h Disabled

Mortality & viral lysis

Symbol Value Units Source / Rationale
m_base 0.025/24 /h ~2.5%/day persistent guild
m_viral,max 0.012 /h Phage mortality cap
K_viral 2e-5 mol/L Standard half-sat
m_total,max 0.40 /h Hard cap
Death → DOM fraction 0.40 fraction Lower than HB (0.80) — pore EPS retains lysate
Death → suspended fraction 0.20 fraction Mostly settled; cells lyse in place

Predation protection

Symbol Value Units Source / Rationale
Biofilm predation protection 0.50 fraction EPS-embedded sediment community
Geometric predation shield scale 0.50 Higher than HB (0.30) — pore-obligate, no planktonic fraction

Denitrifier

Facultative anaerobe owning the NO₃ → N₂ flux — standalone Species (not a SedimentAnaerobeBase subclass), reads bulk + 50% pore NO₃, hypoxia kernel disabled. Refs: Seitzinger 1988, Tiedje 1988, Heijnen & Roels 1981, Korner & Zumft 1989, Zumft 1997, Carlson & Ducklow 1996, Nielsen 1992.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Water-change removal fraction 0.40 fraction Pore-bound; matches HB
Body size 0.0001 cm ~1 µm
μ_max (substrate uptake) 0.18 /h Korner & Zumft 1989 — Pseudomonas anaerobic doubling 3–6 h ≈ 0.12–0.23/h midpoint; slightly slower than HB aerobic 0.25/h
K_DOM 8e-6 mol C / L Matches HB labile DOM
K_detritus (settled) 2e-5 mol C / L Tighter than HB (no spatial access penalty — denitrifiers ARE the sediment community)
DOM (labile) preference 1.0 weight Equal weight on DOM and settled detritus
Settled-detritus preference 1.0 weight
K_NO3 5.0e-5 mol/L Seitzinger 1988 — sediment denitrifiers 10–100 µM; midpoint matches abiotic kernel
Pore-NO3 access fraction 0.5 fraction Nielsen 1992 coupled nit-denit; matches retired abiotic kernel
BGE 0.30 fraction Heijnen & Roels 1981 — NO3 anaerobic BGE ~70% of aerobic ATP per electron; close to HB labile 0.28
NO₃:C 0.8 mol / mol Seitzinger 1988 — 5 CH2O + 4 NO3 → 2 N2 + 5 CO2
N₂:NO₃ 0.5 mol / mol Stoichiometric
TA:NO₃ 1.0 eq / mol +1 TA per NO3 (4 H⁺ consumed per 4 NO3)

Sediment binding

Symbol Value Units Source / Rationale
Has soil substrate False Auto-injected
Soil anoxia factor 0.95 fraction Floor — buried soil pore zone genuinely anoxic
Sediment type "sand" Auto-injected
Sediment area 0.0 cm² Auto-injected
D_O2 (water) 7.2 cm²/h Standard
k_sediment,resp 0.02 /h Standard
Max O₂ penetration 10.0 cm Standard
Q10,sediment resp 2.0 Standard

Stoichiometry

Symbol Value Units Source / Rationale
C:N 5.0 mol / mol Bacterial
N:P 10.0 mol / mol Bacterial

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 1.0e-4 mol Fe / mol C NarG/NirS/NorB heme + Fe-S — 2× AOB anchor
Mo:C 5.0e-8 mol Mo / mol C NarG molybdopterin (matches NOB)
Cu:C 4.0e-7 mol Cu / mol C NosZ Cu-Z cluster (Zumft 1997) — distinctive complete denitrifier

Respiration & thermal envelope

Symbol Value Units Source / Rationale
R_maint 0.0006 mol O₂ / mol C / h Slightly below HB
K_O2 (respiration) 1e-5 mol/L High maintenance O2 affinity
Q10,uptake 2.5 Anaerobe sensitivity
T / pH / salinity bands (5/35, 0/45) °C; (5.5/9.0, 4.5/10) pH; freshwater Match SedimentAnaerobeBase

Hypoxia (disabled)

Symbol Value Units Source / Rationale
O2 stress / lethal / m_hypoxia,max 0.0 / 0.0 / 0.0 Hypoxia DISABLED — denitrifiers thrive in anoxia

Mortality & viral lysis

Symbol Value Units Source / Rationale
m_base 0.025/24 /h ~2.5%/day
m_viral,max 0.015 /h Phage parameterisation
K_viral 2e-5 mol/L Standard
m_total,max 0.40 /h Hard cap
Death → DOM fraction 0.40 fraction Lower than HB — pore EPS retention
Death → suspended fraction 0.20 fraction Mostly settled

Predation protection

Symbol Value Units Source / Rationale
Biofilm predation protection 0.50 fraction EPS-embedded
Geometric predation shield scale 0.50 Pore-resident, no planktonic dilution

DNRA — divergent only

Peer of denitrifier on the NO₃ rung — reduces NO₃ → NH₄ instead of N₂; niche partition emergent from per-NO₃ stoichiometry (DNRA more electron-efficient at high C, lower acceptor demand). Refs: Tiedje 1988, Burgin & Hamilton 2007, Kraft 2011, van den Berg 2015.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Acceptor:C 0.5 mol NO₃ / mol C 2 CH₂O + NO3 + 2 H⁺ → NH4 + 2 CO2; more electron-efficient than denitrifier (0.8)
TA:C 1.0 eq TA / mol C +1 TA per mol C (2 H⁺ per 2 mol C). Chemically correct +2 TA per NO3 (retired abiotic kernel emitted +3)
μ_max (substrate uptake) 0.10 /h van den Berg 2015 — fermentative DNRA genera slower than denitrifier (0.18); kinetic edge denitrifier exploits at high NO3
K_DOM 8e-6 mol C / L Matches denitrifier — shared substrate channel
K_NO3 3.0e-5 mol/L Tiedje 1988, Kraft 2011 — DNRA tighter NO3 affinity than denitrifiers; matches retired abiotic kernel
Pore-NO3 access fraction 0.5 fraction Nielsen 1992 coupled nit-denit
BGE 0.25 fraction van den Berg 2015 — comparable to denitrifier under acetate excess; slightly below 0.30 to reflect fermentative overhead

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 1.0e-4 mol Fe / mol C Nrf 5×heme + NapB c-type heme + Fe-S
Mo:C 5.0e-8 mol Mo / mol C NapA molybdopterin
Cu:C 2.0e-7 mol Cu / mol C Universal anchor — no NosZ Cu-Z

Iron reducer — divergent only

Geobacter-style dissimilatory Fe(III) reducer — third rung of the ladder; releases Fe-bound P as a side effect. Refs: Lovley & Phillips 1988, Methé 2003, Reguera 2005.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Acceptor:C 4.0 mol Fe(III) / mol C 4 Fe(OH)3 + CH2O → 4 Fe²⁺ + CO2
TA:C 8.0 eq TA / mol C +2 TA per Fe × 4 Fe = +8
μ_max (substrate uptake) 0.12 /h Lovley/Methé 2003 — Geobacter sulfurreducens doubling 6–10 h ~0.1/h; slightly slower than denitrifier (Fe(III) yields ~50% of NO3 energy)
K_DOM 1.0e-5 mol C / L Standard pore DOM half-sat
K_acceptor 1.0e-5 mol Fe-oxide Saturated in young tanks; matters once 99% reservoir consumed
BGE 0.10 fraction ~30% of NO3 BGE

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 1.5e-4 mol Fe / mol C OmcS/OmcB/OmcZ c-type cytochrome nanowires (Reguera 2005) — 3× anchor

Ladder inhibition & Fe-P release

Symbol Value Units Source / Rationale
K_NO3,inhib 5.0e-6 mol/L Matches methanogenesis/SR ladder gates — uniform NO3-rung threshold
Adsorbed P (Fe-bound) fraction 1.0 fraction Auto-injected from soil preset (walstad 0.60, aquasoil 0.70); default = bare-bottom / fully Fe-mediated

Sulfate reducer — divergent only

Desulfovibrio analog — fourth rung; suppressed by NO₃ above and reducible Fe(III) loading (pore-concentration basis). Refs: Canfield 1991, Heidelberg 2004, Rabus 2015, Berner 1980, Roden 2003.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Acceptor:C 0.5 mol SO₄ / mol C SO4 + 2 CH2O → HS + 2 HCO3 + H⁺
TA:C −0.5 eq TA / mol C One H⁺ released per 2 mol C
μ_max (substrate uptake) 0.06 /h Canfield 1991 freshwater rates ~0.05/h pure culture; calibrated against abiotic kernel baseline
K_DOM 1.0e-5 mol C / L Standard pore DOM
K_acceptor (pore SO₄) 5.0e-6 mol/L pore Pore SO4 half-sat (saturates above ~1e-4 mol in tap-water tanks)
BGE 0.07 fraction Heijnen & Roels 1981 — ~25% of NO3 BGE

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 1.0e-4 mol Fe / mol C DsrAB siroheme + [4Fe-4S]; APS reductase Fe-S
Mo:C 5.0e-8 mol Mo / mol C Matches denitrifier/NOB
Ni:C 5.0e-7 mol Ni / mol C [NiFe]-hydrogenase distinctive — 5× anchor
S:C 6.0e-3 mol S / mol C Cysteine-rich + Fe-S clusters; slightly above anchor

Ladder inhibition

Symbol Value Units Source / Rationale
K_NO3,inhib 5.0e-6 mol/L Matches ladder gates
K_oxide,inhib (pore) 0.05 mol/L pore Berner 1980, Roden 2003 — SR onset in lake/marsh sediments at pore Fe(III) ~50–100 µmol/cm³; half-strength at ~7% fresh loading, full at ~50% depletion. Pore-concentration basis (not mol stock) — scale-invariant

Methanogen — divergent only

Acetoclastic Methanosaeta/Methanosarcina — bottom rung of the ladder; stronger T-sensitivity than other anaerobes (Q10 ≈ 4). Refs: Conrad 1999, Whiticar 1999, Thauer 2008, Bastviken 2004.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Acceptor:C 0.5 mol CH₄ / mol C 2 CH2O → CH4 + CO2 disproportionation
TA:C 0.0 eq TA / mol C Acid-base balanced at C step
μ_max (substrate uptake) 0.03 /h Bastviken 2004 freshwater rates ~0.02–0.04/h; Methanosaeta doubling 24–48 h
K_DOM 1.0e-5 mol C / L Standard pore DOM
BGE 0.04 fraction ~13% of NO3 BGE — bottom of ladder
Q10,uptake 4.0 Bastviken 2004 lake sediment Q10 ≈ 4 — methanogens more T-sensitive than other anaerobes

Trace-metal:C overrides

Symbol Value Units Source / Rationale
Fe:C 1.0e-4 mol Fe / mol C F430 + [4Fe-4S] in MCR; less Fe-rich than Geobacter
Ni:C 5.0e-7 mol Ni / mol C F430 cofactor in MCR — distinctive (5× anchor)
Co:C 5.0e-8 mol Co / mol C Cobamides drive methyl-transfer — 10× anchor; distinctive methanogen signature

Ladder inhibition

Symbol Value Units Source / Rationale
K_NO3,inhib 5.0e-6 mol/L Matches ladder gates
K_pore SO4,inhib 1.0e-5 mol/L Matches retired abiotic methanogenesis kernel default

Aquatic fungi

Hyphomycetes / chytrids — refractory-specialist decomposers that condition leaf litter and drive the fungal→bacterial succession. Cool-T competitive advantage (T_ref=20°C, below bacteria's 25°C). Refs: Bärlocher 1992, Suberkropp 1991/1998, Gulis & Suberkropp 2003, Gessner 1994/1999/2007, Krauss 2011, Kirk & Farrell 1987, Sinsabaugh 2002, Mille-Lindblom 2006, Gooday 1990, Six 2006, Von Lützow 2006, Reddy & DeLaune 2008, Bosatta & Agren 1999, Duarte 2016, Chauvet & Suberkropp 1998.

Growth & substrate kinetics

Symbol Value Units Source / Rationale
Water-change removal fraction 0.05 fraction Bärlocher 1992 — >95% hyphal biomass embedded in substrate; only zoospores/fragments removed
Body size 0.001 cm ~10 µm hyphal diameter
μ_max (substrate uptake) 0.035 /h Suberkropp 1998: hyphomycete growth 0.05–0.20/day; Gulis & Suberkropp 2003: 0.03–0.12/day → ~0.84/day uptake supports ~0.1/day growth at 12% BGE
K_DOM (refractory) 3e-7 mol C / L Sinsabaugh 2002; Krauss 2011 — high affinity for refractory (~0.004 mg C/L) via cellulases/laccases
K_detritus (settled) 1e-5 mol C / L Settled detritus — physical access limitation
K_soil OM (refractory) 5e-4 mol C / L Bosatta & Agren 1999; Sinsabaugh 2002 — particulate K 1–2 orders above dissolved (physical inaccessibility bottleneck). Gradual deceleration near pool exhaustion
K_DOM (labile) 5e-5 mol C / L Low affinity for labile (bacteria outcompete)
DOM (refractory) preference 3.0 weight Gessner 2007 — fungi dominate lignocellulose
Settled-detritus preference 2.0 weight Bärlocher 1992 — hyphal colonisation of fresh detritus
Soil OM (refractory) preference 0.8 weight Suberkropp 1998 — humified soil OM 5–10× lower fungal growth than fresh material
DOM (labile) preference 0.05 weight Bacteria dominate labile substrates
α (recalcitrance) 0.0 Disabled by default — evolving K_soil modifier
β (recalcitrance) 2.5 Power exponent on depletion fraction when α>0
Initial soil-OM (refractory) 0.0 mol Set by scenario init
Settled-detritus access fraction 0.7 fraction Bärlocher 1992 — fungi primarily benthic
Soil-OM access fraction 0.15 fraction Von Lützow 2006; Kirk & Farrell 1987; Reddy & DeLaune 2008 — peroxidases need O2, restricting decomposition to aerobic top 2–5 mm of 4 cm substrate ≈ 5–12%, plus root-channel access → ~15%
BGE (refractory) 0.15 fraction Suberkropp 1998: 5–15% on leaf litter; Gulis & Suberkropp 2003: 10–18%
BGE (labile) 0.20 fraction Secondary niche
Conditioning fraction 0.20 fraction Gessner 1999; Gulis & Suberkropp 2003 — enzymatic conditioning fraction ~10–20% of fungal-processed C (excluding abiotic leaching)
K_O2 (growth) 3e-5 mol/L Kirk & Farrell 1987 — peroxidases function at 0.5–1.0 mg/L; ~1 mg/L gives O2_fac≈0.89 at 8 mg/L

Space competition & bacterial interference

Symbol Value Units Source / Rationale
Space carrying capacity 0.005 mol / mol Gessner & Chauvet 1994; Suberkropp 1998; Six 2006 — upper bound 5 mg fungal C per g substrate C. Logistic suppression
Space includes detritus True bool Settled detritus counts as colonisable
Bacterial suppression max 0.40 fraction Mille-Lindblom 2006 — max 40% uptake reduction (substrate competition, not killing)
K_bacterial suppression 1e-5 mol C / L Half-sat at ~0.12 mg C/L — gives 5–25% suppression at typical jar densities

Stoichiometry

Symbol Value Units Source / Rationale
C:N 10.0 mol / mol Suberkropp 1991 — hyphomycete C:N 8–12
N:P 15.0 mol / mol Fungal N:P

Respiration

Symbol Value Units Source / Rationale
R_maint 0.0005 mol O₂ / mol C / h Metabolically conservative
K_O2 (respiration) 2e-5 mol/L ~0.64 mg/L; less tolerant than bacteria

Thermal envelope

Symbol Value Units Source / Rationale
T_ref 20.0 °C Suberkropp 1984; Chauvet & Suberkropp 1998 — community optimum 15–25°C; Duarte 2016. Lower than bacteria (25°C) → cool-water competitive advantage
Q10,uptake 2.0 Bärlocher 1992 — Q10 1.8–2.5
Q10,resp 2.0 Standard
Q10,mort 1.5 Standard
T_stress (low / high) 8.0 / 30.0 °C Krauss 2011 — stress above 28–30°C
T_lethal (low / high) 2.0 / 38.0 °C Bärlocher 1992 upper viability
m_thermal,max 0.02 /h Standard

pH envelope

Symbol Value Units Source / Rationale
pH stress (low / high) 4.5 / 8.5 Bärlocher 1992 — fungi tolerate mild acidity better than bacteria
pH lethal (low / high) 3.5 / 9.5
m_pH,max 0.02 /h Standard

Salinity envelope

Symbol Value Units Source / Rationale
S_opt 0.5 PSU Freshwater
σ_S 5.0 PSU
S_stress (low / high) 0.0 / 8.0 PSU Freshwater
S_lethal (low / high) 0.0 / 20.0 PSU
m_salinity,max 0.10 /h Standard

Hypoxia

Symbol Value Units Source / Rationale
O2 stress 5e-5 mol/L ~1.6 mg/L — obligate aerobe
O2 lethal 1.5e-5 mol/L ~0.5 mg/L
m_hypoxia,max 0.06 /h Aerobe sensitivity

Mortality & death routing

Symbol Value Units Source / Rationale
m_base 0.02/24 /h Bärlocher 1992 — hyphal turnover 2–5%/day; low end for established mycelium
m_total,max 0.30 /h Hard cap
Death → DOM (labile) fraction 0.20 fraction Cytoplasmic lysis
Death → DOM (refractory) fraction 0.15 fraction Gooday 1990 — chitin/melanin recalcitrant cell wall fragments
Death → DOM fraction (total) 0.35 fraction Sum of lab + ref (consumed by base class)
Death → suspended fraction 0.15 fraction Hyphae substrate-bound; mostly settled

Biogeochemical & Physical Processes

Process kernels — sediment / water-column chemistry, gas exchange across the air-water interface, light-driven photodegradation, mineral equilibria, allelochemical decay, biofilm maturation, and bioturbation. The conventions below are shared; per-process tables only spell out divergences.

Process symbol glossary

Symbol Meaning
k_X First-order rate constant for process X (per h)
K_X Monod / Hill half-saturation for substrate or driver X
D_X Molecular diffusivity of species X (m²/h or cm²/h)
Q10,X Temperature sensitivity of process X (multiplicative rate increase per 10 °C)
T_ref Reference temperature for Q10 scaling (default 25 °C)
pH_break Sigmoid midpoint for pH-modulated ligand stability
pH_width Sigmoid width for the same transition (pH units)
pKa1 First acid-dissociation constant
Hill n Hill exponent for sigmoid response curve
Ω Mineral saturation state (precipitation when Ω > 1, dissolution when Ω < 1)
f_X,max Fractional ceiling on process X (e.g. maximum local re-oxidation share)
Henry's law constant Air-water partitioning ratio for gas exchange

Decomposition

Abiotic first-order breakdown of suspended and settled detritus with separate O₂-aerobic and anaerobic-floor rates; products split between DOM and direct mineralization (DIC/NH₄/PO₄) and exchanged between suspended/settled pools via aggregation and resuspension.

Decomposition rates

Symbol Value Units Source / Rationale
k_decomp (suspended) 0.12/24 (~12%/day) /h Cole et al. 1984 (5–20 %/day labile OM); Urban-Rich 1999
k_decomp (settled) 0.04/24 (~4%/day) /h Calibrated for ~50/50 biotic/abiotic split with HeterotrophicBacteria; pre-split literature value ~8 %/day

O₂ gating

Symbol Value Units Source / Rationale
K_O2 1.0e-5 mol/L Aerobic decomposition half-sat; standard sediment value
Min decomp fraction 0.15 Anaerobic decomposition floor as fraction of aerobic
Settled O₂ scaling 0.5 Hand-tuned to reflect partially anoxic sediment
Settled O₂ access fraction 0.3 Hand-tuned O₂ demand reduction for settled decomp
litter_anoxic_frac 0.0 (off) Share of the settled-detritus mineralisation flux routed to acetoclastic disproportionation (2 CH₂O → CH₄ + CO₂, no O₂ charged) instead of through the normal DOM/direct split. Represents the anoxic interior of a coarse leaf pack or an unvacuumed gravel bed, which the single well-mixed settled layer cannot: Methanogenesis is a pore-compartment process and env.soil_pore_volume_L is zero without a soil substrate. Experimental and default-off — every existing scenario is bit-identical. Not a calibrated value; it is the lever for measuring the bypass, and the measurement says the bypass is not available (Emilson et al. 2018, Nat. Commun. 9:1801 — CH₄ production from terrestrial tree litter is ≥400× below macrophyte litter because the leachate phenolics inactivate methanogens). See internal_docs/planning/botanicals_second_pass.md §1 and botanicals_beta_tank_benchmark.md §4b.
litter_ebullition_frac 0.0 (off) Share of that CH₄ leaving as bubbles (→ atmosphere in an open tank, booked to atm_exchange_C; → CH4_HEAD when sealed) rather than dissolving into CH4_AQ. It matters more than the anoxic fraction: dissolved CH₄ that is re-oxidised costs two O₂ per carbon, so methanogenesis without an escape route makes the CO₂/O₂ coupling worse, not better.

Product routing

Symbol Value Units Source / Rationale
Fraction → DOM 0.70 70% DOM, 30% direct mineralization split
DOM labile fraction (suspended) 0.70 Kalbitz et al. 2003 / Hedges et al. 2001 — younger detritus more labile
DOM labile fraction (settled) 0.55 Kalbitz et al. 2003 / Hedges et al. 2001 — aged detritus more humified

Particle exchange

Symbol Value Units Source / Rationale
k_resuspension 0.015/24 (~1.5%/day) /h Wainright 1990 (1–5 %/day shallow systems)
k_aggregation 0.015/24 (~1.5%/day) /h Hand-tuned to balance resuspension

Thermal

Symbol Value Units Source / Rationale
T_ref 25 °C Engine reference temperature
Q10,decomp 2.0 Typical microbial Q10

Soil mineralization

Slow first-order mineralization of labile and refractory soil OM into pore-water nutrients with bacterial stimulation, evolving recalcitrance, methanogenic CH₄ routing, and a Phase-2 pore-DOM intermediate.

Mineralization rates

Symbol Value Units Source / Rationale
k_lab 1.0e-4 (~0.24%/day) /h Reddy & DeLaune 2008; Walstad 1999 — labile manure/compost rate. Soil-preset overrides: walstad_fresh 2.0e-4 (~0.48%/day — conservative interim for the fresh-dirt "initial flush": freshly submerged labile OM ammonifies ~0.5–3%/day before the pool draws down. Kept modest, not pushed to clear the ≥1 mg N/L band — the proper fix is a dedicated extra-labile/PMN flush pool, after which this returns to 1.0e-4; cycling audit §9.19), aquasoil_high 1.8e-4, walstad_aged 1.0e-4, aquasoil_low 4.0e-5
k_ref 5.0e-6 (~0.012%/day) /h Reddy & DeLaune 2008 — peat/bark ~20× slower than labile
Q10 2.0 Standard microbial Q10
T_ref 25 °C Engine reference
Soil volume 0.05 L Scenario default; bacterial-stim threshold scaling

Bacterial stimulation

Symbol Value Units Source / Rationale
K_bacterial 1.0e-4 mol C / L soil Hand-tuned bacterial-stim half-sat
Bacterial stim coeff (labile) 0.5 Max fractional stimulation of labile fraction
Bacterial stim coeff (refractory) 0.2 Max stimulation of refractory fraction

Recalcitrance evolution

Symbol Value Units Source / Rationale
α (recalcitrance) 0.0 (disabled) Schmidt et al. 2011; Boudreau & Ruddick 1991 — set by soil preset
β (recalcitrance) 2.5 Recalcitrance exponent
Initial soil-OM (refractory) 0.0 (disabled) mol C Soil preset overrides

O₂ switching

Symbol Value Units Source / Rationale
O₂ aerobic threshold 1.0 mg/L Hand-tuned aerobic-switch upper threshold
O₂ anaerobic threshold 0.2 mg/L Hand-tuned anaerobic-floor lower threshold
O₂ factor (aerobic) 1.0 Full aerobic rate
O₂ factor (anaerobic) 0.15 Facultative-microbe floor

Methanogenic ladder routing

Symbol Value Units Source / Rationale
Anaerobic DIC fraction 0.50 Conrad 1999 / Whiticar 1999 — acetoclastic methanogenesis (2 CH₂O → CH₄ + CO₂)
K_O2 (methanogenesis) 1.0e-5 mol/L Mirrors Methanogenesis Hill² gate
K_NO3 (methanogenesis) 5.0e-6 mol/L Terminal-electron-acceptor ladder ordering
K_pore SO4 (methanogenesis) 1.0e-5 mol/L Ladder ordering, mirrors Methanogenesis
Pore-DOM (labile) fraction 0.5 Phase 2 sediment realism — fraction of labile mineralization routed through PORE_DOM_LAB (denitrifier substrate)

Soil P sorption

First-order desorption/adsorption between mineral-bound P and pore-water PO₄, linearised Langmuir isotherm with equilibrium concentration target; buffers pore PO₄ against root drawdown.

Symbol Value Units Source / Rationale
k_desorb 5.0e-4 (~1.2%/day) /h Reddy & DeLaune 2008; McGechan & Lewis 2002
k_adsorb 2.0e-3 (~4.8%/day) /h Reddy & DeLaune 2008 — P binds Fe/Al oxides rapidly
PO4 equilibrium 3.23e-5 (≈ 1.0 mg P/L) mol P / L Froelich 1988 — typical pore-water equilibrium
Soil pore volume 0.02 L Scenario default
Q10 1.5 Weak T-dependence (partly physical sorption)
T_ref 25 °C Engine reference

Soil humic leaching

Physical extraction of water-soluble humic/fulvic acids from soil refractory OM into water-column refractory DOM; no O₂ consumption, no bacterial dependence — produces the "tea-coloured water" signature.

Symbol Value Units Source / Rationale
k_humic leach 1.5e-5 /h Kalbitz et al. 2000; Thurman 1985; Walstad 1999 — soil-preset overrides (aquasoil-high 3e-5, walstad fresh 2e-5, aquasoil-low 1e-6)
Q10 1.5 Physical dissolution — milder T-dependence than biology
T_ref 25 °C Engine reference

Pore-water diffusion

Series-resistance Fickian diffusion (soil + sand cap + DBL) of dissolved species between pore and bulk water, with rhizosphere physical-barrier interception and bioirrigation amplification.

Free-solution diffusivities

Symbol Value Units Source / Rationale
D_NH4 2.45e-6 m²/h Li & Gregory 1974
D_NO3 3.28e-6 m²/h Li & Gregory 1974
D_NO2 3.28e-6 m²/h Cussler / Li & Gregory 1974 — matched to NO3
D_PO4 2.20e-6 m²/h Li & Gregory 1974 (H2PO4⁻ at pH 7)
D_CO2 6.84e-6 m²/h Jähne et al. 1987
D_Fe 2.59e-6 m²/h Li & Gregory 1974 (aquo Fe²⁺)
D_K 7.06e-6 m²/h Li & Gregory 1974
D_SO4 3.6e-6 m²/h Schulz & Zabel 2006
D_HS 6.5e-6 m²/h Schulz & Zabel 2006
D_CH4 6.6e-6 m²/h Witherspoon & Saraf 1965; Boudreau 1997
D_O2 7.56e-6 m²/h Han & Bartels 1996; Boudreau 1997
D_DOM (labile) 1.8e-6 m²/h Lerman 1979; Boudreau 1997 (amino-acid / small-organic-acid mixture)

Sediment geometry

Symbol Value Units Source / Rationale
Max depletion fraction 0.5 Numerical safety cap
DBL thickness 0.5e-3 m Jørgensen & Revsbech 1985 (0.2–1 mm range)
Default soil tortuosity 0.3 Boudreau 1996 (τ² ≈ 1 − ln(φ²) for φ=0.38)
Sand-cap thickness 1.5 cm Default for typical Walstad
Sand porosity 0.38 Coarse sand typical
Sand tortuosity factor 0.5 Sand-pore tortuosity default
Soil depth 3.0 cm Default soil layer
Soil porosity 0.38 Soil preset overrides
Soil tortuosity factor 0.3 Boudreau 1996
Sediment area 100.0 cm² Scenario default
Soil pore volume 0.02 L Scenario default
Q10,diffusion 1.3 Berner 1980 — weak T-dependence for diffusion
T_ref 25 °C Engine reference

Rhizosphere & bioirrigation

Symbol Value Units Source / Rationale
Max root trapping 0.2 Caffrey & Kemp 1992 — physical-barrier-only contribution (chemical share in RhizosphereOxidation)
K_root trap 5e-5 mol C / cm² ~15 g dry root/m² — half-sat calibrated for mature Vallisneria/Potamogeton
Bioirrigation α (gallery) 2.5 Mermillod-Blondin 2011 Table 2 (tubificid/chironomid bioirrigation)
Bioirrigation α (biodiffusor) 0.3 Hand-tuned — surface mixing weakly enhances pore↔column exchange

Rhizosphere oxidation

Four coupled chemical sinks (HS, NH₄, CH₄, Fe²⁺) driven by radial oxygen loss from rooted-macrophyte aerenchyma; demands scaled uniformly to fit the per-rhs ROL O₂ budget; Fe-P co-precipitation onto root iron plaque.

Symbol Value Units Source / Rationale
k_nit 0.5 /h Hand-set at per-pool depletion cap; supply-capped by ROL O2 budget
K_NH4 (nitrification) 5.0e-7 (~7 µg N/L) mol/L Sub-µM half-sat — O2-limited regime is the steady state
k_so 0.5 /h Set at per-pool 0.5/h cap; Wium-Andersen et al. 1982 (textbook minute-scale)
k_mox 0.05 /h Same magnitude as cryptic-interface kernel in Methanogenesis
k_Fe oxidation 0.5 /h Set at per-pool cap; mirrors IronRedox.k_ox_free_per_h (Stumm & Morgan 1996)
P:Fe scavenge ratio 0.05 mol P / mol Fe Mirrors IronRedox default (Gunnars & Blomqvist 1997)
Q10,chem 2.0 Standard chemical-kinetics Q10
Q10,bio 2.5 Microbial activity steeper than chemical
T_ref 25 °C Engine reference
Pore O₂ routing fraction 0.5 Phase 2 sediment realism — fraction of unused ROL routed to PORE_O2 vs bulk

Gas exchange

Two-film model (Whitman 1923; Liss & Slater 1974) for O₂, CO₂, NH₃, H₂S, CH₄ across the air-water interface; uses Henry's law with overall KLa combining liquid- and gas-side resistance; open-top vs sealed headspace logic.

Symbol Value Units Source / Rationale
D_NH3 / D_O2 ratio 0.78 Cussler 2009 (D_NH3=1.64e-9, D_O2=2.10e-9 m²/s)
D_H2S / D_O2 ratio 0.95 Cussler 2009; Schulz & Zabel 2006
D_CH4 / D_O2 ratio 0.88 Witherspoon & Saraf 1965
pKa1 (H₂S) 7.05 pH units Millero 1986 — H2S ⇌ HS⁻ + H⁺
K_G / K_L ratio 100.0 Liss & Slater 1974 — still indoor air
Open-top threshold 0.5 /h head_leak threshold above which tank is treated as open to atmosphere

CO₂ injection

Pressurised-CO₂ setpoint controller for high-tech planted tanks (processes/co2_injection.py). A PI (proportional + integral) controller with anti-windup driving a carbon source into the DIC pool, gated to the photoperiod — models a pH/solenoid + needle-valve rig timed to the lights. pH drop, the diurnal CO₂/pH swing, and CO₂-limited photosynthesis relief all emerge from existing chemistry/biology; this process only adds the carbon source. The integral term removes the steady-state offset a proportional-only controller carries (a stronger gas-exchange loss — a HOB, an air stone — otherwise leaves a bigger undershoot), so the controller lands on setpoint regardless of kLa; the filter choice then shows up purely as the carbon cost of holding it, not as a lower dissolved CO₂. The integral of the setpoint error lives in the non-mass co2_pi_integral scalar ODE slot (memory the RHS can only keep in the state vector). Anti-windup is two-part: the integral is frozen while the controller is gated off (night / pre-start), so it cannot accumulate a dark-night charge and dump it as a bolus at lights-on; and while active it is clamped to [0, inject_max/Ki] — the band a one-way valve can act on. The lower bound of 0 is load-bearing: above setpoint the integral unwinds fully to 0 and the controller falls back to clean pure-proportional (valve shut), rather than freezing at the demand = 0 boundary, where the RHS chatters and LSODA step-collapses in a no-sink (sealed) tank (the fish-health-at-H=0 freeze precedent — measured: boundary-freeze ran the sealed-conservation fixture in >16 min at rtol 1e-6, integral-clamping in ~0.6 s, same answer). Injected carbon integrates into the non-mass co2_injected_C scalar ledger so mass balance credits it as a "+ injected" external input. Both scalar slots exist only when a CO₂-injection process is in the run, so every scenario without one is bit-identical. Opt-in (never auto-injected); product-gated to open tanks by the scenario builder, though the engine is container-agnostic.

Symbol Value Units Source / Rationale
target_mg_L 25–28 (default 25) mg CO₂/L Hobby high-tech band ~20–30 mg CO₂/L (green drop-checker). Molecule basis; the CO2_aq_mgL output column is carbon basis (× 12/44). Setpoint the PI controller holds during the photoperiod — measured on the F16 gas-exchange rig, asking for 30 mg CO₂/L (≈ 8.19 mg C/L) now lands at ~30.0 on both a canister (kLa 0.20) and a HOB (kLa 0.95).
tau_h 0.5 (0.25 in the demo) h Proportional response time constant (Kp = V/tau_h); the proportional part closes the deficit over ≈ tau. Smaller = stiffer hold but a stiffer DIC pool (runtime ↑); 0.25–0.5 holds the band at acceptable cost. Calibrated against runtime/accuracy sweep, not literature.
TAU_I_H 2.0 h Integral time constant (Ki = Kp/TAU_I_H). 4× tau_h — gentle enough to avoid ringing on the fast DIC pool, fast enough that a 30-day run spends <1 % of its length converging. Internal module constant, not a YAML knob (an integral time is not a user-facing/citable control; keeps the offset-removal mechanism un-tunable from the scenario). Not literature-derived — a control-loop tuning choice.
VALVE_MAX_MULT 4.0 Needle-valve delivery ceiling, as a multiple of the full-deficit-over-tau rate (target × V / tau_h, a wide-open valve at empty). Bounds the cold-start transient and pathological windup; deliberately generous, so steady-state demand never caps the setpoint on any realistic filter (F16 HOB steady demand sits well under it). Internal module constant, not a YAML knob. Not literature — a physical-plausibility bound on actuator flow.
start_day 0.0 day Injection begins at this simulation day.
lights_on_only true bool Gate injection to the photoperiod (light_umol_m2_s > 0), mirroring a solenoid wired to the light timer (CO₂ left on overnight gasses livestock). The integral is frozen (not reset) while gated off, so the morning re-gas is a fast proportional ramp from the held charge, never an overnight-accumulated bolus.
CO2 molar mass 44.009 g/mol Converts the mg CO₂/L setpoint to mol C/L (1 mol CO₂ → 1 mol C in DIC).

Aeration

Air stone / surface agitation. The physical opposite of CO₂ injection (it outgasses the CO₂ you inject), so the scenario builder offers the two mutually exclusively. There is no new process — aeration simply raises the environment's O₂ mass-transfer coefficient kLa_O2_per_h, which GasExchange already uses for every air-water gas (O₂ in, CO₂/NH₃ out, scaled by Schmidt/diffusivity ratios). The values below are the scenario-builder preset bands, not engine constants; the engine reads only the resolved kLa_O2_per_h. Applied as max(container baseline, target) so enabling aeration never lowers a high-circulation tank's exchange. Product-gated to open tanks by the builder (a sealed ecosystem runs without equipment).

Symbol Value Units Source / Rationale
kLa_O2_per_h (open baseline) 0.08 /h Still open-water surface diffusion (container_presets.py); the unaerated floor aeration steps up from.
Aeration target (gentle) 0.5 /h Small air stone / light surface ripple. Order-of-magnitude with reaeration coefficients for gently agitated tanks.
Aeration target (moderate, default) 1.0 /h Standard air stone; holds dissolved O₂ near saturation through the night. Builder default when aeration is enabled.
Aeration target (strong) 2.0 /h Vigorous airstone / wet-dry / sump turnover; O₂ pinned to saturation, dissolved CO₂ stripped toward atmospheric.

Iron redox

End-to-end Fe speciation + redox: free/chelated oxidation, DOM-gated chelation equilibrium, sediment Fe-oxide reduction (biology owns; cryptic trap retained), photoreduction, settling, and Fe-PO₄ co-precipitation/release.

Oxidation kinetics

Symbol Value Units Source / Rationale
k_ox (free) 0.5 (t½ ≈ 1.4 h) /h Stumm & Morgan 1996 (capped vs textbook minute-scale for LSODA stiffness)
k_ox (chelated) 0.008 (t½ ≈ 3.6 d) /h Rose & Waite 2003; Emmenegger et al. 2001
pH_ref (ox) 7.5 pH Stumm & Morgan 1996 — calibration pH for [OH⁻]² rate law
pH ox factor (max) 20.0 Stiffness cap (~pH 8.15 equivalent)
pH ox factor (min) 0.01 Floor (~pH 6.5 equivalent)
K_O2 (Fe ox) 3.0e-5 mol/L Stumm & Morgan 1996
Q10,Fe ox 2.0 Stumm & Morgan 1996; Millero et al. 1987
Q10,Fe red 2.0 Standard microbial Q10
Q10,photoreduction 1.5 Emmenegger et al. 2001 — photon-dominated kinetics
Q10,chelation 1.5 Ligand-exchange coordination kinetics

Chelation equilibrium

Symbol Value Units Source / Rationale
k_chel (forward) 50.0 /h Hand-tuned to match Rose & Waite 2003 / Emmenegger 2001 (>90% chelated in DOM-rich tanks)
k_chel (back) 0.02 /h Hand-tuned dissociation rate
K_DOM (chelation) 5.0e-7 mol C/L Hand-tuned — trace DOM saturates chelation

Sediment reduction & cryptic trap

Symbol Value Units Source / Rationale
k_settle 1.0e-4 (~289 d t½) /h Hand-tuned (colloidal 1–10 nm ferrihydrite suspended indefinitely on simulation timescales)
k_red 5.0e-4 (~1%/day) /h Legacy (biology now owns reduction); Lovley & Phillips 1988 family
K_O2 (anoxia switch) 1.5e-5 mol/L Hill-2 anoxia half-sat
K_detritus (settled) 5.0e-5 mol Hand-tuned settled-det half-sat
Buried anoxia floor 0.5 Hand-tuned proxy for buried sediment oxide always in anoxic pore
Detrital anoxia floor (max) 0.3 Hand-tuned sub-mm anoxic microzone fraction
K_detrital anoxia (C) 2.0e-4 mol C Half-sat for detrital anoxia in settled C
f_local re-ox (max) 0.9 Hand-tuned ≥90% of sediment-reduced Fe trapped in oxic tanks
K_O2 (re-ox) 3.0e-5 mol/L Same scale as Fe²⁺ oxidation affinity
k_pore re-ox 0.05 (t½ ≈ 14 h) /h Hand-tuned for pore Fe²⁺ steady-state
K_oxide (pore re-ox) 1.0e-5 mol Hand-tuned (saturating in typical Walstad ~1e-3 mol oxide)
K_O2 (pore re-ox) 3.0e-5 mol/L Mirrors Fe²⁺ oxidation affinity

Fe-P scavenging

Symbol Value Units Source / Rationale
P:Fe scavenge ratio 0.05 mol P / mol Fe Gunnars & Blomqvist 1997; Griffioen 1994 (range 0.03–0.10)
Adsorbed P (Fe-bound) fraction 1.0 Soil preset overrides (walstad 0.60, aquasoil 0.70)

Photoreduction

Symbol Value Units Source / Rationale
k_photoreduction 0.02 /h Barbeau 2006; Voelker & Sulzberger 1996; Emmenegger 2001 (1–5%/day in humic lakes)
K_light (photoreduction) 40.0 µmol/m²/s Hand-tuned Michaelis half-sat (no photoinhibition at aquarium light)
K_DOM (photoreduction) 5.0e-6 mol C/L Hand-tuned — trace DOM activates recycle

Iron dose release

First-order pH-modulated release of ligand-bound Fe from the iron:protected staging pool into FE_CHELATED; per-form parameter bundles for sulfate / gluconate / EDTA / DTPA / EDDHA.

Form / Parameter Value Units Source / Rationale
Gluconate k_baseline 0.0578 (t½ ≈ 12 h) /h Microbial ligand stripping — hobbyist Flourish Iron timescale
EDTA k_baseline 0.00578 (t½ ≈ 5 d) /h Chaberek & Martell 1959 — Fe-EDTA stability
EDTA pH_break 6.5 pH Chaberek & Martell 1959
EDTA k_breakdown (max) 0.06 /h Hand-tuned breakdown
DTPA k_baseline 0.00289 (t½ ≈ 10 d) /h Chaberek & Martell 1959
DTPA pH_break 7.5 pH DTPA holds to ~pH 7.5
DTPA k_breakdown (max) 0.06 /h Hand-tuned
EDDHA k_baseline 0.00206 (t½ ≈ 14 d) /h Hamilton-Taylor et al. 2005 family — stable past pH 9
EDDHA pH_break 9.0 pH EDDHA stability range
EDDHA k_breakdown (max) 0.06 /h Hand-tuned
EDDHA pH_width 0.4 pH Softer transition
Default pH_width 0.3 pH Sigmoid width — sharp transition

Sulfur redox

Sulfate reduction (biology owns), water-column + cryptic-interface HS oxidation, FeS precipitation (mass-action), FeS re-oxidation, and pH-dependent H₂S speciation cache for gas exchange & toxicity.

Sulfate reduction (legacy — biology owns)

Symbol Value Units Source / Rationale
k_SR 0.005 /h Canfield 1991 freshwater rate scaled to aquarium T (legacy — biology owns SR now)
K_O2 (anoxia switch) 1.0e-5 mol/L Mirrors IronRedox Hill-2 anoxia half-sat
K_detritus (settled, C) 5.0e-4 mol/L Hand-tuned settled-detritus C half-sat

HS oxidation (water column + cryptic interface)

Symbol Value Units Source / Rationale
k_so 10.0 (~6 min t½) /h Millero 1991 — water-column sulfide oxidation
K_O2 (so) 1.0e-5 mol/L Hand-tuned — O2-saturated above 0.3 mg/L
f_pore re-ox (max) 0.7 Berner 1980; Jørgensen 1982 — looser than Fe trap (HS more diffusive)
K_O2 (pore re-ox) 3.0e-5 mol/L Same scale as Fe cryptic trap

FeS precipitation & re-oxidation

Symbol Value Units Source / Rationale
k_FeS precipitation 1.0e6 (mol/L)⁻¹/h Hand-set large (drives mass-action equilibrium)
k_FeS oxidation 0.005 /h Berner 1981 — FeS persists for days under oxic
K_O2 (FeS ox) 3.0e-5 mol/L Same scale as Fe pore re-oxidation

H₂S speciation & thermal

Symbol Value Units Source / Rationale
pKa1 (H₂S) 7.05 pH Millero 1986
Q10,S red 2.0 Standard microbial Q10
Q10,S ox 2.0 Stumm & Morgan family — abiotic kinetics

H₂S toxicity

Hill-2 acute mortality on consumers from undissociated H₂S (the only toxic species; pH-gated via SulfurRedox cache). Per-species K via the consumer K_H2S,tox.

Symbol Value Units Source / Rationale
m_H2S,max (default) 0.05 (~70%/day) /h Matches Cu cap — 96-h kills near LC50 (Bagarinao 1992)
Hill n (default) 2.0 Bagarinao 1992 fig. 3 — well fit by Hill-2

Copper chelation

DOM-gated Cu²⁺ ⇌ Cu-DOM speciation equilibrium (no oxidation/reduction). Parallel to the Fe chelation kernel but ~10× stronger (Xue & Sigg 1993).

Symbol Value Units Source / Rationale
k_chel (forward) 100.0 (~40 s timescale) /h Xue & Sigg 1993; Sunda & Huntsman 1995 — Cu binds DOM ~10× stronger than Fe
k_chel (back) 0.005 /h Hand-tuned to match observed free-Cu²⁺ <1% of total dissolved
K_DOM (chelation) 3.0e-7 (~0.004 mg C/L) mol C/L Hand-tuned — saturated in DOM-bearing tanks
Q10,chelation 1.5 Mirrors IronRedox.Q10_chelation
T_ref 25 °C Engine reference

Copper dose release

First-order pH-modulated release of ligand-bound Cu from copper:protectedCU_CHELATED. Cu-EDTA inverts polarity vs Fe-EDTA (breakdown at LOW pH, not HIGH).

Form / Parameter Value Units Source / Rationale
Gluconate k_baseline 0.050 (t½ ≈ 14 h) /h Hand-tuned — Flourish day-scale observation
EDTA k_baseline 0.003 (t½ ≈ 10 d) /h Morel & Hering 1993 — Cu-EDTA log K=18.8
EDTA pH_break 4.0 pH Outside aquarium range — kept for symmetry with Fe
EDTA k_breakdown (max) 0.030 /h Hand-tuned
EDTA pH_width 0.4 pH Sigmoid width
DTPA k_baseline 0.002 (t½ ≈ 14 d) /h Hand-tuned — DTPA effectively inert in aquarium pH
DTPA pH_break 5.5 pH Off in normal tanks
DTPA k_breakdown (max) 0.050 /h Hand-tuned
Default pH_width 0.3 pH Sigmoid width

Copper toxicity

Hill-2 acute mortality + reproduction suppression on consumers driven by free Cu²⁺ (CU_FREE pool, not chelated). Per-species K via the consumer K_Cu,tox.

Symbol Value Units Source / Rationale
m_Cu,max (default) 0.05 (~70%/day) /h Hand-tuned — 96-h kills near LC50 (Borgmann 1993, Lauer et al. 2012, EPA AWQC)
Hill n (mortality, default) 2.0 Reproduces observed shrimp dose-response (Lauer et al. 2012)
Hill n (repro suppression, default) 2.0 Complement of mortality curve at same K

Methanogenesis chemistry

Five-kernel CH₄ chemistry: settled-detritus methanogenesis (biology owns), water-column methanotrophy, cryptic-interface methanotrophy, ebullition. Closes the C book for anoxic substrate.

Methanogenic source (legacy — biology owns)

Symbol Value Units Source / Rationale
k_methanogenesis 1.0e-3 /h Bastviken 2004 freshwater sediment rate scaled to aquarium T (legacy — biology owns)
K_O2 (anoxia switch) 1.0e-5 mol/L Mirrors IronRedox / SulfurRedox
K_detritus (settled, C) 5.0e-4 mol/L Hand-tuned — sterile substrate has no methanogens
K_NO3 (methanogenesis) 5.0e-6 (~0.07 mg N/L) mol/L Terminal-acceptor ladder ordering
K_pore SO4 (methanogenesis) 1.0e-5 (~0.32 mg S/L) mol/L Ladder ordering

Methanotrophy (water column + cryptic interface)

Symbol Value Units Source / Rationale
k_mox 0.05 (~14 h t½) /h Bastviken 2004; Hanson & Hanson 1996
K_O2 (mox) 1.5e-5 (~0.5 mg/L) mol/L Hand-tuned — methanotrophs microaerophilic
f_pore oxidation (max) 0.5 Hand-tuned — looser than Fe (0.9) and S (0.7) because CH4 bubbles bypass dissolved-phase oxidation
K_O2 (pore oxidation) 3.0e-5 mol/L Same scale as Fe / S cryptic traps

Ebullition & solubility

Symbol Value Units Source / Rationale
k_ebullition 0.2 /h Hand-tuned/calibrated for LSODA stiffness — reduced 5× from 1.0 (May 2026)
CH4 saturation 1.4e-3 mol/L Henry's law at 1 atm, 25 °C (Sander 2015)
Q10,methanogenesis 4.0 Bastviken 2004 — methanogens more T-sensitive than other anaerobes
Q10,mox 2.0 Standard abiotic-kinetics family

Silicon cycling

First-order dissolution of biogenic opal (diatom frustules) back to dissolved silica with weak Q10.

Symbol Value Units Source / Rationale
k_dissolution 0.003/24 (t½ ≈ 10 d) /h Ragueneau et al. 2000; Van Cappellen et al. 2002 (5–20 d range)
Q10,dissolution 1.5 Physical-chemical process — weaker than metabolic
T_ref 25 °C Engine reference

CaCO₃ equilibrium

First-order saturation-state-driven CaCO₃ precipitation (Ω > 1) and dissolution (Ω < 1 with calcareous substrate present); calcite or aragonite phase.

Symbol Value Units Source / Rationale
k_precipitation 0.005 /h per unit Ω excess Hand-tuned slow abiotic kinetics (Morse & Arvidson 2002 family)
k_dissolution 0.002 /h per unit Ω deficit Morse & Arvidson 2002 — dissolution slower than precip
CaCO3 substrate 0.0 (disabled) mol Set per scenario; Plummer & Busenberg 1982 for Ksp(T)
Mineral phase "calcite" str Plummer & Busenberg 1982 (calcite); aragonite Ksp ~39% higher

DOM photodegradation

Light-saturated photochemical breakdown of labile and refractory DOM to DIC + NH₄ + PO₄, with refractory humics 1.5× more photoreactive.

Symbol Value Units Source / Rationale
k_photo 0.03/24 (~3%/day max) /h Cory et al. 2014; Bertilsson & Tranvik 2000 — brown-water lake range
Photo (refractory) multiplier 1.5 Zepp & Schlotzhauer 1981; Bertilsson & Tranvik 2000 — humic aromatic UV absorption
K_light 150.0 µmol/m²/s Tranvik & Bertilsson 2001 — saturation above ~0.4 W/m²
Fraction mineralized 0.40 Moran & Zepp 1997 — 30–50% literature range
Q10,photo 1.3 Photochemistry — weak T-dependence
T_ref 25 °C Engine reference

Allelopathy decay

First-order decay of polyphenol (light-gated photodegradation) and cyanotoxin (T-gated microbial breakdown) allelochemical tracer pools back to DIC. Also provides pure-function Hill-2 suppression / mortality kernels consumed by producer / consumer flux().

Symbol Value Units Source / Rationale
Hill n (default) 2.0 Mirrors Cu toxicity Hill exponent
m_allelo,max (default) 0.04 (~60%/day) /h Rohrlack 2003 (daphnia 24 h 50% at 5 µg MC-LR/L)
k_polyphenol decay 5.0e-3 (~6 d t½) /h Wetzel 1992 (phenolic-OH more UV-absorbing than bulk DOM). Light-gated, so near zero in the dark
k_polyphenol microbial 1.0e-3 (~29 d t½) /h Light-independent floor, T-gated on Q10,cyanotoxin. Bärlocher & Graça 2005 — tannase-mediated tannin loss during microbial conditioning of leaf litter. Added with botanicals: photolysis alone leaves the pool with no sink under a closed floating canopy, so it grew without bound. Set at the slow end of the reported days-to-weeks range so macrophyte-only scenarios move as little as possible
k_cyanotoxin decay 2.0e-3 (~14 d t½) /h Edwards & Lawton 2009 — adapted-community bioremediation
K_light 150.0 µmol/m²/s Same scale as DOMPhotodegradation
Q10,cyanotoxin decay 2.0 Edwards & Lawton 2009 — standard microbial Q10
T_ref 25 °C Engine reference

Biofilm maturity

Per-surface EPS-scaffold maturity index M (0–1) integrating activity history (bacteria + fungi + detritus + nitrifier Monod terms) against decay + grazer-damage; gates late-coloniser exposure, nitrifier protection, grazer access.

Maturation kinetics

Symbol Value Units Source / Rationale
k_mature 0.040/24 /h Battin et al. 2016 — stream biofilms reach maturity in 2–6 months; hand-tuned to t½ ≈ 4 mo at full activity
k_decay 0.001/24 /h Hand-tuned — biofilms persist after activity drops
k_graze damage 0.012/24 /h Feminella & Hawkins 1995; Dillon 2000 — radula physically strips EPS (raised from 0.002/24)
K_graze damage 5.0e-7 mol C/L Hand-tuned (~6 µg C/L, few mg grazers in 30 L tank)
Q10,maturation 2.0 Flemming & Wingender 2010 — enzymatic EPS secretion
Q10,decay 2.0 Besemer 2015 — extracellular hydrolase Q10
T_ref 25 °C Engine reference

Maturity → shelter shaping — how M is read, and a known open question

Every biofilm_predation_protection row in this document is an M = 1 ceiling. What a biofilm at partial maturity actually gets is the linear ramp geo + M·(prot − geo), so at the M ≈ 0.3 a real tank spends most of its life at, a nitrifier realises about a third of its 0.90 ceiling.

Open question, measured and deliberately not shipped (Aug 2026). There is a good case that shelter should saturate in M rather than track it linearly — EPS secretion begins at attachment and microcolony architecture forms within days, so what the remaining months of M buy is scaffold thickness, not the onset of protection (Flemming et al. 2016 find 40–80% of freshwater bacteria biofilm-associated in ordinary biofilms, not ancient ones). This was nitrifier_dormancy.md §7b item 2. A saturating form f(M) = M(1+K)/(M+K) with K = 0.25 (endpoint-preserving, so every geo and prot keeps its meaning) was implemented and measured: it rescues comammox in the beta reproduction and removes a terminal ammonia spike, but it lifts the un-filtered baseline enough to compress the filter differentials and breaks 9 targets across F15 / F16 / F19 / F4 — e.g. the filter's nitrifier-stock edge falls from the required ≥1.20× to 1.109×. Landing it means re-deriving the filter epic's "flow is the lever" claims, which is its own piece of work. See labile DOM accumulation §7.

Activity-signal weights & half-sats

Symbol Value Units Source / Rationale
w_bacteria 0.35 Hand-tuned activity-signal weight
w_fungi 0.25 Hand-tuned activity-signal weight
w_detritus 0.25 Hand-tuned activity-signal weight
w_nitrifier 0.15 Hand-tuned activity-signal weight
K_bacteria 5.0e-5 (~0.6 mg C/L) mol C/L Hand-tuned to keep Monod responsive across realistic biomass
K_fungi 5.0e-6 mol C/L Hand-tuned
K_detritus 2.0e-5 mol C/L Hand-tuned
K_nitrifier 1.0e-5 mol C/L Hand-tuned

Per-grazer damage coefficients

Symbol Value Units Source / Rationale
Bladder snail 1.0 Hand-tuned (radula scraper — Dillon 2000)
Neocaridina 0.4 Hand-tuned (soft-appendage scraper). Lowered 0.7 → 0.4 to reconcile with the shrimp's low grazing biofilm_graze_penetration (0.35): a brush-tipped grazer that cannot rasp through cemented mature EPS should not also strip the scaffold at ~0.7× a snail radula. Sits just above the ostracod browser (0.3) — more active than a picker, far gentler than a radula (Steinman 1996; Dillon 2000).
Ostracod 0.3 Hand-tuned (browser/picker)
Daphnia / Copepod / Rotifer 0.0 No biofilm contact (planktonic)
Ciliate 0.05 Hand-tuned (minimal structural damage)
Nanoflagellate 0.02 Hand-tuned (negligible)

Bioturbation

FeS re-exposure (gallery-fauna only) and settled-detritus resuspension driven by burrowing-fauna intensity published into env._bioturbation_intensity. Bioirrigation lives as a multiplier in PoreWaterDiffusion.

Symbol Value Units Source / Rationale
k_FeS bioturbation 0.02 (~35 h t½ at intensity=1) /h Mermillod-Blondin 2011 — paced ~4× faster than SulfurRedox.k_fes_ox_per_h (bypass of O2 penetration limit)
k_resuspension bioturbation 3.0e-4 (~0.7%/day) /h Hand-tuned ≈0.5× Decomposition baseline
Resuspension weight (gallery) 1.0 Hand-tuned (parameter for future asymmetric tuning)
Resuspension weight (biodiffusor) 1.0 Hand-tuned
Q10,chem 2.0 Standard chemical Q10
T_ref 25 °C Engine reference

Surfaces — the macrophyte leaf surface (dynamic)

The model's only dynamic surface: area is not declared, it is Σ (SLA_cm2_per_mg_C × leaf C) summed over every rooted, submerged, and floating macrophyte (pool_registry.macrophyte_leaf_area_cm2; per-species SLA rows are in the macrophyte sections above). The scenario builder emits it whenever a macrophyte is stocked, so it is present in every planted user tank — where it is typically the largest surface. On the shipped default 30 × 20 × 25 cm planted tank it is 10 699 cm² at day 0 and 12 682 cm² at day 100, against 2 050 cm² of glass and 600 cm² of sand.

Parameter Where Default Units Rationale / citation
roughness surfaces.pyDYNAMIC_SURFACE_PRESETS 0.40 Soft leaf cuticle with moderate texture — above smooth glass (0.05), below gravel (0.70). Hand-set on the Hoagland (1982) 10–100× smooth-to-rough colonisation span.
grazer_access DYNAMIC_SURFACE_PRESETS 0.85 Exposed, easy to scrape. Note this is the surface-level exposure; the per-grazer reach that actually decides who eats leaf periphyton is set in interactions.yaml and anchored to feeding mode (Brönmark 1985; Porter et al. 1983; Williamson & Reid 2009) — see the table in docs/environment/surfaces.md.
detachment_rate_per_day DYNAMIC_SURFACE_PRESETS 0.06 /day Flexible substrate: a leaf moves in the current, so it sheds film faster than gravel and slower than shifting sand.
max_N_density_ug_per_cm2 DYNAMIC_SURFACE_PRESETS 5.0 µg N/cm² Set equal to sand. Within the 1–10 µg N/cm² band implied by Dodds et al. (1999) for mature biofilms.
benthic_fraction DYNAMIC_SURFACE_PRESETS 0.30 Mostly wall-like (leaves span the water column), with a benthic share for the shrimp and snails that do reach them.
fractal_dimension DYNAMIC_SURFACE_PRESETS 2.05 Near-smooth: a leaf has little micro-crevice structure for small organisms to exploit, unlike porous ceramic.
geometric_light_frac DYNAMIC_SURFACE_PRESETS 0.55 Canopy-mid. Canopy self-shading is then applied dynamically per RHS (model._compute_macrophyte_canopy_factor), so this is the light before the plants shade their own leaves.

⚠️ geometric_light_frac 0.55 and grazer_access 0.85 are flagged, not settled. Together they make the leaf a lit, heavily-grazed place to be a nitrifier. Measured on the default planted tank at day 100, the leaf carries 83 % of the colonisable area but only 12 % of the AOB and 22 % of the NOB — roughly 1/50th the sand's areal density. Epiphytic nitrification is real in the model (adding the surface raises total AOB by 34 % and cuts the nitrite peak by 30 %, and the substrate's own stock rises rather than being cannibalised), but the density is in tension with Eriksson & Weisner (1999) and Körner (1999), the two papers cited for the lightly_seeded cycling tier. Recalibrating these is a separate change with its own A/B: see internal_docs/planning/macrophyte_leaf_surface_builder.md §2.4.


Surfaces — filtration & forced convection

Parameters describing filtration. A filter is not modelled as a separate box of water: it is a colonizable surface that carries a flow attribute.

Parameter Where Default Units Rationale / citation
mass_transfer_factor (m) surfaces.pySurface 0.0 dimensionless Forced-convection relief of the diffusion boundary layer over a surface. 0.0 = a static surface (glass, sand, gravel, leaves), where attached microbes wait for ammonia to diffuse across an unstirred layer; > 0 marks media water is actively pumped through. Reads as K_apparent(static) / K_apparent(flow) − 1 — see the Monod identity below. A calibration, not a derivation (decision D2, re-confirmed by the Option-B spike): see the note beneath this table. Driven against the f15_filtration A/B harness.
mass_transfer_factorfilter_sponge surfaces.pySURFACE_PRESETS 3.0 dimensionless Air-driven / low-head sponge. Compresses the AOB half-saturation from 0.35 → 0.09 mg N/L. The response saturates: residual ammonia falls to 0.57× / 0.44× / 0.38× / 0.34× of the unfiltered arm at m = 1 / 3 / 6 / 16, so the exact value is low-stakes above ~3.
mass_transfer_factorfilter_canister surfaces.pySURFACE_PRESETS 3.0 dimensionless Was 6.0 — an inverted ordering, corrected 2026-07-10. External mass transfer scales as k_L ∝ Sh/d_p, and a canister packs 5–15 mm sintered ceramic against a sponge's 0.8–1.5 mm pores, so a canister has the lowest k_L of the three classes (2.0–2.6e-5 m/s vs sponge 4.6–9.6e-5, HOB 5.0–9.3e-5). No scored check constrained it: every canister arm is differenced against a canister control, so m cancelled.
mass_transfer_factorfilter_hob surfaces.pySURFACE_PRESETS 3.0 dimensionless Was 4.0. Derived k_L (5.0–9.3e-5 m/s) is indistinguishable from a sponge's (4.6–9.6e-5); the 4-vs-3 split was fake precision. A HOB differs from the others through its kLa_contribution_per_h, not its biofilm kinetics.
area_cm2 — filter presets per scenario cm² Not a preset value; the builder supplies it. A coarse foam block ≈ 200–400 m²/m³ and sintered ceramic ≈ 500–1000 m²/m³ of nominal surface, so hobby filters land at ~3 000–20 000 cm².
k_areal (AREAL_CAPACITY_UG_N_PER_CM2) species/bacteria/nitrifier.py 50.0 µg N/cm² Areal carrying capacity of a nitrifier biofilm: the conservative end of the 50–100 µg N/cm² (≈ 0.5–1 g N/m²) reported for mature fixed-film reactors (Rittmann & McCarty 2001; Nogueira et al. 2002). Shared across AOB + NOB + comammox — it is a property of the substratum, not of an organism, and one cm² holds one biofilm. A ceiling, not an operating point (see below).
n (AREAL_CAP_HILL_N) species/bacteria/nitrifier.py 4.0 dimensionless Hill exponent of the crowding factor cap = 1 − (X_areal / k_areal)ⁿ. Keeps cap within 1e-5 of 1.0 at the 0.9–2.8 µg N/cm² densities real tanks reach, so the ceiling behaves like a ceiling rather than a gradual drag on growth.

Why m is one calibrated constant and not three derived ones. The Option-B spike (internal_docs/planning/option_b/b_spike_verdict.md) tried to derive m from media geometry: interstitial velocity → Reynolds → Sherwood (Wakao–Funazkri 1978, valid over the whole hobby range 3 < Re_p < 10⁴) → external mass-transfer coefficient k_L, referenced against a static wall's k_L = D/δ. Two results, and both are load-bearing.

  1. The absolute value is not derivable. (1+m) is a ratio; geometry supplies only its numerator. Its denominator needs δ, the diffusion-boundary-layer thickness on still aquarium glass — cited at 300 µm with a 150–500 µm bracket (Jørgensen & Des Marais 1990, Limnol. Oceanogr. 35:1343, O₂ microelectrode: 0.59 mm at 0.3 cm/s falling to 0.16 mm at 7.7 cm/s; the O₂→NH₄ correction is ~5 %, since δ ∝ D^⅓). It also needs the film's areal uptake capacity, itself uncertain ±30 %. Across those brackets the derived m spans 0.19 … 197. There is no citable number here. The correct relation is K_app = K_int + J_max/(2 k_L) — a boundary layer adds to the half-saturation, where m divides it — and the two agree only in the transport-limited limit J_max → ∞, which this model (Damköhler number O(0.1–1), areal density ~2.2 µg N/cm², some 20× under the literature ceiling) is nowhere near.
  2. The ordering is derivable, because δ and J_max cancel in a ratio between two classes — and the ordering originally shipped was inverted. Measured sponge:canister enhancement ratio 1.04–1.30 (sponge better) for every δ and every J_max; the old presets declared (1+3)/(1+6) = 0.571. Guarded by tests/test_filter_plumbing.py::test_a_canister_never_out_flows_a_sponge.

So m is one calibrated constant. What actually separates the presets is kLa_contribution_per_h (a 16× span) and mechanical_capture_per_h — never biofilm kinetics.

The cap throttles anabolic growth and settlement only. A biofilm at carrying capacity is the workhorse: it oxidises ammonia at the full per-cell rate, it just stops adding cells. Maintenance, mortality and the catabolic oxidation flux are untouched — the physically correct decoupled/overflow-metabolism picture.

What counts as a filter, and the two rules that follow

Surface.is_filter is true when a surface declares any of mass_transfer_factor, kLa_contribution_per_h, mechanical_capture_per_h, a cleaning: block or a chemical_media: list — "media in a housing that water is pumped through", as opposed to glass, sand, gravel or a leaf. Two rules follow:

  1. A tank may declare at most one filter (enforced in config.load_surfaces). The builder offers a single filter selector; two filters would sum their kLa contributions into one air-water interface and split nitrifier settlement between two housings — a configuration that would run, plausibly, and be wrong.
  2. Filter media are never buried in the substrate. In a soil tank, nitrifiers route pore_fraction of their biomass (AOB 0.6) into a pore-resident zone that reads pore-water ammonia and O₂. Media sitting in a canister have no pore water around them, so nitrifier.py::_flux_surfaces runs a filter surface wholly in the bulk zone. Without this gate a canister's biofilm mined ammonia out of the soil pore water and excreted nitrite back into it — measured at d(PORE_NO2)/dt = +1.0e-06 mol/h from a biofilm that isn't there.

Gas exchange — a filter moves air as well as water

Surface.kLa_contribution_per_h is the liquid-side O₂ volumetric mass-transfer coefficient a filter's return flow adds to the scenario's base kLa_O2_per_h (container geometry plus the aeration lever). Env.kLa_O2_total_per_h is their sum. kLa is additive across independent surface-renewal mechanisms, which is why filter choice and an air stone compose rather than one silently overwriting the other.

Every gas rides this one coefficient — processes/gas_exchange.py derives CO₂ by Schmidt-number scaling and NH₃ / H₂S / CH₄ by diffusivity ratio. So a filter that oxygenates well also strips injected CO₂. That is not a modelling artefact; it is the hobby's oldest filter trade-off, and here it is a single number.

Parameter Where Default Units Rationale / citation
kLa_contribution_per_h surfaces.pySurface 0.0 1/h Additive O₂ mass transfer from this surface's flow. 0.0 for every non-filter surface, which is what keeps pre-filter scenarios bit-identical (x + 0.0 is exact). Bracketed by two things the model already knows: a still aquarium surface is kLa_O2 ≈ 0.02–0.08 /h (scenario_builder/container_presets.py) and an air stone is 2.0 /h (the aeration lever). Regime placements in the spirit of decision D2 — no citable GPH → kLa map exists at hobby flow rates.
kLa_contribution_per_hfilter_canister SURFACE_PRESETS 0.05 1/h Sealed housing, spray bar below the waterline: high flow, almost no surface disturbance. The CO₂-preserving filter, and the reason every high-tech planted tank runs one.
kLa_contribution_per_hfilter_sponge SURFACE_PRESETS 0.30 1/h An air-lift sponge filter is a weak air stone — the rising bubble column that drives it also aerates.
kLa_contribution_per_hfilter_hob SURFACE_PRESETS 0.80 1/h The waterfall return falls through air and shatters the surface film. 16× the canister. Measured on f16_co2_hob vs f16_co2_canister: holding the same drop-checker-green setpoint costs 4.75× the injected carbon — exactly the kLa ratio (0.95/0.20) — and lands on the same dissolved CO₂. The HOB pays much more and gets the same. (Before the PI fix it paid 3.6× and settled 24 % lower; that "gets less" half was a P-controller artefact, not physics. See Appendix D11 and tech_debt.md §S1.)

Surface agitation — FILTER_AGITATION_KLA

The three preset constants above are what a filter contributes at a typical installation. They are no longer what a builder-made tank uses: a scenario built through the wizard writes an explicit kLa_contribution_per_h resolved from a user-chosen surface-agitation rung, because the preset constant was a single number standing in for a range that spans more than an order of magnitude.

Why this was added. A tester's 35 L sponge-filtered tank measured KH 7 / pH 7.5 — 12.2× atmospheric CO₂ — while the simulation held 1.1× and pH 8.5. The sponge preset's 0.30 /h was 79 % of that tank's entire gas budget and 3.75× the whole still open-tank baseline (0.08). A bubble-column estimate (kLa = k_L·a, a = 6·holdup/d_bubble, k_L ≈ 1e-4 m/s, 4 mm bubbles, 22 cm rise, 35 L) places 0.30 at roughly 1 L/min of air — a vigorously driven sponge — and gives 0.023 /h at 0.1 L/min. Air flow was simply not an input. Re-running that tank at the rung matching the owner's own description ("light bubbling in one corner" → faint) with his real floating-mat cover reproduced 11.1× atmospheric and pH 7.4–7.8, against 12.2× and 7.5 measured.

Rungs are named for what a keeper can see, because that is the only thing they can answer reliably — "air strength" is meaningless on a canister and flow rate is the wrong variable (a canister at full flow with a submerged spray bar exchanges almost nothing).

rung what the keeper sees sponge HOB canister
still glassy, no visible movement 0.01 0.05 0.02
faint a faint ripple in one spot 0.03 0.15 0.05
moderate visible ripple across the surface 0.08 0.35 0.12
brisk rippling with some splash 0.18 0.60 0.25
turbulent churning / broken surface 0.35 0.90 0.40

Bold = the class default (FILTER_AGITATION_DEFAULT), chosen as the typical installation rather than the strongest the class can manage. The canister default is exactly the old preset; sponge and HOB defaults are lower than theirs (0.30 and 0.80 are now reachable at turbulent).

🔒 The class ordering canister < sponge < hob holds at the defaults, and deliberately not rung-by-rung. Once the keeper has told us what the surface looks like, the class stops being the dominant signal: a sponge at a faint ripple is still running a bubble column, and bubbles are gas-liquid interface in the water column that a spray bar's ripple does not have at all. So sponge ≥ canister at a matched appearance is correct. Pinned by tests/test_filter_builder.py::test_class_ordering_lives_on_the_DEFAULTS_not_on_matched_rungs.

Mechanical capture — particles are relocated, never destroyed

A filter advects suspended detritus into its media and holds it. The captured mass moves to a per-surface detritus:trapped:<name> pool (allocated only for surfaces that capture) and mineralises in place: an unrinsed sponge is a nitrate factory, not a nutrient sink. Export happens only on a clean event. See processes/mechanical_capture.py.

Parameter Where Default Units Rationale / citation
mechanical_capture_per_h surfaces.pySurface 0.0 1/h First-order clearance of DETRITUS_SUSP_*. Derived, not guessed: k = tank turnovers per hour × single-pass capture efficiency. Both factors are things the hobby knows — GPH is printed on the box, and a filter clears a stirred-up tank in an hour or two. Scale is the hard part. Heterotrophic bacteria already clear suspended detritus at ≈ 1.1 /h in this model, so a k around 0.02 /h (the "e-folding over a day" intuition) intercepts under 2 % of the particulate flux and is invisible. The values below intercept 27–42 % of it, which is what a filter actually does — not all of it, and it should not be: the bacteria still get most of the fine POC.
mechanical_capture_per_hfilter_sponge SURFACE_PRESETS 0.40 1/h ≈ 1.5 turnovers/h × η 0.27. Slow, but open-cell foam is a deep, highly retentive depth filter.
mechanical_capture_per_hfilter_hob SURFACE_PRESETS 0.50 1/h ≈ 4 turnovers/h × η 0.125 through a thin cartridge pad.
mechanical_capture_per_hfilter_canister SURFACE_PRESETS 0.80 1/h ≈ 5 turnovers/h × η 0.16 through floss + packed media: the best mechanical polisher of the three. Measured on f16_canister: suspended detritus falls to 0.52× the unfiltered control, and 1.38 mg N/L of mulm accumulates inside the media.
k_decomp_trapped_per_h processes/mechanical_capture.py 0.15 / 24 1/h Mineralisation rate of trapped mulm at 25 °C (Q10 = 2, O₂-Monod-gated on bulk O₂ — flow keeps the media oxic, which is what a filter is for). Sits between the abiotic suspended rate (12 %/day, Decomposition) and the abiotic + biotic total a suspended particle really experiences. It is an effective constant that lumps abiotic hydrolysis with the dense heterotrophic biofilm a real filter grows, because HeterotrophicBacteria is a lumped water-column species with no per-surface pools (see internal_docs/planning/decisions/lumped_vs_per_surface_bacteria.md) and cannot be put on the media. Hand-anchored, not fitted: the fate is identical either way (→ NH₄), only the lag differs.
frac_to_DOM / frac_DOM_labile processes/mechanical_capture.py 0.70 / 0.55 fraction Product routing. Same DOM split as Decomposition, but with the settled labile/refractory ratio (0.55, not the suspended 0.70): trapped mulm is aged, compacted material, and the humics it leaches are what tint the water of a filter nobody has rinsed in a year.

Filter cleaning — the mini-cycle

A cleaning: block on a filter surface schedules the classic disaster. Config lives on the surface, not in a top-level block, because cleaning is a property of the filter you clean — and because riding the existing surfaces: path needs no new schema. A tank may declare at most one filter (Surface.is_filter, enforced in config.load_surfaces), matching the builder's single filter selector; "never clean all your media at once" is therefore expressed as biofilm_removed_frac < 1, not by staggering two filters. See engine/filter_maintenance.py and simulation.apply_filter_clean.

Parameter Where Default Units Rationale / citation
biofilm_removed_frac surface cleaning: block 0.50 fraction Fraction of every species pool on the media that a clean strips. 0.50 ≈ swishing half the media in a bucket of tank water; 1.00 = replacing the cartridge outright. The surface's biofilm-maturity index M is scaled by the same factor — scrubbing strips the EPS scaffold, so a cleaned filter is a young filter and recovers on the maturation timescale, not instantly.
slough_to_detritus_frac surface cleaning: block 0.20 fraction Of the biofilm removed, the share that falls back into the tank as settled detritus rather than leaving with the rinse water. It then mineralises to ammonia, deepening the spike rather than sparing it.
trapped_export_frac surface cleaning: block 0.90 fraction Share of the trapped mulm rinsed away. The one term that helps: it is the only route by which particulate N and P leave a filtered tank between water changes.
flow_restored_frac surface cleaning: block 1.00 fraction Epic C. Share of lost flow a clean gives back (clog *= 1 − frac). Default 1.0 — rinsing the media is the act that unblocks them. Declared, not derived from trapped_export_frac: tying them together would smuggle in the mulm → flow map the model refuses to ship.

Filter clogging — a declared flow fraction

Epic C. A clogging: block on a filter surface makes its flow fall over time, and lets that scale the three flow-borne channels: kLa_contribution_per_h, the effective mass_transfer_factor, and mechanical_capture_per_h. It is one non-mass scalar ODE per clogging surface (the biofilm-maturity precedent), gated on Surface.is_clogging, so every scenario without a block is bit-identical.

The whole design is that the flow is declared, never derived. The chain from trapped mulm to lost flow has three links and each is uncitable — and the first is not even a calibration, it is a hard fact about this engine. Full evidence: internal_docs/planning/clog_and_persurface/spike_findings.md.

Parameter Where Default Units Rationale / citation
clogging.flow_fraction surface clogging: block — (1.0 if block absent) dimensionless, (0, 1] The fraction of rated flow the filter passes, seeding clog = 1 − flow_fraction. A calibration by the user, not the model — the model cannot honestly derive it, and does not try. Why not: (a) the driver does not accumulate — trapped mulm is a standing stock (det_trap_ss = capture / k_decomp), measured flat from day 30 to day 365 on f16_clean_none, so an emergent clog would have nothing to integrate; (b) the deposited-mass → porosity-loss coefficient is the deposit's bulk density, which the literature (Clement, Hooker & Skeen 1996, Ground Water 34:934; Taylor, Milly & Jaffé 1990, WRR 26:2161; Vandevivere 1995, Biofouling 8:281) reports as fitted per system, spanning Kozeny–Carman β = 1.05 → ∞ on the measured mulm; (c) porosity → flow needs a pump head curve that puts the clean bed anywhere from 0.03 % to 93 % of system head. Strictly positive, so no channel ever divides by zero.
clogging.clog_rate_per_day surface clogging: block 0.0 1/day Rate the clog closes, d(clog)/dt = k (1 − clog). Default 0 = a held flow fraction (a constant). Also a user calibration — same three uncitable links, now on the rate rather than the level. The (1 − clog) factor makes the state saturate at 1 from below, so flow_fraction stays in [0, 1] and the RHS never drives against a clamp (avoiding the step-collapse the CO₂ PI controller's boundary-freeze once caused; tech_debt.md §S1). The closed form clog(t) = 1 − e^{−kt} is checked directly — f20_hob_reclog lands on e^{−0.08·28} = 0.1065.
kLa_flow_borne_frac surfaces.pySurface 1.0 fraction Epic C. What share of a surface's kLa_contribution_per_h is carried by the water flow, and therefore clogs. A structural claim, not a calibration. filter_canister and filter_hob = 1.0 (spray bar and waterfall both stop when the water stops); filter_sponge = 0.0 (its gas exchange is the air lift — a rising bubble column — which a blocked foam does not stop). Getting this backwards would have a clogged sponge silently suffocate a tank it is still aerating. Measured on F20: an identical clog costs the sponge 0.9 % of its O₂ minimum and the HOB 8.0 %.

Removed mass that leaves the system is booked to the filter_removed_{C,N,P} scalar ledgers — the mirror of the fish-carcass export ledger — so diagnose_mass_balance.py credits it as "− removed" rather than reporting a leak. Measured on the f16_filter_object maintenance rig, same day and same routing, only biofilm_removed_frac differing:

Arm Removed Ammonia peak Nitrite peak Days to re-cycle
f16_clean_none 0.11 mg N/L 0.16
f16_clean_half 50 % 0.37 mg N/L 0.18 1
f16_clean_full 100 % 2.74 mg N/L 1.92 11

2.74 mg N/L of total ammonia at pH 7.8 / 26 °C is ≈ 0.15 mg/L free NH₃ — well past the chronic-damage threshold. "Never clean all your media at once", as a differential equation.

Chemical media — adsorption (Phase 3)

A chemical_media: list on a filter surface loads it with adsorbent: activated carbon, zeolite (clinoptilolite) or GFO (granular ferric oxide). Config lives on the surface, for the same two reasons cleaning: does — media are a property of the filter you load them into, and riding the existing surfaces: path needs no new top-level block. See processes/chemical_media.py.

One kernel, three behaviours. Each medium relaxes toward a Langmuir isotherm at a linear-driving-force rate (Ruthven 1984, §5):

db/dt = k_ldf · ( q_max · C/(K_L + C)  −  b )

Exhaustion, leach-back and hold-on are not three flags — they are what that one equation does at three values of K_L. Adsorbed mass is relocated into a tracked media:bound:<medium> pool, never destroyed: the same "an unrinsed sponge is a nitrate factory" invariant as mechanical capture. The only export is a media swap on a clean event.

Three consequences that look like bugs and are not:

  • Saturation is bounded by the water, not the dose. At equilibrium b/q_max = C/(K_L + C), so carbon in a 5 mg C/L tank cannot exceed 63 % loading however little of it there is. Carbon in a clean tank never fills up; it stops working because biofilm blinds its pores, which this model does not represent. GFO is the medium that genuinely exhausts here.
  • The tank's clearance rate is not the medium's. k_obs = k_ldf · q_max / (K_L · V) scales with the dose and inversely with volume; k_ldf is the medium's property.
  • Once C ≫ K_L uptake is zero-order at k_ldf · q_max, independent of how dirty the water is. That is why a GFO reactor strips at a flat rate until breakthrough.

Scale was set against the incumbent, not by intuition. Every adsorbate already has a sink, and a k_obs far below it makes the medium invisible. Measured on this engine with diagnose_fluxes.py (gross removal ÷ pool):

Adsorbate Incumbent sink Its apparent clearance Why
DOM_REF heterotrophic bacteria 4.0e-3 /h at 0.016 mg C/L HB half-saturate at 0.006 mg C/L, so any stain worth looking at has them zero-order
NH4 nitrifiers 7.7e-3 /h at a 2.2 mg N/L spike; 3.0 /h at 0.004 mg N/L the same Monod saturation, spanning 400× across one cycle
PO4 nothing, in a dark tank 1.6e-5 /h (residence: years) no producers; the bacteria are not P-limited

The 400× span on ammonia is the whole story of zeolite: it wins the spike and loses the plateau.

Parameter Where Default Units Rationale / citation
q_max_mg_per_gactivated_carbon processes/chemical_media.pyMEDIA_SPECS 40.0 mg C / g Langmuir capacities for humic substances on bituminous GAC span ~30–200 mg humic acid/g, i.e. ~15–100 mg C/g at ~50 % C by mass (Summers & Roberts 1988; Newcombe et al. 1997). The conservative middle — §3.3 says bias inert when uncertain. Quoted per gram of element, never per gram of the humic molecule.
K_L_mg_per_Lactivated_carbon MEDIA_SPECS 3.0 mg C/L NOM on GAC half-saturates around 1–10 mg DOC/L. Weaker than the stain it fights (a blackwater tank runs 5–30 mg C/L), so carbon works on the rising limb of its isotherm: it equilibrates at partial loading and genuinely leaches back. The real hobby failure mode, and it emerges rather than being switched on.
k_ldf_per_hactivated_carbon MEDIA_SPECS 0.045 1/h Intraparticle diffusion into GAC macro/mesopores is an hours-to-a-day process (Ruthven 1984 §5); t½ ≈ 15 h. With a 30 g dose in 60 L that is k_obs ≈ 0.30 /h — carbon clears tea-coloured water overnight, which is what it does, and ~75× the heterotrophs it competes with.
q_max_mg_per_gzeolite MEDIA_SPECS 6.0 mg N / g ≈ 7.7 mg NH₄⁺/g. Reported Langmuir capacities for NH₄⁺ on clinoptilolite run 8–22 mg NH₄⁺/g in clean single-salt solutions (Wang & Peng 2010; Hedström 2001), but competing Na/K/Ca in real water take most of the sites. This is an effective in-freshwater capacity at the bottom of the range: the model does not track the competing cations, so the capacity must already have paid for them.
K_L_mg_per_Lzeolite MEDIA_SPECS 20.0 mg N/L ≈ 26 mg NH₄⁺/L, from the same Langmuir fits (1/K_L with K_L ≈ 0.02–0.1 L/mg). Far above any survivable tank ammonia, so zeolite works on the near-linear limb: it takes a fixed share, never all, and never approaches q_max. The implied partition coefficient q_max/K_L = 0.3 L/g (≈ 286 L/kg, in range for freshwater clinoptilolite) means 100 g hides ammonia in 30 L of equivalent water against a 60 L tank — about a third. Holding 90 % would take ~1.8 kg. This is why a real bag cannot stall a cycle.
k_ldf_per_hzeolite MEDIA_SPECS 0.5 1/h Ion exchange is film-diffusion-limited and fast; t½ ≈ 1.4 h. With 100 g in 60 L, k_obs ≈ 0.25 /h — 32× the nitrifiers' apparent clearance at a 2 mg N/L spike, and 1/12 of theirs in a cycled tank. Wins the spike, loses the plateau, without either being coded in.
q_max_mg_per_ggfo MEDIA_SPECS 15.0 mg P / g Genz et al. (2004) fit q_max ≈ 15–24 mg P/g for granulated ferric hydroxide at circumneutral pH. Low end.
K_L_mg_per_Lgfo MEDIA_SPECS 0.05 mg P/L Inner-sphere Fe–O–P bonds. 60× below carbon's K_L and ~20× below the phosphate a fed tank carries, so once P accumulates GFO sits high on the flat plateau of its isotherm, where loading barely tracks the water — it fills up and is thrown away. At equal fractional loading θ, a medium supports C_eq = K_L·θ/(1−θ): a half-loaded GFO holds the water at 0.05 mg P/L, a half-loaded carbon at 3.0. That single ratio is why one leaches back and the other does not.
k_ldf_per_hgfo MEDIA_SPECS 3.0e-3 1/h t½ ≈ 230 h. Because C ≫ K_L the uptake is zero-order at k_ldf·q_max ≈ 1.35 mg P/h for a 30 g charge, so a reactor strips 1 mg P/L out of 60 L in ~2 days and a charge lasts 1–2 months at hobby P loads. Both match the product literature.
max_transfer_frac processes/chemical_media.pyChemicalMedia 0.5 fraction/h A maximum first-order clearance of 0.5 /h on any one medium's transfer — the same guard, and the same value, SoilPSorption puts on its sorption terms. Needed because once C ≫ K_L the driving force is zero-order in C and so unbounded by the pool it draws from. Bites above k_obs = 0.5 /h (a carbon dose over ~50 g in 60 L; a fresh GFO charge meeting a small phosphate pool). It can only slow an approach, never move an equilibrium: the fixed point is b = b_eq, which the cap does not touch.
media_replaced_frac surface cleaning: block 0.0 fraction Share of each chemical medium swapped for fresh at a clean. Defaults to zero: rinsing a sponge does not throw away the carbon, and the two are separate physical acts even though a keeper performs both with the filter open. The bound mass leaves with the spent charge and is booked to the same filter_removed_{C,N,P} ledgers as biofilm and mulm, so diagnose_mass_balance.py credits it as "− removed". Replacing a fraction removes that fraction of the bound mass and leaves q_max alone (fresh media of the same mass go back in).

Alkalinity: all three media are TA-neutral, for three different reasons. This engine's TA state is carbonate alkalinity, [HCO₃⁻] + 2[CO₃²⁻] + [OH⁻] − [H⁺] (chemistry.py), and it treats NH₄⁺ as a conservative cation — ammonification does f[TA] += ΔN, NH₃ volatilization f[TA] += NH3_flux. Neither precedent transfers:

  • Zeolite is ion exchange, NH₄⁺(aq) + Na-Z ⇌ Na⁺(aq) + NH₄-Z. A conservative +1 cation replaces the +1 ammonium, so the solution's charge balance — and hence carbonate alkalinity — is unchanged. (An H⁺-form resin would acidify at 1 eq/mol N. Aquarium clinoptilolite is sold Na/K/Ca-charged; all three are conservative.) Na⁺ is not a tracked pool, so no pool moves.
  • GFO's phosphate ligand exchange releases ~0.3–1 OH⁻ per P over pH 6–8 depending on surface protonation the engine does not carry (Antelo et al. 2005; Arai & Sparks 2001). But phosphate is outside this engine's TA definition entirely — no process anywhere touches TA on a PO₄ flux, producer uptake included — so charging GFO alone with an alkalinity term would make it the model's sole inconsistency rather than a refinement. At hobby P (≤2 mg P/L = 65 µmol/L) even a full 1 H⁺/P stoichiometry is ≤0.065 meq/L against a 2–4 meq/L buffer.
  • Humic acids carry organic alkalinity in reality, but the engine's DOM is a neutral C/N/P pool and organic alkalinity is represented nowhere. DOM_REF_N is organic amine N, not TAN.

Getting this wrong would silently shift pH, which is both a nitrifier kernel and the NH₃-toxicity kernel, so it is asserted (tests/test_chemical_media.py) rather than believed — and scored, as approx no-divergence rows on pH_mean in the F18 registry. Measured: the GFO arm's pH is identical to its control's to 6 significant figures.

Measured, on scenarios/cycling_matrix/f18_chemical_media/ (60 L, dark). Three results that contradict the marketing, none of them tuned for:

Claim Measured
Carbon clears a stain days 1–5 mean dom_ref_C 0.166× the same-filter control (30 g); 0.779× at 3 g
…and gives it back releases 95 % of the 249 mg C it took; ends with 6.8× the control's dissolved humics, having sheltered them from the bacteria
Zeolite buffers a spike ammonia peak 0.83×; 68 mg N sits on the media at peak
…but does not stall the cycle 18 → 17 d, nitrifier stock +1 %. AOB half-saturates at 0.35 mg N/L against a 2.6–3.2 spike: it is substrate-saturated, and losing a third of its ammonia costs it nothing
…and makes nitrite worse NO₂ peak 1.12×. Holding ammonia off the water suppresses NH₃ volatilization (≈ half of all NH₄ removal at this pH), so nitrogen an open tank would have vented survives to be oxidised
…then hands it all back bound N → 0.005 mg by day 60; the maturing biofilter regenerates the zeolite for free
GFO strips and exhausts phosphate 0.52× the control, charge 86 % spent by day 60; recharging on day 30 holds it at 0.19×

Mass balance is exact. Absolute P drift is identical across every arm of each sub-rig (+5.7799e-10 mol on all three carbon arms; −6.2442e-05 mol on all three GFO arms — with media absent, adsorbing 4.1e-3 mol, and exporting 2.6e-3 mol on a clean). Read absolute mol, not %: crediting an export shrinks the expected denominator. Carbon's C is exact too — sealing the headspace collapses its −16 % open-top drift to +4.6239e-08 mol on both arms identically, proving the −16 % is the CO₂ vent the tool never credits, not a media leak.

References: Newcombe, Drikas & Hayes (1997) Water Res. 31:1065; Summers & Roberts (1988) J. Colloid Interface Sci. 122:367; Wang & Peng (2010) Chem. Eng. J. 156:11; Hedström (2001) J. Environ. Eng. 127:673; Genz, Kornmüller & Jekel (2004) Water Res. 38:3523; Antelo et al. (2005) J. Colloid Interface Sci. 285:476; Ruthven (1984) Principles of Adsorption and Adsorption Processes, §5.

The Monod identity that makes m meaningful

A diffusion boundary layer does not change a cell's intrinsic affinity; it inflates the apparent half-saturation the biofilm shows, because the cells sit in a depleted micro-environment. Forced convection thins the layer and pulls the apparent value back toward the intrinsic one. Monod makes "add m × S to the perceived substrate" and "divide the apparent half-saturation by (1 + m)" the same statement:

S' = (1 + m)·S    ⟹    S'/(K + S')  ==  S/(K/(1+m) + S)

Uptake still draws from the bulk pools — only the Monod factor sees the boost — so mass balance is preserved by construction. The source is scaled on ammonia, not on total dissolved inorganic N: in a mature tank nitrate runs ~100× the ammonia, and a DIN-scaled boost would let a filter perceive a replete ammonia supply at zero ammonia and fabricate nitrification capacity.

Nitrite-oxidising bacteria get the same relief applied to their substrate, nitrite. This is not a detail: without it a filter speeds up the ammonia oxidisers, strands the nitrite they produce, and lengthens the cycle from 19 to 22 days — worse than having no filter at all. Forced convection thins the boundary layer over every solute, not just the one you were thinking about.

Flow is the lever; area is a ceiling, not an engine

Measured on the f15_filtration rig — a 60 L tank under a fixed 1.0 mg N/L/day ammonia load, run five ways. The no flow arm is the control: identical media, forced convection switched off.

Arm Filter media Flow Residual ammonia Nitrifier stock Peak areal density Crowding factor
No filter 0.0552 mg N/L 0.327 mg N/L 2.81 µg N/cm² n/a
Same media, no flow 10 000 cm² no 0.0437 0.383 n/a
Undersized 500 cm² yes 0.0351 0.357 35.7 µg N/cm² 0.74
Filter 10 000 cm² yes 0.0241 0.411 2.22 1.000
2× media 20 000 cm² yes 0.0241 0.411 1.11 1.000

Forced convection more than halves the ammonia a fixed bioload leaves standing — that is the hobbyist's "a filter lets me keep more fish." Media area, by contrast, buys capacity only while the areal cap binds: the undersized arm runs at 71 % of the ceiling and pays 1.45× the residual ammonia for it, while doubling an already-ample 10 000 cm² buys nothing measurable.

The no flow row separates two effects a naive filtered-vs-unfiltered comparison would conflate. Simply having media — a rough, sheltered, low-detachment place to live — buys 0.79× the ammonia and 1.17× the nitrifier stock. Flow then buys a further 0.55× ammonia and 1.07× stock on top. So a filter's ammonia advantage is overwhelmingly about convection, while its standing-stock advantage is mostly about being a nicer surface. Both are real; only the first is what "filtration" means.

The benefit grows with bioload, which is the point of it. Doubling the ammonia load doubles the nitrifier population in every arm (1.92× unfiltered, 1.87× filtered — the identity below, confirmed), while the absolute ammonia gap between filtered and unfiltered widens from 0.031 to 0.046 mg N/L.

The reason is a chemostat identity rather than a modelling gap. At plateau, nitrifier standing stock is set by the ammonia supply:

X_steady_state = (load × yield) / (mortality + maintenance)

There is no area term. Flow does not raise the standing stock; it raises the per-cell rate at low substrate, so ammonia settles to a lower steady state. Doubling ample media changes no term in the identity. Area matters only when the biofilm hits the ceiling and can no longer add cells.

This also explains why the literature's 50–100 µg N/cm² is a ceiling no aquarium approaches. Those are wastewater fixed-film numbers measured at areal loads of 1–10 g N/m²/day; this rig runs at 0.08 g N/m²/day. Run the identity backwards and a 10 000 cm² filter would need ~20 mg N/L/day — a fish-kill bioload — before space became its constraint. So a realistically-sized aquarium filter is never space-limited, "more media" saturates quickly, and the knee sits near 1 000–2 000 cm² at a 1 mg N/L/day load.

Guild partitioning falls out of the existing kinetics

No new guild parameters were needed. Because X_fac(AOB)/X_fac(comammox) = (K_cmx + S)/(K_aob + S) rises with S, raising perceived ammonia favours the r-strategist. Measured nitrifier composition on the filtered rig, as comammox's share of nitrifier N:

Location Flow Comammox share
filter_sponge media yes 0.28 %
Glass wall no 3.2 %
Sand bed no 8.4 % (vs 2.2 % in the same tank with no filter)

High-flow, substrate-replete media go almost pure r-strategist AOB + NOB. Meanwhile the filter draws bulk ammonia down, making the static surfaces more oligotrophic — widening the niche of the low-K K-strategist comammox exactly where the design predicted it.

The same partition, measured on a cycled filter-dependent tank (f16_clean_none, day 60, bulk TAN 0.0043 mg N/L), shows the other half of the picture: comammox reaches 87.4 % of nitrifier N on the glass and only 22.2 % inside the sponge. Comammox takes over the quiet surfaces, never the media. docs/microbes.md and docs/species/microbes/bacteria/nitrifier.md said the opposite until Phase 4 and have been corrected; the nitrifier page now also records where this diverges from the survey literature, which samples filters and finds comammox dominant in them.

The builder's filter selector (Phase 4)

What the webapp exposes, and — more importantly — what it refuses to expose. All of these live in scenario_builder/surface_generator.py; the filter is a slot-3 surface emitted by generate_surfaces, and it is stripped for sealed containers exactly like aeration and CO₂ injection.

Param Where Value Unit Rationale / source
_FILTER_AREA_CM2sponge surface_generator.py 7 000 cm² A coarse reticulated foam block. Fixed per class, not a user control — see the note below.
_FILTER_AREA_CM2hob surface_generator.py 5 000 cm² Cartridge floss plus a token handful of bio-media. The smallest of the three, as in reality.
_FILTER_AREA_CM2canister surface_generator.py 10 000 cm² Packed baskets of sintered ceramic. Real hobby filters span 3 000–20 000 cm²; all three values sit inside that range and far above the ~1 000–2 000 cm² knee where the areal cap begins to bind.
CHEMICAL_MEDIA_DOSE_G_PER_Lactivated_carbon surface_generator.py 0.5 g/L The F18 rig charge (30 g in 60 L), on which every measured claim in docs/chemistry/chemical_media.md rests.
CHEMICAL_MEDIA_DOSE_G_PER_Lzeolite surface_generator.py 1.67 g/L 100 g in 60 L — a hobby "ammonia remover" pouch.
CHEMICAL_MEDIA_DOSE_G_PER_Lgfo surface_generator.py 0.17 g/L 10 g in 60 L. A GFO reactor is a spoonful.
FILTER_CLEAN_BIOFILM_REMOVED_FRAC surface_generator.py 0.0 / 0.50 / 1.00 fraction The three user-facing cleaning modes (none / rinse_half / replace_all) mapped onto the surface cleaning: block's biofilm_removed_frac. "Never clean all your media at once" is rinse_half.
_FILTER_CLEAN_TRAPPED_EXPORT_FRAC surface_generator.py 0.90 fraction Emitted only when the biofilm is actually rinsed. Swapping a spent carbon or GFO charge does not wash the mulm out with it (the f18_gfo_replaced shape), and exporting detrital P there would confound the very ledger the user is watching.
_FILTER_CLEAN_SLOUGH_FRAC surface_generator.py 0.20 fraction The engine default, restated at the builder's edge.
filter_clean_interval_days ScenarioInput 30.0 days First clean falls one interval in, matching the water-change convention.

Media area is deliberately not a slider, and this is the phase's product-integrity decision (Appendix D8). A biofilter's standing stock is a chemostat identity in the ammonia supply with no area term (see Flow is the lever above). Measured on F15 at 1.0 mg N/L/day, doubling the media from 10 000 → 20 000 cm² moves residual TAN by −0.29 %, nitrifier stock by +0.07 % and the cycle by 0 days; the filter's share of the tank's nitrifier N saturates too (82.8 % at 500 cm², 89.3 % at 10 000, 89.6 % at 20 000). Every filter a hobbyist can buy sits in that flat region, so a media-amount control would be an inert knob presented as a lever. The values above are also chosen to stay far clear of the ~300 cm² regime where a single-box model's competitive exclusion makes an absurdly small filter score worse than no filter at all (Phase-1 §9).

Chemical-media dose is the opposite, and both controls appear in the same panel, so the UI says which is which. q_max ∝ grams and k_obs = k_ldf·q_max/(K_L·V), so the physically meaningful control is a concentration, not an absolute mass — the same bag clears a nano tank far faster than a 200 L one. Measured (F18): a 30 g carbon charge holds early dissolved humics at 0.166× the control where a 3 g charge holds 0.779× (Appendix D9).

kLa composes additively. Env.kLa_O2_total_per_h = max(container baseline, aeration target) + Σ surface.kLa_contribution_per_h. The max() is right because still-water surface renewal is replaced by agitation, and the sum is right because an air stone and a filter return are independent surface-renewal mechanisms. A "Strong" air stone (2.0 /h) on an air-driven sponge (+0.30 /h) really is 2.30 /h — two bubble columns, not one counted twice. The builder's UI shows the resulting total rather than the target the user picked.


Liquid fertilizer — the builder's mixture presets

frontend/src/lib/store/scenarioStore.ts (LIQUID_FERTILIZER_PRESETS, initial state) and frontend/src/components/setup/LiquidFertilizerConfig.tsx (NUTRIENT_ROWS). These are not engine constants, but they reach the engine as <nutrient>_dosing.amount_mg via perDoseAmountMg, and a wrong default here is indistinguishable — from the tank's side — from a wrong rate constant. They get the same sourcing standard as every other row in this file.

The builder's unit is a weekly target concentration of the element: mg/L/week for N, P, K and µg/L/week for Fe, Cu, Mo, Zn. That is the only form in which published regimes are comparable. A bottle's label is mL per litre of product, a dry-fert schedule is teaspoons per gallon per dose, and both carry tank size and dosing frequency inside them; the weekly-element form divides those out. The store multiplies back up by the tank's water volume and the dosing interval, so a user who changes "every N days" never changes the weekly nutrient load.

Reference regimes

Every figure below is derived from a published label dose or guaranteed analysis. Guaranteed-analysis percentages are % w/v, so 1 % = 10 mg of element per mL of product.

Regime Label dose N P K Fe Cu Mo Zn Mg
Tropica Specialised Nutrition 5 mL / 50 L, weekly 1.30 0.10 1.00 70 6.0 2.0 2.0 0.40
2Hr Aquarist APT Complete 5 mL / 100 L, 4×/wk 1.63 0.91 15.2 200 1.60
NilocG Thrive 2 mL / 10 US gal, weekly 1.35 0.36 5.0 250
NilocG Thrive same, 3×/wk (label max) 4.06 1.08 15.0 750
PPS-Pro 1 mL macro + 0.5 mL micro / 10 gal, daily 1.58 0.23 9.3 ~350 0.70
Seachem Flourish (traces only) 5 mL / 250 L, 2×/wk 0.004 0.12 128 0.04 0.36 0.28 0.044
EI, high light ¼ tsp KNO₃ + 1/16 tsp KH₂PO₄ + 1/16 tsp CSM+B, 3×/wk, 20–40 gal 4.1–8.2 1.0–2.3 20–30 500–1000 7–14 4–9 29–57
EI, low tech (Barr: 5–10 % of the above) 0.23–0.68 0.05–0.23 1–3 25–100 0.4–1.4 0.2–0.9 1.5–5.7

Macros are mg element/L/week, micros µg element/L/week. Sources: Tropica Specialised guaranteed analysis and dosage (N 1.3 %, P 0.1 %, K 1.0 %, Mg 0.4 %, Fe 0.07 %, Cu 0.006 %, Mo 0.002 %, Zn 0.002 %); APT Complete dosing (per 5 mL/100 L: K 3.8, NO₃ 1.8, PO₄ 0.7, Fe 0.05, Mg 0.4 ppm); NilocG Thrive (per pump per 10 gal: NO₃ 6, PO₄ 1.1, K 5, Fe 0.25 ppm); Perpetual Preservation System (daily: NO₃ 1.0, PO₄ 0.1, K 1.33, Mg 0.1 ppm); Seachem Flourish guaranteed analysis (Fe 0.32 %, Cu 0.0001 %, Mo 0.0009 %, Zn 0.0007 %, Mg 0.11 %, soluble potash K₂O 0.37 % → K 0.31 %; this one is quoted % by weight, so the row above takes the product's density as ≈ 1 g/mL); EI schedule and targets and the original Barr EI method (weekly cumulative NO₃ 20–30, PO₄ 3–7, K 20–30, Fe 0.5–1.0 ppm; 5–10 % of that for a low-tech tank); Plantex CSM+B analysis (Fe 7.0 %, Mn 2.0 %, Zn 0.40 %, Cu 0.1 %, Mo 0.06 %, Mg 1.5 %).

Two conversions carry real uncertainty and are flagged rather than hidden. Teaspoon → gram for a dry fert is ±20 % depending on how the powder packs (¼ tsp KNO₃ ≈ 1.5 g at ~1.2 g/mL bulk), which is why the EI row is quoted as a range across the 20–40 gal band rather than a single number. And EI sources disagree on PO₄ — the tsp schedule integrates to 5–7 ppm/week, while the commonly-quoted target is 3 ppm — so the preset takes the middle of the published 3–7 band.

Nutrient ratios are not a constant across regimes, and the UI no longer claims they are. N:P by mass runs 1.8:1 (APT), 3.8:1 (Thrive), 4.3:1 (EI mid-band), 6.9:1 (PPS-Pro) and 13:1 (Tropica), with Redfield at 7.2:1. An all-in-one aimed at a stocked tank deliberately runs P-rich relative to Redfield, because fish waste supplies the balance of the N. The trace block is far more stable: expressed against the mix's own Fe, CSM+B is Cu 1.4 %, Mo 0.86 %, Zn 5.7 %, and every preset's trace block is filled in on those ratios where the product itself does not publish Cu/Mo/Zn.

The presets

Preset Anchor N P K Fe Cu Mo Zn
all_in_one Median of the three all-in-one label doses (Tropica / APT / Thrive at 1×/wk); traces on the CSM+B ratio 1.4 0.35 5.0 150 2.0 1.3 8.5
ei Mid-band of Barr's high-light targets — NO₃ 25, PO₄ 4, K 25, Fe 0.5 mg/L per week — converted to the element 5.6 1.3 25.0 500 7.0 4.3 28.5
macros_only PPS-Pro's published daily macro dose summed over a week 1.6 0.25 9.0 (off) (off) (off) (off)
trace_only The trace half of all_in_one, i.e. a comprehensive trace mix at label rate (off) (off) (off) 150 2.0 1.3 8.5

all_in_one is also the store's initial per-nutrient state, because setLiquidFertilizerEnabled(true) on an empty mix applies that preset anyway; keeping the two in step means a hand-built mix starts from a real label dose.

Slider bounds

Nutrient min max step Rationale
Nitrogen 0.05 12 0.05 mg N/L/wk. Min is a third of the leanest low-tech regime; max is 2× the EI preset (NO₃ ≈ 53 ppm/wk)
Nitrogen (ammonium form) 0.05 1.0 0.05 NITROGEN_AMMONIUM_MAX_WEEKLY_DOSE, an order of magnitude below the nitrate ceiling. A 1 mg N/L weekly TAN pulse is ~0.18 mg NH₃-N/L at pH 8.5 / 26 °C via ammonia_fraction_unionized — the top of the sublethal band, below acute LC50s. setNitrogenDoseForm clamps to it on the form change; without that the cap is cosmetic, since the EI preset's 5.6 would survive the switch and the slider would sit pinned at a max it cannot reach
Phosphorus 0.01 3.0 0.01 mg P/L/wk. Max is 2× the EI preset (PO₄ ≈ 9 ppm/wk)
Potassium 0.1 50 0.1 mg K/L/wk. Max is 2× EI
Iron 5 1000 5 µg Fe/L/wk. Max is 2× the EI preset and also the top of the published EI Fe band (1.0 ppm/wk)
Copper 0.02 15 0.02 µg Cu/L/wk. Max is 2× EI. Toxicity is a function of free Cu²⁺, not dosed Cu — see Copper toxicity above; the chelate selector is what decides whether a 7 µg/L dose is a fertilizer or an algicide
Molybdenum 0.02 10 0.02 µg Mo/L/wk. Max is ~2× EI
Zinc 0.1 60 0.1 µg Zn/L/wk. Max is ~2× EI

Each amountMax is set at or above 2× the corresponding ei preset value, which is exactly LIQUID_FERTILIZER_STRENGTH_MAX. That is not a coincidence but the constraint: the strength control rewrites every nutrient to preset × strength, so a ceiling below 2× the richest preset would let strength drive a slider past its own scale. At the other end, 25 % strength on all_in_one is N 0.35, P 0.09, K 1.25, Fe 38 µg/L/week, which lands inside Barr's low-tech band — so the strength rungs span "leanest regime anyone runs" to "twice full EI" with the presets as authored.

What was wrong before, and what the engine actually does with the fix

The previous values were 25–130× below every regime in the table above — N 0.03, P 0.007, K 0.1, Fe 3.3 µg, Mo 0.015 µg per week on the all_in_one preset. They were never sourced: they were the old per-dose milligram amounts divided by 30 L when the UI moved to a weekly-concentration unit, and the milligram amounts were themselves the engine's dosing-test fixtures rather than a dosing regime. Even Barr's low-tech guidance — 5–10 % of full EI, the leanest thing in the literature — is 7–20× higher than the P the builder recommended, and the phosphorus slider's ceiling (0.1) sat below a normal dose.

The engine was checked for over-response before the numbers were changed, because "the doses are low on purpose, the model is twitchy" is the obvious competing explanation and it would have been the more important finding. It is not what happens. Nine 365-day runs on scenarios/walstad_planted_aquarium_365day.yaml — a 20 L soil Walstad with Salvinia, Cryptocoryne, Vallisneria and a shrimp/snail community — with the builder's default floating trim added (cover_threshold 0.50, leave 30 %, which every builder-produced scenario carries and that fixture does not):

Arm PO₄ NO₃ K pH O₂ min peak algae Crypt shoot
control, no dosing 0.017 0.009 8.0 8.15 6.10 0.297 2.53
old preset 0.016 0.021 9.6 8.19 6.11 0.303 2.54
new all_in_one 2.70 2.99 123 8.60 6.12 0.312 0.016
new all_in_one + 25 %/wk water change 0.50 3.50 23.1 8.12 6.56 0.306 2.53
new ei 25.0 103 637 8.63 6.14 0.331 0.000
new ei + 50 %/wk water change 2.29 11.1 54.4 8.06 5.15 0.316 2.60

Day 365 unless stated; concentrations mg element/L, algae the peak algae_N_mgL over the whole run, O₂ the minimum over the whole run. The fixture's own maintenance is 20 % every 60 days, an export of ≈ 2.3 %/week against a weekly dose.

No runaway algae, no crash, no stiffness. Peak algal biomass moves +3 % (all_in_one) to +7 % (ei) against the no-dosing control — that peak is the week-4 diatom bloom, which is silica- and light-limited, not fertilizer-limited. Minimum dissolved O₂ is higher with dosing paired to its water change (6.56 vs 6.10 mg/L), because more plant biomass means more daytime production. All nine runs integrated to day 365 cleanly at default tolerances, in the same wall-clock band as the control.

The one thing that does break is not a dose response but a maintenance-schedule mismatch, and it is worth stating precisely because it first looked like an over-response. Dosed at the all_in_one rate against the fixture's 2.3 %/week export, the Cryptocoryne collapses from day ~180 and is gone by day 365. Three ablations locate the cause:

  • Phosphorus alone is not it. Raising only P to the new rate — 50× the old, letting PO₄ accumulate to 7.2 mg P/L — and leaving every other nutrient at the old rate leaves the Crypt at 2.545, the epiphyte layer at 0.0003 and pH at 8.19, all indistinguishable from the control. Under the old preset the tank is nitrogen-limited, so excess P does nothing at all.
  • It is not canopy competition. Deleting the Vallisneria slows the collapse without stopping it (0.357 vs 0.016 at day 365).
  • The discriminator is algae_surf_N_mgL, the epiphyte film on the macrophyte leaf surface: 0.0001 in the control, and a sustained 0.026–0.047 in every arm where nitrogen is dosed at a real rate without a matching export. That is the Phillips–Eminson–Moss epiphyte-shading route by which nutrient enrichment removes submerged macrophytes, and the Cryptocoryne is the plant it takes first because this fixture puts it at geometric_light_frac 0.28, the dimmest position in the tank.

Pair each regime with the water change it is defined to include and the effect disappears. all_in_one + 25 %/week holds PO₄ at 0.24–0.50 mg P/L, NO₃ at 2.6–3.5 mg N/L and K at 23 mg/L, all ordinary planted-tank readings, with the Crypt at 2.53 against a control 2.53, Vallisneria 11 % above control, and the +0.45 pH rise gone (8.12 vs 8.15). ei + 50 %/week settles at PO₄ 2.1–2.3 mg P/L, NO₃ 10–11 mg N/L and K 54 mg/L, which is what an EI tank reads.

The sign of the model is right and its magnitude is defensible, so the conclusion is the opposite of "keep the doses low". The old values only looked stable because they held the tank permanently nitrogen-limited, which hides the mechanism rather than getting it right.

Open gap, not closed here. A dosing regime is a dose and an export, and the builder lets a user pick the first without the second: waterChangeFrac defaults to 0. Choosing ei and leaving water changes off gives K 637 mg/L and NO₃ 103 mg N/L after a year, a faithful simulation of a regime nobody runs. The panel copy now names the water change each regime assumes; coupling the two controls is a separate change.


Cycling stage — the starting inoculum

scenario_builder/cycling_presets.py. A new tank's microbial community depends entirely on how it was started, and the difference between methods is the largest single lever on how long the tank takes to cycle. Each stage is a set of multipliers applied to the per-species auto_seed_per_L / auto_seed_N_mg values in species_metadata.py at scenario-build time. seeded is the reference baseline (multiplier 1.0 throughout — the metadata values are tuned to it); every other stage scales away from it. A species with no entry in a stage defaults to 1.0.

Nitrifier multipliers

Stage aob nob comammox AOB:NOB gap Source / rationale
uncycled 0.01 0.003 0.001 Chlorinated municipal tap. Chlorine sterilises the tank; NOB are more chlorine-sensitive than AOB (Holler & Bachofen 1969; Regan et al. 2003; Wahman et al. 2009 — the conservative end of a 3–10× reported range).
water_only 0.01 0.003 0.001 Identical to uncycled by design. Nitrifiers are biofilm-attached, so donor water moves a negligible inoculum (Del'Duca et al. 2019: biofilm abundance climbs continuously while water-column abundance does not change significantly).
lightly_seeded 0.05 0.015 0.005 A freshly set-up planted tank: epiphytic nitrifiers arriving on established plant leaves and roots (Eriksson & Weisner 1999; Körner 1999), plus the customary media squeeze. 5× the tap floor.
bottled 0.30 0.10 0.002 A dose of bottled nitrifiers. 30× the tap floor on AOB, but comammox stays at the floor — no bottled product delivers a slow-growing K-strategist. The AOB:NOB gap encodes Nitrobacter-vs-Nitrospira (Hovanec & DeLong 1996; Hovanec et al. 1998). See the calibration note below.
seeded 1.0 1.0 1.0 A squeeze of filter media or a cupful of substrate. No asymmetry — a media transfer moves the intact biofilm, Nitrospira included, rather than whichever organism survived a fermenter and a warehouse shelf.
cycled 10.0 10.0 20.0 Media/substrate transferred in quantity (hobby rule of thumb: about a third of the donor's media). Comammox gets 20× because they dominate mature freshwater biofilters (Bartelme 2017; Sauder 2017).

Non-nitrifier multipliers where they differ from the uncycled floor

Stage heterotrophic_bacteria denitrifier planktonic algae / rotifer / ciliate / nanoflagellate Rationale
water_only 0.40 0.01 0.10–0.25 (5× the floor) These guilds genuinely are planktonic and travel with the water. Benthic algae and benthic cyanobacteria stay at the floor because they are attached and do not.
bottled 0.05 (= floor) 0.003 (= floor) floor A bottle of nitrifiers is not a plankton culture.
cycled 5.0 5.0 3.0–5.0 Substrate transfer carries the whole community.

The bottled AOB:NOB gap is measured, and the first guess was wrong

This tier was drafted with a 15× AOB:NOB gap, reasoning that "the bottle carries the wrong NOB" deserved a much wider asymmetry than the 3× chlorine selectivity in uncycled. A sweep on the F4 rig (60 L bare fishless, 2 mg N/L conditional dosing, 26 °C, pH 7.8, AOB held at 0.30) falsified it:

NOB seed cycle_complete_day NO2_peak_mgL
0.02 (15× gap) 36 13.1
0.04 33 9.64
0.06 32 6.47
0.10 (3× gap, shipped) 29 4.13
0.15 29 2.46
(uncycled reference) 34 4.32

At any gap wider than ~3× the model claims a bottled dose leaves the tank slower and its nitrite spike up to 3× worse than doing nothing at all. The only observation supporting that is a single confounded tank in the ISME 2025 home-biofilter survey, which is not enough. At 0.15 the spike is relieved instead, which over-sells the product. 0.10 is where the emergent behaviour matches the literature without over-claiming in either direction, and it tells the right story through timing rather than magnitude:

vs uncycled — cycle 29 d (−5), NO₂ peak 4.13 (0.96×, unchanged), NO₂ peak day 13.9 (−10), days above 1 mg/L 6.8 (+1.5). The AOB head start pulls the whole cycle forward, so ammonia clears early, but the nitrite phase arrives sooner and then drags because NOB is behind.

That is the most common complaint levelled at these products, and it is emergent here rather than asserted. The evidence for the tier being modest at all: Scagnelli et al. (2022), the only peer-reviewed test, found four of five quick-start products produced no statistically significant TAN decrease over 14 days in naïve 10-gallon aquaria; only Tetra SafeStart Plus did, taking the full fortnight to go 1.0 → 0.29 ppm.

Two levers deliberately not built

Both were measured during the same phase and both came back marginal.

Seed placement is not modelled. simulation.build_initial_state splits a BIOFILM_RESIDENT species' surface share evenly by surface count, so a "transferred filter media" seed lands only ⅓ on the filter in a glass + sand + filter tank — even though the filter perceives (1+m) = 4× bulk ammonia and is where the bacteria physically came from. Measured on F15 by holding the total seed constant and moving only its placement: 100 % on the filter cycles in 17 d against 19 d for the even split, and 100 % on glass also 19 d. 2 days at an unphysical 100 % concentration is the ceiling; a realistic transfer seeds the glass and substrate too, so the true effect is nearer 1 day. Not worth a per-surface seeding schema.

Initial biofilm maturity is not set by the builder. initial_conditions["biofilm_maturity"] already exists and is already applied (as one scalar to every surface), so the builder could set it for the seeded tiers with no engine change. It does not, because maturity is a steady-state lever, not a cycling one. Measured on the same rig:

biofilm_maturity at t=0 cycle_complete_day NO2_peak_mgL TAN_residual_mgL final nitrifier N mg/L
0.0 (shipped) 19 6.011 0.0241 0.411
0.3 19 5.926 0.0197 0.438
0.6 19 5.849 0.0146 0.473
0.9 22 5.779 0.0085 0.525

Zero days off the cycle up to M = 0.6 and three days worse at 0.9 (the extra perceived N via the maturity-scaled diffusion-boundary-layer sources accelerates AOB more than NOB, lengthening the nitrite tail). What maturity does move is the plateau: residual TAN falls 2.8× from M = 0 to M = 0.6 and standing nitrifier stock rises 28 %. That is the real "a mature tank holds ammonia lower" effect, and it belongs to the biofilm-maturity model rather than to how the tank was started.