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_fac — K_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 formerdeath_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 ininternal_docs/planning/tech_debt.mdfor 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 | Derived — Physa 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 | Derived — Neocaridina 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_inclusiveflag 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-deficitstarvation m_maxstays 0 — under-feeding manifests mechanistically as condition wasting (W shrinks → c falls → thec_deathwasting 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:protected → CU_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 formf(M) = M(1+K)/(M+K)with K = 0.25 (endpoint-preserving, so everygeoandprotkeeps 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.py → DYNAMIC_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_frac0.55 andgrazer_access0.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 thelightly_seededcycling tier. Recalibrating these is a separate change with its own A/B: seeinternal_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.py → Surface |
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_factor — filter_sponge |
surfaces.py → SURFACE_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_factor — filter_canister |
surfaces.py → SURFACE_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_factor — filter_hob |
surfaces.py → SURFACE_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
mis one calibrated constant and not three derived ones. The Option-B spike (internal_docs/planning/option_b/b_spike_verdict.md) tried to derivemfrom media geometry: interstitial velocity → Reynolds → Sherwood (Wakao–Funazkri 1978, valid over the whole hobby range 3 < Re_p < 10⁴) → external mass-transfer coefficientk_L, referenced against a static wall'sk_L = D/δ. Two results, and both are load-bearing.
- 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 derivedmspans 0.19 … 197. There is no citable number here. The correct relation isK_app = K_int + J_max/(2 k_L)— a boundary layer adds to the half-saturation, wheremdivides it — and the two agree only in the transport-limited limitJ_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.- The ordering is derivable, because
δandJ_maxcancel 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 everyJ_max; the old presets declared(1+3)/(1+6)= 0.571. Guarded bytests/test_filter_plumbing.py::test_a_canister_never_out_flows_a_sponge.So
mis one calibrated constant. What actually separates the presets iskLa_contribution_per_h(a 16× span) andmechanical_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:
- 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. - Filter media are never buried in the substrate. In a soil tank, nitrifiers route
pore_fractionof 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, sonitrifier.py::_flux_surfacesruns 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 atd(PORE_NO2)/dt = +1.0e-06 mol/hfrom 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.py → Surface |
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_h — filter_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_h — filter_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_h — filter_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.py → Surface |
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_h — filter_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_h — filter_hob |
SURFACE_PRESETS |
0.50 |
1/h | ≈ 4 turnovers/h × η 0.125 through a thin cartridge pad. |
mechanical_capture_per_h — filter_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.py → Surface |
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_ldfis the medium's property. - Once
C ≫ K_Luptake is zero-order atk_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_g — activated_carbon |
processes/chemical_media.py → MEDIA_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_L — activated_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_h — activated_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_g — zeolite |
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_L — zeolite |
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_h — zeolite |
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_g — gfo |
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_L — gfo |
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_h — gfo |
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.py → ChemicalMedia |
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
TAon 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_Nis 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_CM2 — sponge |
surface_generator.py |
7 000 |
cm² | A coarse reticulated foam block. Fixed per class, not a user control — see the note below. |
_FILTER_AREA_CM2 — hob |
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_CM2 — canister |
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_L — activated_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_L — zeolite |
surface_generator.py |
1.67 |
g/L | 100 g in 60 L — a hobby "ammonia remover" pouch. |
CHEMICAL_MEDIA_DOSE_G_PER_L — gfo |
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 atgeometric_light_frac0.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 | 3× | 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 | 3× | 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 | 3× | 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 | 3× | 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 | 1× | 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 | 1× | 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.