Synapse Reef The Hot Brook lakes of eastern Maine

Part 4: The model and what building it taught

On this page

The Hot Brook lakes of eastern Maine — part 4 of 5

← Synthesis II: fish, early life, predation, wildlife and forest · Contents · Discussion, data availability and the use of AI →

4. The model (Methods)

The model is a spatially explicit, individual-based simulation of Upper and Lower Hot Brook Lake and the brook between them: a three-dimensional water and chemistry model, plants and invertebrates as fields, fish as agents with their own neural networks and published bioenergetics, and the wildlife, anglers and camps that take from or add to the lakes. It is written as pure JavaScript modules (src/w3/) that run in Node and in a browser worker, and it inherited, then re-based on field values, the calibrated rates of an earlier two-dimensional slice model of a generic lake (src/). What is described here is the "package": every mechanism built so far, switched on together by one function (stageR5 in src/w3/fish3.js), each switchable for A/B comparisons (Table 4.2); section 5's findings come from it and from its earlier states. Most parameters in src/config.js and the modules carry their source in a comment or are marked as an inference — here "(project estimate)". The package is described as committed on 23 October 2026 (commit cf70977); the last arms in section 5 (arm AM, 22–23 October) ran before two of its pieces were added, the camps' effects and the young white perch's move to the bed at 2 cm.

4.1 The world

The geometry comes from public data (tools/hotbrook/). Terrain and lake outlines are from the USGS 3DEP lidar (Maine Eastern B1/B2, 2017), whose hydro-flattened water surfaces put the lakes at 128.93 m (Upper) and 128.23 m (Lower). The beds are from the 1949 MDIFW survey maps (revised 1965 and 2004): their 146 spot soundings were located on the scans, fitted to today's shoreline by trimmed iterative closest point (median misfit 18 m) and interpolated. The shallowest fringe (fully to 1 m, fading out by 1.5 m) is from the visible-bottom band of NAIP aerial photographs, its dark edge set at 1.3 m by angler observations (project field notes); the photographs had no skill against held-out soundings at 1–3 m, so they set only the fringe. Land cover is NLCD 2021 with the National Wetlands Inventory over it. On this geometry Upper covers 369 ha (mean depth 2.99 m, maximum 5.52 m in its north basin by the outlet) and Lower 274 ha (2.57 m, 4.12 m); 44 % and 55 % of them lie at ≤ 3 m. The brook is 154.6 m long and ~8 m wide, with a pool of 1.06–1.13 m at its upper mouth and riffles of 0.35–0.45 m (profile from angler observations). Water runs south to north.

There are two worlds. The true-scale world, the viewer's default and the world of the year runs, is a band of 455 × 1,385 cells of 5 m covering the lakes and ~150 m of land around them. The older 1/10 world divides horizontal lengths by ten at true depths (1.5-m cells, 6.4 ha of water, the brook at half its length) and remains where most CPU checks and probes run. Distance-dependent physics uses real lengths in both worlds, and landscape distances (home ranges, search radii) are written as real meters × scale. Because the 1/10 world steepens slopes ten-fold and makes the brook ~25 times its real share of the shallows, habitat and predation are judged at true scale. The water is a graph of columns 50 m across (real), each with 0.5-m layers to its bed — 2,622 columns and 15,072 cells at true scale — with the brook given its own 20-m stretches so its pool and riffles are not averaged into its banks. The bed keeps the geometry's cells, each holding an organic layer, bed animals, plants, mussels and a substrate (rock, gravel, sand, organic) mapped from wave exposure and shore type, which sets crayfish shelter, rooting room and spawning substrate.

4.2 Time, the calendar, weather and the catchment

The clock is real time (a year is 365 × 86,400 s); the 2-D model's per-second rates enter multiplied by 1/17,520, the ratio of its 30-minute year to a real one. Fidelity changes the time step, never the clock. Fish near a viewer take 0.1-s steps, deciding every second step (5 Hz); far fish then live staggered 60-s blocks. The gate and the year runs use coarse blocks of 1,752 s (~29 min), in which each fish's brain decides once, the fish moves in at most six hops toward where its drives point as bent by its brain, then wanders, and it feeds, grows, spawns and is exposed to predators over the block. The water is updated once a block.

The surface-temperature target is a "Maine calendar", a monotone cubic through 13 knots: ice-out at ~4 °C around 23 April, 10 °C around 12 May, a 24 °C peak at the end of July, below 10 °C again around 15 October and ice-on around 1 December — 208 days below 10 °C, matching the 208 ± 4 days reported for Spednic Lake ~30 km east (Dudley & Trial 2014). Runs open on 20 May with "the season's young so far", spawned over each window's first ten days and grown at 0.73–0.5 of maximum consumption, a start calibrated against the lakes run from ice-out.

The weather has four sky states (clear, cloudy, rain, storm; winds 2.5, 4.0, 6.5 and 10 m/s) in a frontal cycle with mean spells of 1.0, 1.6, 0.6 and 0.5 days (× a uniform 0.6–1.4) and gamma(2)-distributed rain per wet episode, fitted to Houlton's daily record (NOAA GHCN-Daily USW00014609, 1991–2020; Table 4.1). Air temperature is Houlton's monthly normal plus a synoptic Ornstein–Uhlenbeck anomaly (SD 2.6–6.5 °C by month, time constant 3 days), a seasonal one (SD 1.0 °C, 30 days) and the storms' warm air in winter (Houlton's wet days up to ~5 °C above the month's mean). The water's target moves 0.75 °C per °C of air anomaly (project estimate). The weather has its own random stream, so changes to the fish or plants cannot change a seed's weather.

The catchment is a conceptual model with the HBV structure (HBV n.d.) — a degree-day snowpack, Hamon's potential evapotranspiration, a soil store and quick and slow runoff stores — driven by Houlton's precipitation (998 mm a year). Its seven parameters were fitted inside HBV's usual ranges by 1,000 random draws (30 years × 2 seeds each) to the monthly flow ratios of Wytopitlock Stream (USGS 01030350) and the Mattawamkeag River (Table 4.1). The flow scales the lakes' through-flow by Q/Q_ref, keeping mean residence at ~100 days in Upper and ~55 in Lower, and sets the brook's depth as (Q/Q_ref)^0.4 (Leopold & Maddock 1953).

Table 4.1. The weather generator (60 years × 2 seeds) and the fitted catchment model (60 years × 3 seeds) against their targets. Fitted catchment parameters: field capacity 82 mm, β 2.72, LP 0.39, quick-store recession 0.196 d⁻¹, percolation 0.21 mm d⁻¹, slow-store recession 0.0048 d⁻¹, snowmelt 4.61 mm d⁻¹ °C⁻¹.

StatisticTargetModel
Wet days (≥ 0.25 mm), Houlton39 %39–40 %
P(wet | wet)0.500.52
Mean wet / dry spell2.0 / 3.1 days2.1 / 3.1 days
Days ≥ 25.4 mm a year6.96.1–7.0
CV of monthly totals0.440.47–0.52
Annual runoff, eastern Maine gauges580–710 mm582–592 mm
April / August flow ÷ mean3.3 / 0.30–0.332.75–2.79 / 0.40–0.60
Daily storm recession0.81–0.880.85–0.87
December flow ÷ mean1.13–1.410.86–1.01 (a known misfit)

Ice forms column by column, first in sheltered coves (an exposed column must be 0.12 °C colder per m/s of wind × its exposure). It thickens by Stefan's law, h = α√(freezing degree-days), α falling from 2.7 to 1.3 cm (°C·d)^−½ under deep snow. Snow on the ice is 0.7 of the season's snowfall (project estimate) and floods to white ice when its load exceeds the freeboard. Light under ice is a layered Beer–Lambert transmission with Donini et al.'s (2026) median albedos and extinction coefficients, so 40 cm of black ice passes ~33 % and 10 cm of snow on it ~1.8 % (Maine measurements 1–12 %). The cover goes only once melted through.

4.3 Physics and chemistry

Each column's temperature relaxes toward the calendar target plus the air anomaly, with a diel swing wider in thin water; there is no explicit surface heat budget. Wind mixing (6 m at ordinary wind) and night convection (6 m) keep the basins (≤ 5.5 m) from staying stratified. Below 4 °C colder water floats, and under ice the bed's stored heat warms the water above it toward 4 °C. Transport is conservative finite-volume: a wind-driven, depth-averaged circulation from two precomputed friction-dominated fields (RMS 2 cm/s at 5 m/s wind) with a surface drift of 1.2 % of the wind and its return flow; grid-scale horizontal diffusivity K = 3.6 × 10⁻⁴ L^1.07 m² s⁻¹ (Lawrence et al. 1995); a night thermal siphon down the slopes at 0.9 cm/s on calm nights (Doda et al. 2022); a 3-mm/s density current under ice; damping of currents in shallow water by up to ~90 % (bottom friction and summer weed beds, as a function of depth); and the through-flow, solved implicitly. The free surface and Langmuir cells are not simulated. Each column's effective fetch (16 directions) gives the depth stirred by a 10-m/s storm's waves (Coastal Engineering Manual hindcast; 0.7–1.2 m here). A color term of 0.4 m⁻¹ for the stained water gives a summer Secchi depth of ~3.3–3.5 m (§5.5).

Re-aeration follows the lake-size wind model k₆₀₀ = 2.51 + 1.48U + 0.39U·log₁₀A cm/h (Vachon & Prairie 2013) with a convective night floor and none under ice, and saturation follows Garcia & Gordon (1992). Oxygen is made by phytoplankton, plants and the bed's algae, and used by their respiration, by bacteria decomposing dissolved organic matter (DOM), by nitrification (4.6 g O₂ per g N), by the bed's demand and by every fish in its own cell. Nitrogen and phosphorus are carried as ammonium, nitrate and phosphate, in four algal groups, in DOM, in the bed's bound-P store and in the plants. The inflow carries ~14 µg/L of total P, almost all of it as phosphate, and its inorganic N is 95 % nitrate; a version with the field's P forms was built, tested (section 5.2) and is switched off. The bed captures dissolved P through a diffusive boundary layer, receives settling algae, buries bound P, and releases P by a temperature-driven oxic flux (Q₁₀ 2.5; after Søndergaard et al. 2003) and under anoxia. Burial was refitted on the true world's grid to a retention of ~0.48 by the second year, inside the 0.28–0.54 that four published retention models give for these lakes' flushing (section 5.2). The bed's organic layer receives settled algae, dead plants, faeces, carcasses and a catchment subsidy of 800 g wet m⁻² yr⁻¹, half of it an autumn leaf fall (late September to mid-November) weighted to the shore (project estimate); its decay is the bed's O₂ demand.

A ledger records every input, output, burial, denitrification and fixation, and the N and P inventories of water, bed and plants must close against it (section 4.8). Animals are energy pools outside these inventories: the N and P in what they eat returns to the water at once. Every flow across the lakes' edge passes through the ledger, including plants carried ashore by moose and deer or pulled from swim areas, the alewives' import and export, and the camps' loads.

4.4 Producers and invertebrates

The four algal groups are edible greens, diatoms, nitrogen-fixing cyanobacteria and large grazing-resistant algae. Growth is per capita, limited by light, temperature and nutrients, with a P half-saturation of 1 µg/L for all but the cyanobacteria (Edwards et al. 2015's compiled median is 1.08); each group sinks at its own speed (greens and resistant algae 0.1, diatoms 0.5 m/day), and lysis is 0.08 a day at 20 °C. Zooplankton are biomass fields for Daphnia, small cladocerans (Bosmina, Ceriodaphnia, Chydorus, Diaphanosoma), copepods (with a seasonal naupliar share of 10–34 %) and rotifers, with resting-egg banks. Each grows from what it eats by a Holling type II response with field clearance rates (Daphnia 1.0, copepods 0.4 mL µg⁻¹ d⁻¹), starves below maintenance, and is eaten by invertebrate predators (0.05 of young Daphnia a day at 20 °C); copepods persist by lower losses and ~30 % autumn dormancy, and rotifers and cladocerans also eat bacteria grown on DOM. Weed beds give a refuge.

The invertebrates are energy pools (g wet m⁻²) on each bed cell. Worms and scuds eat the organic layer (capacity 15 g/m²), and from late June a fifth of the fauna of soft, oxic mud rises at dusk over 12 days as the hatch of the mayfly Hexagenia. Weed fauna, in two sizes at ~30 mg wet per g of plant dry mass, produce 0.10 and 0.04 a day at 20 °C and emerge on degree-days from ice-out. Snails are capped by soft water (calcium unmeasured at Hot Brook). Surface insects are emergers plus land insects falling from forested banks (~50 mg dry mass per meter of bank a day at the July–August peak). Virile crayfish, adults and the year's young, are held at capacities by shelter that the package sets at a fifth of Michigan-based values (rocky shallows 5 g/m²) for the soft water (project estimate). Eastern elliptio mussels reach 15/m² on firm margins and 40 in sheltered coves, recruit at 0.25 a year × (1 − N/K) × the availability of host fish, and each clears 0.8 L/h at 20 °C, between laboratory (0.05–0.19) and field (2.6–3.1 L/h) values and the dominant uncertainty. In the brook, outlet filter feeders strain Upper's outflow up to 1.5 g wet m⁻² d⁻¹, and its riffles hold three times a lake bed's invertebrates.

Twenty-one plant species are simulated per bed cell in five growth forms: emergents (e.g. pickerelweed, bulrush), floating-leaved (e.g. the two water-lilies, watershield), a submerged canopy (three pondweeds and bladderworts), isoetid rosettes (e.g. pipewort, water lobelia) and a low meadow of Nitella and mosses. Only Nitella flexilis and N. tenuissima are on record from these lakes (Upper, 2015); project field photographs show plants consistent with bulrush, ribbon-leaved pondweed and riffle moss (identified by growth form only); the rest are near-certain regional flora. Shoots and stores (g dry m⁻²) grow by a Monod function of the mean light over the canopy (PCLake's integral), temperature (Q₁₀ 2.5), P and N, with each form's losses set to just balance growth at its light limit over a season, so depth limits emerge from clarity; the rooted canopy's limit is 21 % of surface light at its bed (Chambers & Kalff 1985). Substrate sets the room to grow, waves remove plants by fetch, ice scours the bed above 0.75–1.25 m, and floating and emergent forms need shelter. Runs start from beds grown five years from bare seeding. Plants give fish cover (only within the canopy's height), spawning structure, a zooplankton refuge and O₂; bladderworts eat zooplankton. Their N and P are in the budgets.

Table 4.2. The model's main components and processes.

ComponentStateMain processesUpdateModule
Weather, catchmentsky state, air anomaly, snowpack, soil and storesfrontal chain fitted to Houlton daily data; OU air anomalies; HBV runoffeach water updateenv3.js
Watertemperature, ice and snow, currents, water agerelaxation to calendar + anomaly; wind and convective mixing; Stefan ice; gyres, drift, diffusion, siphon, through-flow1,752 s in runsenv3.js
ChemistryO₂, NH₄, NO₃, PO₄, DOM, bed P, organic layergas exchange; N cycle; bed P capture, burial, release; closed ledgereach update; slow pools every 3rdchem3.js
Plankton4 algal groups; Daphnia, small cladocerans, copepods, rotifers, eggs, microbial foodlight- and nutrient-limited growth; Holling II grazing; sinking; dormancyeach / every 3rd updatechem3.js
Plants21 species × shoots and stores per bed cellgrowth by light at the bed; storage; waves, ice, grazingevery 3rd updateplants3.js
Invertebratesworms and scuds, weed fauna, snails, surface insects, crayfish, musselseating organic matter and periphyton; emergence; filtering; recruitmentevery 3rd updatelittoral3.js, chem3.js
Fish~300,000 agents; young-of-year schoolsbrains, drives, feeding, FB4 energetics, reproduction, predation, hazards0.1 s; 60-s or 1,752-s blocksfish3.js, GPU kernels
Fish-eaters9 bird and mammal kinds, snapping turtles, bullfrogs, anglers, bearsHolling II take within size, depth, light and ice windowseach fish stepfish3.js (WILD3)
Herps, forest, campsturtles, frogs, newts, tadpoles; bears, deer, moose; 58 campsrations from the pools; movement on land; N and P loads, shade, woodeach water update (herps every 3rd)herps3.js, forest3.js, campfx3.js

4.5 The fish

Only fish recorded in the lakes are simulated: MDIFW's list plus redbreast sunfish from angler observations (project field notes). Golden shiner (no record), largemouth bass (probably mislabeled smallmouth) and American eel (probable, never recorded) are left out, and the sea-run alewife, listed for Lower on MDIFW's 2024 chart, enters as a seasonal visitor (Table 4.3). No census has been taken in either lake, so each density is a reasoned estimate inside the range measured in similar northern lakes; yellow perch were lowered from 500 to 75/ha after angler observations found them scarce at any size. The package's census sums to ~945 fish ≥ 7.5 cm per hectare (~0.6 million; project arithmetic), plus ~150,000 banded killifish and ~1,000 blacknose dace, and its runs start at ~79 kg/ha.

Table 4.3. The fish simulated: census (fish ≥ 7.5 cm per hectare, as in the package), representation, bioenergetics parameter set (Fish Bioenergetics 4.0, FB4; Deslauriers et al. 2017) and spawning.

SpeciesCensus /haAgentsFB4 parameter setSpawning ground; temperature (°C)
White perch Morone americana450schools of ~80; individuals above the budget's length cutoff (recomputed every 10 days; ~20 cm in the design)yellow perch (Kitchell et al. 1977), stand-inflats at 0.3–1.5 m; 14–20
Yellow perch Perca flavescens75 (was 500)as white perchyellow perch (Kitchell et al. 1977)rigid structure at 0.5–2 m; 7–12
Pumpkinseed Lepomis gibbosus50individuals from 7 cm; young in groups of 25bluegill (Kitchell et al. 1974), adult respiration × 0.7 (Roberts 1964)colonies at 0.15–1.7 m; 17–26
Redbreast sunfish L. auritus50as pumpkinseedbluegill, adult respiration × 0.7nests at 0.25–0.6 m; 19–26
Brown bullhead Ameiurus nebulosus100individuals from 10 cm; young in groups of 25Hartman et al. 2017; below 30 g largemouth bass (Rice et al. 1983)0.3–1.5 m, guarded; 18–24
White sucker Catostomus commersonii70individualsyellow perch, stand-inbrook riffles; 10–15
Smallmouth bass Micropterus dolomieu40individualsWhitledge et al. 2003; below 250 g largemouth bass (Rice et al. 1983)nests at 0.5–1.5 m within ~20 m of last year's; 15–21
Chain pickerel Esox niger25individualsnorthern pike (Bevelhimer et al. 1985); below 10 g that set adjusted for larvae (§5.8)vegetation mats at 0.3–1 m; 6–11
Fallfish Semotilus corporalis85individuals from 12 cm; young in groups of 20dace (He 1986; Trudel & Boisclair 1994); adults with pikeminnow consumption (Petersen & Ward 1999)gravel mounds in the brook (lake shoals when full); 15–20
Banded killifish Fundulus diaphanus233 (from 4 cm)shoals of 40fathead minnow (Duffy 1998), stand-inon plants at 0.1–0.5 m; 19–26
Blacknose dace Rhinichthys atratulus0.8 per m² of brookindividualsdace (He 1986; Trudel & Boisclair 1994)riffle gravel in the brook; 19–23
Sea-run alewife Alosa pseudoharengusrun of 15 adults per acre (project estimate)schools of 10–300alewife (Stewart & Binkowski 1986)shallows at 0.15–1 m, at night; 10.5–21

Each hectare of lake has a budget of 470 agents (about 300,000 on the true lakes). Solitary species are individuals; yellow and white perch move in schools of ~80, each agent carrying n fish with one genome and body record, and a school whose fish pass the budget's length cutoff breaks into individuals that go on schooling by choice. The super-individual rules follow Scheffer et al. (1995) and Parry & Evans (2008): losses take a fraction of n, a strike takes one fish, crowding comes from Σ n × mass rather than agent counts, and a merged school keeps one parent's genome. Each agent's brain is a recurrent network, 26 → 10 → 6, with leaky hidden units. Its inputs are the bearings of the nearest food, threat and schoolmates, the fish's depth and place over the bed and shore, light, temperature, O₂, energy, hunger, fear and home; its outputs are turn, pitch, thrust, strike, flee and hide. The genome holds 346 weights and seven trait genes (maturation size, speed, tolerance, fins, eyes, body, brain size). Innate drives from the habitat synthesis (the bottom depth sought by day, night and under ice, preferred temperature, escape from low O₂, schooling, home range) propose a heading and depth, and the brain bends them (weight 0.6). Learning is Baldwinian: only a plastic copy of the 60 hidden-to-output weights changes in life, reinforced when the fish eats, and it is never inherited; a young school's genome is a mutated crossover of its parents'.

Fish cruise at 0.4–1.2 body lengths a second (field values) and sprint at 7–19 (3-s bursts on the DFO fatigue curves; Katopodis & Gervais 2016). Home ranges of the lake species at true scale are radii from 45 m (pumpkinseed) to 700 m (smallmouth), most from the literature; yellow perch's, white perch's, fallfish's and killifish's (300, 400, 300 and 60 m) are project estimates. The brook is part of every range, 0.5–6 % of each species settles in the other lake each year (from connected-lake marking studies), and a fish short of O₂ swims across the lake toward better water. Adults split their foraging time among their foods in proportion to f⁴, f being each food's own functional response (after Werner et al. 1983 and Wu & Culver 1992): zooplankton (type III, half-saturation 60 µg dry/L), the bed's worms and scuds, weed fauna, snails and crayfish within gape, the organic layer (bullheads, suckers), surface insects and fish. An adult feeds over a footprint of a quarter of its home range (40–200 m), and in a coarse block its time within reach of the bed comes from heights gamma-distributed about its mean. Smallmouth bass and chain pickerel are braked by a hunger gate: hunting and foraging are multiplied by 1 − gut/G, with G = pGate·Cmax·W/k the gut content that empties at pGate of maximum consumption (k is gastric evacuation; pGate 0.35 for bass, 0.3 for pickerel), and a sated predator rests from all foraging until 90 % of its meal is digested.

Energetics follow Fish Bioenergetics 4.0 (Deslauriers et al. 2017) with each species' set (Table 4.3), but because sets fitted in warm water overstate winter costs two- to five-fold, empirical cold rules take over in cold water for bass, young bullheads and pickerel (after Chipps et al. 2000), and energy density falls with condition. Mature fish put half their surplus into gonads (0.8 for batch spawners), and nest guards pay staged costs. Fish die of starvation (logistic in condition, 50 % a day at K 0.55), heat and hypoxia beyond their lethal limits, old age, and an "other" mortality for unsimulated causes — half the species' natural mortality, cut by the share wildlife and anglers now take.

A ripe fish heads for its spawning ground as the water nears its spawning temperature (Table 4.3); the pairing species meet on traditional grounds whose number scales with lake area. Eggs become a clutch on the bed and develop by degree-days on the bed's temperature from published incubation equations — for example 686.99·e^(−0.1402T) hours for white perch (Margulies 1989). Clutches lose eggs to temperatures outside the species' window, low O₂, storms and egg predators, and a guard deserts if the water cools to 10.6 °C (a smallmouth also if it falls 2 °C below its laying temperature). Hatch fractions are field survivals where these are known, not laboratory hatch or fertilization rates (white sucker 0.05, white perch 0.45 on a lake bed); yolk-sac survival is 0.2 for perch and white perch, 0.33 in successful bass nests and an unsourced prior of 0.95 for the rest, and yolk-sac larvae are already prey.

The young of the year are brainless super-individual schools. Larvae feed on a prey ladder set by gape and by count, from rotifers and nauplii to Daphnia, and within a school intakes spread lognormally (CV 0.25), so the share below maintenance starves while the rest grow. Background mortality is 0.02 a day for 1-cm larvae (as in predator-free enclosures), falling with length, and 0.015 for juveniles, rising with density, both slower in the cold. Cyclopoids take the smallest larvae. Fish clear larvae at a visual planktivore's rate, 3.42 × 10⁻⁷ L^2.94 m³/s (Sørnes & Aksnes 2004), × 0.15 for the zooplankton about. Followed piscivores meet the juveniles through the same encounter volume, school terms and capture rule as followed prey (below), and schools of young piscivores clear 400·L(mm)^0.6 L a day within a size window peaking at prey 0.19 of their length (Persson et al. 2004; Persson & Brönmark 2002). The first winter follows the form of Shuter et al. (1980) in days below 10 °C, as applied to Spednic Lake (Dudley & Trial 2014): a 208-day winter kills every young smallmouth under 48 mm and none over 92 mm, with other species' thresholds scaled to their own (none for fallfish, killifish or dace, for lack of data) and white perch on Johnson & Evans's (1990) measured model; the young stop feeding below 4 °C. Schools recruit to followed fish only in spring as overwintered schools (age 1), once the water passes ~10 °C. A cap of 1.5 times the census remains as a safety net, its discards tallied.

Predation on followed fish is an encounter–strike–capture rule. Encounters arise at E = π·RD²·(u + v)·N from prey within 6 m, the reaction distance RD (pickerel 1.0–1.2 m and smallmouth 0.8–1.0 m to 6-cm prey) scaled by prey size through R²e^(cR) ∝ prey area (Aksnes & Utne 1997; c = 1.7 m⁻¹ in the stained water) and by light. Strikes follow S = E/(1 + E/a_max) during a diel hunting rhythm, a_max being 3 an hour for pickerel, 12 for smallmouth and 4 for perch-like predators. Capture success depends on prey and predator — an esocid lands 0.7 of strikes on soft-rayed prey, 0.12 on sunfish and 0.1 on bullheads (after Wahl & Stein 1988) — times a size term that falls linearly with the prey's length relative to the predator's (to nil at 0.88 for soft-rayed and 0.6 for spiny-rayed prey), renormalized to 1 at the ratio the successes were measured at (0.3–0.4 of the predator's length; 0.12 for a bass on spiny prey) and capped at 0.9; the prey must also fit the predator's gape. Cover cuts attacks, counted once (after Savino & Stein 1982). An esocid meets a school as n^0.65 fish at undiminished success (Turesson & Brönmark 2004), whereas a school confuses a bass (× n^−0.6) and cuts a perch-like predator's success to 0.15. No predator strikes over water shallower than 0.01 m per cm of its length (full effect from twice that); small fish hide in the brook's riffles and bullheads in winter mud. A school of piscivores hunts as its n fish and shares each kill, so prey mass is conserved.

4.6 Wildlife, anglers, the forest and the camps

Nine fish-eating bird and mammal populations are set at densities from the Maine and regional literature, several of them inferred for these lakes (project estimates), each with a calendar and a daily need — for example common loons at 2 per 150 ha from ice-out to November (1.1 kg a day an adult, chicks from July), belted kingfishers at 1 per 0.8 km of shore, and great blue herons, ospreys, bald eagles, common and hooded mergansers, river otters and mink. Snapping turtles (1/ha, 50 g a day, a fifth of it fish) and bullfrogs also take fish. Each takes its daily need from fish within its windows of prey length, depth, bed depth, light and ice, by a per-fish hazard ρ = D/(A + K) — Holling type II with K a day's need and A the larger of the reachable biomass and its one-day running mean. Anglers enter the same way, killing ~1.9 kg of fish a day on the true lakes in open water (May–November, kept fish plus hooking deaths) and ~1.1 kg through the ice (January–March), from ~5,500 angler-hours a year scaled from regional surveys (project estimate); smallmouth are released by law. Black bears fish spawning suckers in the brook during the run (600 g per hour of fishing; project estimate).

Painted turtles, green and mink frogs, red-spotted newts and tadpoles draw rations from the plants, weed fauna, snails, crayfish and surface insects. Bears (0.4/km²), deer (1.5/km²) and moose (0.6/km²) are individuals walking home ranges over the true world's 9.3 km² of land through their seasons; deer crop the water's edge and lake-using moose graze the shallows in summer, carrying the plants' N and P ashore. The alewife run is 15 adults per acre (project estimate for a colonizing run, ~23,600 adults), varying lognormally (CV 0.5). The adults arrive at Lower's outlet between 10 and 20 °C, spawn at night, stay a median of 17 days and half die in the lakes; their young emigrate from mid-July in pulses after rain, rising flow or cooling, and never recruit; the run's import and export of N and P pass through the ledger.

The 58 lived-in shoreline camps (36 on Upper, 22 on Lower, 6 year-round), 54 docks, ~1.4 km of gravel road within 76 m of the water and a boat launch act through mechanisms with published values. Septic systems deliver 0.1 kg of P per 90 days of occupancy (NH DES 2019) after a groundwater travel time; lots yield 0.15 kg of available P a year (Maine's Phosphorus Control Action Plan coefficient after Dennis et al. 1992, read as available P; about 0.3 kg as total P); and roads 9.0 kg per hectare a year, 21.6 % available (Dudley et al. 1997), with storms scaling the loads. In front of camps fallen wood is cut to 0.15 of an undeveloped shore's (a project estimate between Christensen et al. 1996's 0.1 and Merrell, Howe & Warren 2009's 0.38) and leaf fall to 0.43 (Merrell, Howe & Warren 2009); docks pass 10 % of the light beneath them from 25 May to 15 October (Garrison et al. 2005); and swim areas at half the camps are cleared to a tenth of their plants each June (project estimate). Together the loads come to ~0.28 kg of available P per camp a year.

4.7 The engines and their speed

The CPU code (fish3.js with the water modules) is the model's definition: it runs the gate, the 1/10 world and the fine steps near a viewer. On the true lakes it can split the fish into two shards (Upper with the brook; Lower), each reading and writing only its own water in shared memory, with crossing fish handed over as plain data and each shard on its own random stream, so sharded runs are deterministic. A WebGPU engine (src/w3/gpu/) is a second implementation of the same model, built for speed, with its constants generated from the CPU configuration. Each agent has 102 fields plus its genome and brain state, and a block runs ten kernels (neighbor grid, senses, brain, drives and relocation, feeding, predation, body, death, births and the young, schools). Counter-based random numbers keyed by seed, agent, block and purpose, 64-bit fixed-point atomic sums and index-sorted grid cells make its results independent of thread order. The water stays on the CPU, running while the GPU works, and the fish's takes come back as differences.

Float32 arithmetic and parallel sums rule out bit-identity, so the GPU engine is validated statistically, within the CPU's spread across seeds. On the 1/10 lakes (three seeds × 30 days) every species' adult survival agreed within 0.01 except blacknose dace (0.891 against 1.081), a gap traced to food sharing and the merging of young schools and then largely closed. On the true lakes (seed 611, against the CPU's two-shard run) biomass was 102 against 102.3 kg/ha at day 28, with every species' adults within 0.003 at day 14 and the young within ~4 %. Known differences remain — proportional food sharing on the GPU against first come, first served on the CPU; more merging of young schools on the GPU (46,900 schools against the CPU's 61,300 at day 42, the fish in them alike); the brook's dace diverging by day 98 (211 left on the CPU, in a run of slightly older code, against 50 on the GPU) — and the docks' shade as fish cover is CPU-only (and off in the package).

Table 4.4. Cost of the true-scale lakes (~300,000 agents) on an NVIDIA GeForce RTX 3060 and an AMD Ryzen 5 5600G (6 cores).

EngineOne 29-min blockA simulated year
CPU, one thread4.8–4.9 s (11.6–18 µs an agent through the year)—
CPU, two shards2.4–3.2 s~12–16 h
GPU, side-by-side parity run74 ms (~40× the two shards)~22 min
GPU, later builds and runs~45–97 ms14–30 min (block time)

4.8 Testing and experimental protocol

npm test runs the 2-D model's suites and the 3-D model's gate (test/w3.mjs), which at its last full run (23 October 2026) passed 145 checks, failed none and reported one known gap. The gate requires the N and P inventories to close against the ledger to a relative error below 10⁻⁵ in summer, in a storm and under ice, also with the camps, moose, deer and herps on. For determinism, the same seed must give the same fish after 30 blocks, sharded runs must repeat exactly, GPU state handed back to the CPU must live on identically, and the camps must draw nothing from the simulation's random stream; refactors are proven bit-identical outside the gate by a fingerprint of every fish and young school (tools/w3_fingerprint.mjs). The 3-D model has no save and resume yet, so the exact-resume test (load, then 600 steps byte-identical) covers only the 2-D model. Field-range checks require, for example, ice-out between year fractions 0.13 and 0.20 (counted from 1 March: about 17 April to 13 May), summer bottom water in the north basin ≥ 4 mg/L O₂, a lake-wide winter O₂ minimum ≥ 3 mg/L as the median of three seeds (single seeds are fragile), phosphorus retention in the published range for the grid used, founders at their census ±10 % and 60–150 kg/ha, and a summer pickerel killing 0.1–2 fish a day with 30–70 % of stomachs empty. A known miss of a field bound is reported as a "gap" rather than a failure; the one open gap is plant presence on 84–88 % of the lakes' bed, against 35–45 %. Cost checks guard speed.

The results in section 5 come from three kinds of run. The GPU year runner (tools/gpu/year.html, driven by tools/gpu/year_cdp.mjs) runs the true lakes from 20 May in 1,752-s blocks, seed after seed, and reports every 14 days each species' numbers against the start, biomass, feeding level p, condition, diet, young, spawnings, recruits and deaths by cause (starvation, heat, hypoxia, other, old age, eaten, stranded, wildlife), with who ate whom at the end. Arms are named configurations (A to AM) of the package plus overrides in the page's URL, each run from a frozen snapshot of the code, mostly on one to three of seeds 611–613. Probes are short Node scripts on the CPU reference, mostly on the 1/10 lakes, that isolate one mechanism (for example the under-ice O₂ budget, the burial fit or the weather fit); a CPU season runner in two shards (tools/w3_season.mjs) prints lines that compare with the GPU's. The project's rule is to judge a change on an A/B of at least three seeds and to audit survival at each life stage, not adult counts alone.

5. What building and testing the model taught

The findings below come from the project's running log (docs/FINDINGS.md), where each is dated and points to the probe, the runs (seeds) and the full write-up; the dates and codes in parentheses (e.g. 2026-10-22, E9e) name its entries. Model artifacts are reported as findings: what a whole-lake model gets wrong, and why, is as useful to the next modeler as what it gets right. Unless stated otherwise, "true scale" runs are the GPU year runner on the real-size lakes, and "1/10" runs are the CPU reference on the lakes at a tenth of their width (true depths), which crowds the littoral zone ten-fold.

5.1 Where the model stands

The model does not yet sustain its fish community. In the most recent two-year runs (arm AM, seeds 611 and 613, true scale) the whole-lake fish biomass fell from 79 kg/ha to 43 and 56 kg/ha after one year and to 24 and 38 kg/ha after two. Recruitment broadened (over the two years, per seed: brown bullhead ~166,000 recruits, yellow perch 112,000–139,000, fallfish ~98,000, redbreast sunfish 37,000–49,000, smallmouth bass 7,700–36,000), but white perch recruit almost none (115–123) and fall to 1.5–3.0 kg/ha. The founding white perch stock is eaten in its first summer — 57 % in 112 days, an instantaneous mortality of ~2.7 per year against ~0.4–0.7 for a stable white perch stock's adults — mainly by smallmouth bass, chain pickerel and fallfish (by a probe on the 1/10 lakes). The bass need ~15 kg/ha of fish a year and find white perch the most numerous prey. In a real lake that demand is met by each year's young growing into the predators' size window; without recruitment the predators eat the standing stock down. In the same runs the summer crustacean zooplankton (84–116 µg/L) stayed inside the 50–150 µg/L given for mesotrophic lakes (30–150 in §3.3's synthesis for these lakes), and the phosphorus inventory ended each year at 112–126 % of the start (docs/FINDINGS.md, 2026-10-23, arm AM).

For scale, the only whole-lake fish counts from Maine — rotenone and SCUBA counts of three small lakes (Rupp & DeRoche 1965) — give 44.5, 70.1 and 117.1 kg/ha of all species. Earlier versions of the model grew to 140–165 kg/ha in their first year, its white perch alone (55–63 kg/ha) exceeding the lowest of those lakes' totals (docs/FINDINGS.md, 2026-10-19).

The rest of this section is how the model got here: the errors found, the mechanisms that turned out to matter, and the field values that would settle what remains open.

5.2 A parameter is only as good as what it measured

Several of the largest errors were not wrong numbers but right numbers that measured something else.

Table 5.1. The lakes' oxygen budget under the ice with the ammonium-rich inflow (January–February, g O₂ m⁻² d⁻¹; probe o2budget, docs/FINDINGS.md 2026-10-22).

Processg O₂ m⁻² d⁻¹
The bed's demand−0.255
Nitrification−0.152
Bacteria on dissolved organic matter−0.043
Algae−0.031
Plants+0.014
Sum of the terms listed−0.47 (the project log reports a total of −0.45; field under-ice demand 0.2–0.39)

5.3 Compensations stack

In a model built a piece at a time, a parameter moved to fix a symptom is a debt: when the missing mechanism arrives, the old fix stays and multiplies with it. A four-part audit of every parameter against its source (predation; habitat and the young; physiology; the food web), classifying each as field value, compensation, stacked compensation or prior, found the pattern throughout (docs/review/audit_*.md; docs/FINDINGS.md 2026-10-21):

Undoing each compensation to its research value and letting the mechanism the research named do the work — cover counted once, the size term renormalized, the handling rate equal to the strike ceiling, the bass's laboratory ceiling, a diel activity rhythm, and a hunger gate with a post-meal rest (no fish hunted until ~90 % of a satiating meal is digested) as the only brake — gave a June pickerel 0.37 kills a day at a consumption ratio p of 0.40 with 34 % empty stomachs, against the pike-scaled targets (§3.7) of 0.4–0.8 kills, p 0.39–0.42 and 35–60 % empty. The same pattern appeared at the larvae: the fish's predation on larvae had been fitted down (a "larva-picking" factor from 0.3 to 0.1) when the panfish took 41 % of the suckers' hatch, which later disabled the main larval mortality process once a realistic egg stage existed (2026-10-22, E3/E2c). A background mortality that stands in for unsimulated predators must shrink as those predators are simulated (2026-10-19, stage Y1).

5.4 Two representations of one fish

The model follows adult fish as individuals (or as schools of up to 80 identical fish) and the year's young as super-individual schools until they recruit. Every place the two representations met produced an error that looked like ecology.

5.5 The base of the food web

Table 5.2. The plankton before and after the re-base (Z1 → Z1b + Z2; docs/FINDINGS.md 2026-10-22).

QuantityBeforeAfterField
Edible algae's dip through the Daphnia peak~180×2.6–3.5× (4.4× at the late-summer low)1.5–3×, rarely 5–10×
Rotifers at the Daphnia peak10–30 L⁻¹370–480 L⁻¹≥ 100–250 L⁻¹
Crustacean zooplankton, summerup to ~1,100 µg/L100–180 µg/L50–150 µg/L
Grazing-resistant share of algae, late summer90–98 %47 %median 58 % (IQR 28–85 %)
Summer dissolved P2.5 µg/L≲ 0.5 µg/L≲ 0.5 µg/L

Secchi depth was 3.3–3.5 m and the bed received 20–40 % of production (field 20–50 %). Still open: summer total P ~5–6 µg/L against the model's reference of 12 (the analog lakes read 8–13; §2.4), Daphnia declining after their peak at ~0.06 a day (field 0.1–0.2), and copepods ~2× the ~20–30 µg/L of the nearest LakePulse lakes (other regional sets give 46–121 µg/L; §3.3).

5.6 Habitat: the plants, the waves and the starting state

5.7 Predators: what sets how much they eat

5.8 Energetics outside the fitted range

5.9 The first summer

Table 5.3. The white perch's first year in the 1/10 lakes against the field, before the yolk-sac thinning (Y4) (per hectare; docs/FINDINGS.md 2026-10-22).

StageModelField
Mature adults318—
Eggs laid4.2 million (~13,000 per mature fish)fecundity 20,000–150,000 per female in landlocked stocks (Maine 20,000–300,000; §3.5)
Eggs → swim-up18 % (777,000)~6–48 % (inferred)
Swim-up → 20 mm8 %0.02–0.15
End of August~19,000~100–700 (Oneida Lake); ~3,000 (Lake Erie)

Each stage's survival in the table lay inside the field's range, at its generous end; together they left far too many young. Larval mortality ran 0.055–0.09 a day against the field's ~0.1–0.2, fish took only ~0.03–0.05 a day of it, and the crowded larvae took ~65 days to pass the larval stage instead of 30–45.

5.10 Weather: the sequence, not the totals

The two-dimensional model's four-state sky (clear, cloudy, rain, storm) had plausible shares but cycled every ~27 days: a 10-day wet spell, then a 20-day dry one (the longest 201 days), months without rain beside 270-mm months, and no day over 22 mm. On the catchment model this gave a median daily flow of 0.16× the mean, and in the second year the lakes starved of water and phosphorus: over 252 days the inflow brought 3,163 units of P while the bed buried 9,862. Houlton's daily record (NOAA GHCN-Daily, 1991–2020) has 39 % wet days, P(wet | wet) 0.50, wet and dry spells of 2.0 and 3.1 days, 6.9 days a year ≥ 25 mm and a monthly coefficient of variation of 0.44. A front cycle with per-episode gamma intensities reproduced it (40 %, 0.52, 2.1 / 3.1 days, 6.5–6.8 days, CV 0.49–0.51; Table 4.1 gives the final fit over 60 years × 2 seeds), and storms had to bring warm air: Houlton's winter wet days run 4–5 °C above the month's mean, and with independent air anomalies only ~15 % of December's precipitation fell above 0 °C (field ~50 %). Refitting the HBV catchment model within its usual ranges then brought the hydrograph close to the gauges' (runoff 582–592 mm), with misfits remaining in several months, among them April, August and December (Table 4.1). A "summer too wet" diagnosed earlier as missing canopy interception was the same artifact. For a small lake's flushing and nutrient supply, the weather's sequence matters as much as its monthly totals: calibrate a weather generator on daily statistics, not means (2026-10-22, E9d; 2026-10-21, E9b).

Real weather also exposed an ice bug: the cover had melted when the water's seasonal target crossed a threshold, so a +4 °C January thaw lifted the whole lake's ice in a day. With the ice's thickness modeled (Stefan's growth, snow, slush to white ice) the cover goes only once it has melted through; a lake opened on 1 March starts under ~71 cm of ice and snow passing ~0.25 % of the light (Maine measurements 1–12 %; the model had assumed 40 %, and its under-ice oxygen had depended on photosynthesis through that bright ice — two errors canceling) (2026-10-21, 2026-10-19).

5.11 The engine

A WebGPU engine (counter-based random numbers, 64-bit fixed-point atomic tallies) reproduces the CPU reference statistically — every species within the seeds' spread in the first checks, with the remaining differences listed in §4.7 — at ~40× the speed of the CPU's two shards: a true-scale year in ~14–30 minutes instead of ~15–20 hours (Table 4.4). Building it as an independent re-implementation found a bug in the CPU–GPU hand-over (mates resolved before their identities were set), and its agreement check found the school-kill error of §5.4 (2026-10-18, 2026-10-22). The ecology also broke the engine: by a fourth winter fish crowding into the deep basin's wintering cells (~1,400 agents a cell, from ~250–700) turned a per-cell insertion sort into quadratic work that passed the operating system's two-second watchdog and reset the GPU — deterministically, years into a run, with a symptom that read as hardware. An agent model's data structures carry assumptions about the ecology (that fish spread out) which the emergent behavior (aggregation at wintering sites, as real fish do) can violate (2026-10-21).

5.12 Diagnostics that catch what calibration does not


← Synthesis II: fish, early life, predation, wildlife and forest · Contents · Discussion, data availability and the use of AI →