Water resources

eWater Source: a storage model with a closing balance

Build a daily resource model, distinguish inaccessible storage from a supply rule, and measure shortfall under comparable scenarios.

Practical tutorial7 min readEdition: 25 September 2026
Workflow basis: Source User Guide 5.60; explicit reference balance suppliedAllow 30–60 minutes for the exercise

Define what this model can answer

The exercise asks whether a small hypothetical storage can meet demand through a dry sequence and recover when inflow returns. Source is suited to river-system and resource-allocation questions across time. It does not establish the pressure available at an individual customer. The final deliverable is a mass-balanced scenario comparison with a traceable shortfall calculation.

The downloadable CSV supplies 14 daily inputs and a transparent Python reference calculation. It is not a native Source project. The reference specifies its update order, which can differ from Source’s within-step integration. Use it to check units and mechanisms, not to demand identical answers from differently configured numerical methods.

Download the complete practice pack ↓Download daily storage inputs ↓Download the reference balance script ↓

Prepare a consistent input set

All values are synthetic teaching inputs
InputExercise valueInterpretation
Initial and maximum volume30 ML and 40 MLInitial condition and physical capacity are separate.
Minimum supply volume10 MLStop supplying demand below this threshold in the reference calculation.
Demand and delivery capacity2 ML/day and 3 ML/dayRequested use and infrastructure limit are separate.
InflowZero for ten days, then 8 ML/day for four daysAn artificial dry-to-wet sequence.
Evaporation and area5 mm/day over a fixed 2 ha0.1 ML/day in this simplified reference.
RainfallZeroNo double-counted direct rainfall or catchment runoff.
Evaporation loss, ML = depth, mm × area, ha × 0.01

One millimetre across one hectare is 10 m³, equal to 0.01 ML.

Real storage area varies with level. Prepare consistent level–volume–area relationships and state the vertical datum. Check monotonicity and that the relationship covers the simulated range. A fixed-area exercise deliberately removes that complexity so a units error is easier to find.

Construct the conceptual network

  1. Create a daily scenario covering all fourteen dates, with the intended ordering and storage-processing methods documented.
  2. Represent the inflow boundary, storage, supply path and water user using the nodes appropriate to the installed Source configuration. Check link direction and supply connectivity.
  3. Enter storage dimensions, initial state and full-supply condition. Configure the actual outlet behaviour and capacity.
  4. Attach inflow, demand, evaporation and rainfall data to the intended inputs, checking the displayed units after import.
  5. Define the minimum supply rule explicitly and nominate outputs for storage, inflow, releases, losses, spill, demand and delivered supply.
  6. Run the baseline and inspect every day before extending the period or adding more processes.

Do not copy a relative level into a field expecting an absolute elevation. If your dimensions use a local datum, document how that datum relates to node elevation and any other level-based controls. A consistent set of numbers is more important than using a visually familiar level.

Dead storage is not a universal release switch

Source behaviour depends on the ordering and processing methods. In the 5.60 documentation, the dead-storage setting does not itself restrict releases in rules-based ordering; outlet characteristics govern that behaviour. In netLP ordering, the dead-storage setting restricts release even if the outlet relationship would allow it.

The availability of operating constraints also depends on the storage-processing configuration and node type. Confirm the configured method, define an appropriate outlet or operating constraint and test its behaviour near the intended limit. A field named “dead storage” is not sufficient evidence that a pump will stop at the assumed intake level.

A minimum supply level should restrict supply, not necessarily every physical loss. Evaporation and seepage may continue after abstraction stops. Clipping the entire water balance at the minimum can silently create water. This distinction is essential in drought studies.

Close the water balance at each step

Send = Sstart + inflow + rain − evaporation − seepage − supply − other releases − spill

All terms are volumes over the same time step; distinguish storage change from an outflow.

In the reference sequence, the first day ends at 30 − 0.1 − 2 = 27.9 ML. After nine dry days, storage is 11.1 ML. On day ten, evaporation leaves 11.0 ML, so only 1.0 ML can be supplied above the 10 ML minimum. The day has a 1.0 ML shortfall.

With four subsequent days of 8 ML inflow, 2 ML demand and 0.1 ML evaporation, storage rises by 5.9 ML/day and finishes at 33.6 ML. No spill occurs in this example. The total shortfall is 1.0 ML on one day. These are reproducible reference results with the stated update order.

Run the supplied script with Python 3 using python storage_balance.py from the extracted folder. It writes storage_results.csv and checks closure at every step. To inspect the complete implementation without leaving the site, expand the code below.

Show the complete reference calculation
python
"""Transparent daily reference balance, not an implementation of Source."""
from pathlib import Path
import csv
root=Path(__file__).resolve().parent
storage=30.0;capacity=40.0;minimum=10.0;delivery_limit=3.0
out=[]
with (root/'storage_daily.csv').open() as f:
 for row in csv.DictReader(f):
  before=storage
  inflow=float(row['inflow_ml_day'])
  demand=float(row['demand_ml_day'])
  area=float(row['area_ha'])
  rain=float(row['rain_mm_day'])*area*0.01
  available=before+inflow+rain
  evaporation=min(available,float(row['evap_mm_day'])*area*0.01)
  available-=evaporation
  supplied=min(demand,delivery_limit,max(0.0,available-minimum))
  available-=supplied
  spill=max(0.0,available-capacity)
  storage=available-spill
  residual=before+inflow+rain-evaporation-supplied-spill-storage
  if abs(residual)>1e-9:raise ValueError('Balance does not close')
  out.append([row['date'],before,inflow,evaporation,supplied,demand-supplied,spill,storage])
with (root/'storage_results.csv').open('w',newline='') as f:
 w=csv.writer(f);w.writerow(['date','start_ml','inflow_ml','evap_ml','supply_ml','shortfall_ml','spill_ml','end_ml']);w.writerows(out)
print('Final storage ML:',round(storage,4))
print('Total shortfall ML:',round(sum(r[5] for r in out),4))
print('Days with shortfall:',sum(r[5]>1e-9 for r in out))
print('Balance checked at every step')

Diagnose differences in a Source run

Distinguish configuration errors from numerical differences
DifferenceCheck first
Evaporation much too high or lowDepth units, area units, period convention and pan-to-lake adjustments if used.
Supply continues below the intended levelOrdering method, outlet characteristics, operating constraint and level datum.
Storage never falls below minimum despite lossesWhether a rule is restricting releases only or incorrectly imposing a storage floor.
Water user receives no supply despite available storageConnectivity, ordering, supply-point configuration, outlet limits and demand units.
Small timing differences from the referenceStorage integration method and the treatment of within-day inflows, losses and releases.

Check mass balance at the node and whole-system boundaries. If a model has internal transfers, do not count them as both new external inflow and final supply. Retain the results time convention so that the “start” and “end” volumes align correctly with daily fluxes.

Design comparable scenarios and useful metrics

First vary one assumption: demand reduction, delivery capacity, usable volume or inflow sequence. Keep the common inputs and initial state unchanged unless the scenario intentionally changes them. Then test combinations and uncertainty. An option with more nominal storage may have little benefit if the outlet or refill opportunity is the actual constraint.

Report time reliability, volumetric reliability, maximum consecutive shortfall duration and shortage severity. Define whether restricted demand or unrestricted demand forms the denominator. A supply that meets a reduced restriction target is not the same outcome as supplying the original demand in full.

For a real study, test multiple plausible dry sequences, climate assumptions, source-quality restrictions and maintenance states. Include lead times for emergency supply. A single historic sequence and a favourable starting volume do not establish dependable yield.

Save a decision-ready package

Retain the project version, input time series, geometry, model methods, operating rules, balance checks and scenario definitions. Explain why shortfalls occur and which intervention addresses that mechanism. Separate observed data, assumptions and sensitivity ranges.

Continue to water-security metrics and the regional drought framework. For the hydraulic delivery question beyond a resource model, use the EPANET guide.

Sources & further reading

Source findings are distinguished from editorial interpretation. Apply current local criteria and project evidence when making engineering decisions.