MODFLOW From Zero
MODFLOW From Zero
Groundwater Modeling · Evaristo Critical Zone Hydrology Lab
Interactive model-building companion

MODFLOW From Zero

Five groundwater models, built one on top of the other, running live in your browser. In each module you first work a number out by hand, then type it in, then run the model and watch your number appear in the water budget.

By the end you can
  1. Compute flow through an aquifer with Darcy's law and predict what a model must return.
  2. Read a steady-state water budget and say where a pumping well's water actually comes from.
  3. Explain why water-table aquifers fail suddenly, and find a well's maximum sustainable yield.
  4. Split pumping between storage and capture through time, and explain the delay.
  5. Predict when a pumping well flips a stream from gaining to losing, and by how much.

How this works. The solver behind every module is a finite-difference groundwater engine — it solves the same equations as MODFLOW, the U.S. Geological Survey's standard groundwater modeling code, on a 21 × 11 grid of 100 m cells. Every reference number here was cross-checked against real MODFLOW 6.8.0 runs of the same models (open the browser console to see the self-test). Checkpoints are self-assessment only; nothing is recorded, and progress resets if you reload.

Module 1 of 5

An Aquifer in a Straight Line

One row of 21 cells, water held at 10 m on the left and 0 m on the right. Small enough to solve on paper — which is exactly why we start here: if the model can't reproduce your algebra, nothing bigger can be trusted.

The one law under everything

Water flows downhill in head

Hydraulic head h is the level water would rise to in a pipe stuck into the aquifer — a direct readout of the water's energy, in metres. Groundwater always moves from higher head to lower head, and Darcy's law says how fast:

Q = K · b · W · (Δh / L)Darcy's law for a confined slab of aquifer

K is hydraulic conductivity — how easily the sediment lets water through (fine sand ≈ 1–10 m/d). b is the saturated thickness, W the width of the slab, and Δh/L the gradient — the slope of the energy line. In this module the layer is confined: b is fixed at the full 10 m no matter what the head does, so everything stays beautifully linear.

Our aquifer: K = 10 m/d, thickness b = 10 m, one row W = 1 m wide. The two end cells are constant-head boundaries (MODFLOW's CHD package): head is pinned at 10.0 m and 0.0 m at the cell centres, which sit 2000 m apart.

✏ Checkpoint · calculate by hand

How much water flows through this aquifer, in m³/day? Use Darcy's law with the numbers above.

m³/d
Show the worked solution
Q = K·b·W·Δh/L = 10 × 10 × 1 × (10 − 0)/2000 = 1000 × 0.005 = 0.5 m³/d. Half a cubic metre a day through a metre-wide strip — groundwater is slow.
✏ Checkpoint · calculate by hand

The 21 cell centres run from x = 50 m to x = 2050 m. If head drops linearly from 10 m to 0 m, what head should the model compute at the middle cell (cell 11, x = 1050 m)?

m
Show the worked solution
Cell 11 sits exactly halfway between the boundaries (1000 of 2000 m), so h = 10 − ½ × 10 = 5.0 m. In general h(i) = 10 − 0.5·(i − 1) for cell i.
Now run the model

Your algebra vs. the machine

This is the exact model, solved by finite differences the way MODFLOW does it. If your two checkpoint answers were right, they should appear — to the decimal — in the tiles below.

The 21-cell aquifer
low head high head head profilehover the cells to read values
Flow through aquifer
m³/d
Head at cell 11
m
Budget error
in minus out, m³/d

Two things to try. Double K and watch the flow double while the heads don't move at all — in a purely head-driven problem the profile is set by the boundaries; K only scales the throughput. Then raise the east boundary and watch the whole line pivot. The budget-error tile is the modeler's seatbelt: in ≈ out, always, or something is wrong.

🔮 Checkpoint · predict, then test

Before you touch the slider: if K doubles from 10 to 20 m/d, what happens to the head at cell 11?

Beyond this page

The professional version

Real aquifers are modelled with the same ingredients you just used: a grid, a K value per cell, and boundary conditions. In MODFLOW's vocabulary the pinned end cells are the CHD (constant-head) package. A MODFLOW 6.8.0 run of this exact model returns the linear profile to within 10⁻¹⁵ m and a water-budget discrepancy of 0.00% — reproducing a hand solution to machine precision is the standard first test of any modeling tool, and now you have performed it yourself.

Module 2 of 5

Drop In a Well

The same aquifer, widened to 11 rows — a 2.1 km × 1.1 km slab — with a well pumping from dead centre. The head field becomes a landscape, and the budget starts answering the only question that matters: whose water is the well taking?

One number to rule the layer

Transmissivity

In 2-D it gets tedious to carry K and b separately, so hydrogeologists multiply them once and give the product a name:

T = K · btransmissivity, m²/d — the layer's capacity to transmit water sideways
✏ Checkpoint · calculate by hand

With K = 10 m/d and a 10 m thick confined layer, what is the transmissivity T?

m²/d
✏ Checkpoint · calculate by hand

Before any well: the aquifer is now 11 rows × 100 m = 1100 m wide. How much water flows through the whole slab, west to east, in m³/d? (Same Darcy's law as Module 1 — only W changed.)

m³/d
Show the worked solution
Q = K·b·W·Δh/L = 10 × 10 × 1100 × 0.005 = 550 m³/d. Watch for this number in the budget tiles when the pumping rate is zero.
Run the model

The cone of depression

Drag the rate up and watch two things at once: the shape (heads dimple into a cone around the well) and the budget (the boundaries rearrange themselves to feed it).

Confined aquifer, 21 × 11 cells
0 mhead10 m
In from west boundary
m³/d
Out to east boundary
m³/d
Well
m³/d
Head at well cell
m

Read the budget at 500 m³/d. Inflow rises 550 → 800 (+250) and outflow shrinks 550 → 300 (−250). The well's 500 is exactly half "new water pulled in" and half "water that used to leave" — the split is symmetric because the well sits dead centre. Hydrogeologists call this capture. Steady state has no storage: every drop the well takes is a drop some boundary gives up.

🔮 Checkpoint · predict, then test

At steady state, where does a pumping well's water come from?

Beyond this page

The professional version

In MODFLOW a pumping well is the WEL package: a single line of input naming the cell and the rate, negative for extraction — everything else you watched happen (the cone, the capture) is the physics responding to that one line. The MODFLOW 6.8.0 run of this model gives a well-cell head of 0.993 m and the 800 / −300 budget you just reproduced. Agreement to the third decimal between two independent solvers is what "verified" means in modeling.

Module 3 of 5

The Water Table Fights Back

Flip one switch — the layer is now unconfined — and the model turns nonlinear. The saturated thickness is the water table, so pumping erodes the very property that delivers water to the well. This module is about what that feedback does.

The feedback loop

Transmissivity that depends on the answer

Unconfined, the transmissivity is T = K · h — thickness equals the water-table height above the aquifer bottom. Drop the water table and T drops with it. Two consequences:

1 · The natural profile curves. With head 10 m on the west and 2 m on the east, the east side is thin and slow, so it needs a steeper gradient to carry the same flow. The result is the classic Dupuit parabola:

h²(x) = h₁² − (h₁² − h₂²) · x/LDupuit: head-squared is linear, so head itself is curved

2 · Wells can fail suddenly. Pumping thins the aquifer at the well → less T → less inflow → more drawdown → thinner still. Past a threshold the loop runs away and the cell dries out.

Why the east boundary moved to 2 m. In Modules 1–2 it was 0 m — the aquifer bottom. Unconfined, that would mean zero saturated thickness at the outlet: T = 0, a wall no water can cross. A water-table boundary must stay wet, so this model holds the east side at 2 m.

✏ Checkpoint · calculate by hand

Use the Dupuit formula to predict the natural (no pumping) water-table height at the well column — x = 1000 m along the 2000 m between boundaries, with h₁ = 10 m, h₂ = 2 m. Give h, not h².

m
Show the worked solution
h² = 100 − (100 − 4)·(1000/2000) = 100 − 48 = 52, so h = √52 ≈ 7.21 m. A linear profile would have said 6.0 m — the curve holds the water table more than a metre higher at midfield.
Run the model

Find the maximum sustainable yield

The solver below uses MODFLOW's standard formulation, where drying is abrupt. Raise the rate slowly and watch the delivered water and the well-cell head. Somewhere there is a cliff.

Unconfined aquifer, east boundary 2 m
m³/d
water table now no-pumping Dupuit curve
Requested
m³/d
Delivered
m³/d
Head at well cell
m above aquifer bottom
Well status
 
CHALLENGE Find the largest whole-number rate this well can actually sustain — delivered = requested, cell still wet. Bracket it with the fine control. NOT YET FOUND
🔮 Checkpoint · explain what you saw

The confined aquifer of Module 2 delivered 500 m³/d without complaint. Why does the same aquifer, unconfined, fail near 280?

Beyond this page

The professional version

In MODFLOW, confined versus unconfined is a single flag per cell (ICELLTYPE: 0 confined, 1 convertible) — the entire nonlinearity you just wrestled with switches on with one input value. A MODFLOW 6.8.0 bisection on this model put the maximum sustainable yield at 282.5 m³/d — with a band just above it where the solver fails to converge at all, and a false-calm zone above ~294 where it "converges" to a dry cell and a well delivering zero. Professional water-table models use the Newton–Raphson method to ride through drying gracefully; the solver behind Modules 4 and 5 does the same.

Module 4 of 5

Borrowed Water

Steady state is a convenient fiction — real aquifers take years to get there, and the journey is paid for out of storage. This module turns time on: the well starts at day zero against the natural water table, and you watch where each day's water actually comes from.

The bank account

Specific yield

When the water table drops, the sediment above it doesn't empty completely — capillary forces keep some water behind. The fraction that actually drains is the specific yield Sy (≈ 0.10–0.25 for sands). It converts water-table movement into volume:

V = Sy · A · Δhwater released from storage when the table drops Δh over area A
✏ Checkpoint · calculate by hand

One model cell is 100 m × 100 m and Sy = 0.15. How many m³ of water are released if the water table under that one cell drops by 1 m?

Show the worked solution
V = 0.15 × 100 × 100 × 1 = 1500 m³. At 500 m³/d, the well can run three whole days on a 1 m drop under a single cell — which is why pumping looks free at first.
Run the model

Ten years in twelve seconds

Press Run: the solver computes 100 growing time steps across 10 years, then plays them back. The chart splits every day's pumping into its two possible sources.

Transient unconfined aquifer · Newton-style solver
0 mhead10 m
delivered by well from storage captured from boundaries
Day
since pumping began
Well delivering
m³/d
Coming from storage
% of pumping
Head at well cell
m

The lesson in the crossover. Early on, storage supplies almost everything — the boundaries haven't felt the well yet. Over months to years the cone reaches them and capture takes over; at true steady state, storage's share is zero. At 500 m³/d something else happens too: near year 3 the water table reaches the aquifer bottom at the well and physics forces the rate down toward ~400 m³/d — the model version of a well that "can't make its rate" anymore. Overpumping is invisible exactly as long as storage is picking up the bill.

🔮 Checkpoint · predict, then test

If you cut Sy from 0.15 to 0.05 (a finer-grained aquifer) and rerun, the day the well first fails to make its full rate will…

Beyond this page

The professional version

In MODFLOW, turning on time means declaring a transient stress period and supplying storage properties through the STO package — Sy becomes an input alongside K, and it is the parameter a modeler calibrates against observed drawdown. Water-table transients also need the Newton–Raphson formulation, which turns wells down smoothly instead of crashing as cells approach dry. The MODFLOW 6.8.0 run of this model delivers the full 500 m³/d until day ~1064, then reduces to 403 m³/d by year 10 — the same curve your run traces.

Module 5 of 5

The Stream Pays

A stream crosses the aquifer 300 m east of the well. It talks to the groundwater through its bed — both directions. This is the module where "sustainable yield" stops being a number and becomes a question: sustained at whose expense?

A boundary with a mind of its own

Head-dependent exchange

MODFLOW's river (RIV) boundary exchanges water at a rate proportional to the head difference across the streambed:

Qstream→aquifer = C · (stage − h)positive = losing stream (water leaks into the aquifer); negative = gaining

The conductance C bundles the streambed's geometry and permeability. For one model cell's worth of stream:

C = Kbed · L · W / bbedbed conductivity × reach length × width ÷ bed thickness

If the water table ever drops below the streambed bottom the stream disconnects: leakage caps at C · (stage − bottom) no matter how much deeper the aquifer is pumped.

✏ Checkpoint · calculate by hand

Our stream: bed conductivity 0.1 m/d, reach length through one cell 100 m, width 10 m, bed thickness 0.5 m. Compute the conductance per cell.

m²/d
Show the worked solution
C = 0.1 × 100 × 10 / 0.5 = 200 m²/d per cell.
✏ Checkpoint · calculate by hand

Before pumping, the model's water table at the stream is 5.064 m and the stream stage is 5.0 m. How much water does ONE stream cell gain from the aquifer, in m³/d? (Give the magnitude.)

m³/d
Show the worked solution
Q = C·(stage − h) = 200 × (5.0 − 5.064) = −12.9 m³/d — negative in MODFLOW's sign convention, meaning the aquifer discharges ~12.9 m³/d into each stream cell. Times 11 cells ≈ 142 m³/d of baseflow. That is the number the well is about to start stealing.
Run the model

Watch the flip

Press Run. The chart tracks the stream–aquifer exchange on a log time axis — the way stream-depletion curves are always plotted — while the map shows the cone reaching the stream.

Transient aquifer + stream, well 300 m away
0 mhead10 m
stream leakage to aquifer well pumpingbelow zero = stream gaining · above = losing
Stream flips on day
gaining → losing
Exchange now
m³/d
Well delivering
m³/d
Streamflow depletion
m³/d vs. natural

Three acts. (1) For weeks the exchange barely moves — the well is living on storage and the stream hasn't noticed. (2) Near day 140 the curve crosses zero: the whole reach flips from gaining to losing. (3) It levels off with the stream donating ~217 m³/d and the well finally making its full 500 — the stream's support is precisely what makes the "unsustainable" rate of Module 3 sustainable. Total depletion ≈ 142 lost baseflow + 217 induced leakage ≈ 359 m³/d, 72% of the pumping, invoiced to whoever is downstream.

🔮 Checkpoint · the big one

A regulator asks: "The well is 300 m from the stream — is the stream affected?" Based on this model, the honest answer is:

Beyond this page

The professional version — and where you go next

In MODFLOW the stream is the RIV (river) package, and its inputs are exactly the three numbers you computed by hand: stage, conductance, and bed bottom. MODFLOW 6.8.0 numbers for this model: natural gain 141.6 m³/d, flip at day 142, equilibrium leakage 216.6 m³/d — check them against your tiles.

Where modelers go from here: a streamflow-routing package that tracks the river's own discharge shrinking reach by reach; moving the well and watching the flip day scale with distance²; recharge, seasons, more layers. Each is one more package on the five-model backbone you just climbed.