A 9×5 lattice of limestone fractures connects a recharge surface to a spring outlet. Flow through every fracture follows the cubic law for parallel-plate fractures — conductance g ∝ a³ for aperture a — so the network is solved every frame as a resistor mesh (Gauss–Seidel relaxation on hydraulic head) with fixed head at the recharge row and zero head at the spring row:
g = a³
q_edge = g·(φ_i − φ_j) / L
Σ q_in = Σ q_out (at every interior node)
Water enters undersaturated (C=0) and approaches the calcite equilibrium concentration C_eq (set by acidity/pCO2) along each flow path with first-order kinetics — the residence time is exactly the fracture length over the local flow velocity, so slow, narrow fractures react closer to equilibrium while fast ones stay aggressive:
τ = L·a / q
C_out = C_in + (C_eq − C_in)·(1 − e^(−k·τ))
da/dt = k_grow · q · (C_out − C_in)
This is the standard positive-feedback loop behind real karst speleogenesis (Dreybrodt-style reactive transport): a fracture that starts even slightly wider carries more flow, which — up to a point — lets more undersaturated water reach it before it saturates, so it dissolves faster and gets wider still, while its neighbours starve. Watch the spring discharge stay comparatively flat even as the max aperture climbs: a single widening link is throttled by whatever resistance remains upstream and downstream of it, so total spring flow only rises sharply once an entire path has broken through end to end — a real, often counter-intuitive lesson about karst aquifers.
- Edge colour/width — pale thin lines are unaltered fracture; bright thick lines are enlarged conduit.
- Tracer dots — move along each edge at a speed proportional to its flow rate.
- Breakthrough — declared once the widest fracture passes 8× the network's average starting aperture, matching the literature's qualitative threshold for a self-sustaining trunk conduit.