gwflow
Purpose¶
gwflow is the cell-based 2D groundwater module that replaces the lumped aquifer (*.aqu) when active. It discretises the basin into a structured or unstructured mesh and solves a horizontal groundwater balance per cell, with optional couplings to channels, tiles, reservoirs, wetlands, floodplains, canals, recharge ponds, phreatophyte transpiration, time-varying boundary heads, solute transport, and heat transport. All input files share the gwflow.* (or gwflow_canal.*) prefix and live in the project directory next to the standard SWAT+ inputs.
Activation¶
Set gwflow = 1 in codes.bsn. The model then expects gwflow.chancells to exist. basin_read_objs opens that file to count channel-cell intersections, sets sp_ob%gwflow to that count, switches aqu_con to null, and points gwflow_con at gwflow.con (the connection file written by gwflow_chan_read). If gwflow.chancells is missing, bsn_cc%gwflow is reset to 0 and the lumped aquifer is used.
gwflow_chan_read runs first (from hyd_connect) and writes gwflow.con based on gwflow.chancells. Then the standard *_con reader processes gwflow.con, and gwflow_read reads everything else.
File overview¶
Most files are optional. The module probes for each one with inquire(...). When a file is missing, the corresponding sub-feature is disabled with a message to the gwflow record file.
| File | Purpose | Reader |
|---|---|---|
gwflow.input |
Master file. Mesh definition, feature flags, aquifer and streambed parameters, time step, output flags | gwflow_read.f90 |
gwflow.chancells |
Channel-cell intersections (cell id, bed elevation, channel id, channel length, depth zone) | gwflow_chan_read.f90 |
gwflow.con |
Generated. Channel-cell connection table written from gwflow.chancells |
gwflow_chan_read.f90 |
gwflow.chancells_depth |
Optional. Per-zone daily channel depths | gwflow_chan_read.f90 |
gwflow.hrucell |
HRU-to-cell area mapping. Required when conn_type = 1 (HRU) |
gwflow_read.f90 |
gwflow.lsucell |
LSU-to-cell area mapping. Required when conn_type = 2 (LSU). Disables gw-to-soil and gw-to-wetland transfers |
gwflow_read.f90 |
gwflow.cellhru |
Optional reverse mapping (cell to HRUs) | gwflow_read.f90 |
gwflow.wtdepth |
Optional initial water table depth below ground per cell | gwflow_read.f90 |
gwflow.array_K |
Optional grid override of aquifer hydraulic conductivity zones | gwflow_read.f90 |
gwflow.array_Sy |
Optional grid override of specific yield zones | gwflow_read.f90 |
gwflow.array_rdel |
Optional grid override of recharge delay | gwflow_read.f90 |
gwflow.array_exdp |
Optional grid override of ET extinction depth | gwflow_read.f90 |
gwflow.array_hinit |
Optional grid override of initial head | gwflow_read.f90 |
gwflow.array_bc |
Optional per-cell boundary condition code | gwflow_read.f90 |
gwflow.array_strK |
Optional grid override of streambed K | gwflow_read.f90 |
gwflow.array_strthick |
Optional grid override of streambed thickness | gwflow_read.f90 |
gwflow.pumpex |
External pumping schedule per well (cell id, periods, rates) | gwflow_read.f90 |
gwflow.hru_pump_observe |
HRU list for daily pumping observation output | gwflow_read.f90 |
gwflow.tiles |
Tile drainage parameters and per-cell tile flag | gwflow_read.f90 |
gwflow.array_tiledepth, gwflow.array_tilearea, gwflow.array_tileK |
Optional per-cell tile depth, area, K | gwflow_read.f90 |
gwflow.rescells |
Reservoir-cell links (bed K, thickness, cell list) | gwflow_read.f90 |
gwflow.floodplain |
Floodplain-cell links (cell id, channel, K, area) | gwflow_read.f90 |
gwflow_canal.con |
Canal-cell connections per canal (length, stage) | gwflow_read.f90 |
gwflow.ponds |
Recharge ponds (attributes plus pond-cell links and solute concentrations) | gwflow_read.f90 |
gwflow.phreatophytes |
Depth-rate curve for phreatophyte ET and the cells where it applies | gwflow_read.f90 |
gwflow.tvheads |
Time-varying head boundary conditions (annual values per cell) | gwflow_read.f90 |
gwflow.heat |
Heat transport: thermal conductivity per zone, initial temperatures | gwflow_read.f90 |
gwflow.solutes |
Solute transport configuration (constituent list, initial concentrations, dispersivity, reaction rates) | gwflow_read.f90 |
gwflow.solutes.minerals |
Mineral equilibrium parameters for salt solutes | gwflow_read.f90 |
gwflow.transit |
Cells for groundwater transit time tracking (structured grids only) | gwflow_read.f90 |
gwflow.gwsw_groups |
Cell groups for daily aggregated gw-sw exchange output | gwflow_read.f90 |
gwflow.chancells_obs |
Channel cells flagged for daily observation output | gwflow_read.f90 |
Exhaustive column-by-column documentation for each file is a follow-up. The summaries below describe purpose and the reader entry point so users can locate the exact format in source.
Mesh and boundary conditions¶
gwflow.input is the master file and is read line by line near the top of gwflow_read. It defines:
grid_type:structured(usescell_size,grid_nrow,grid_ncol) orunstructured(usesncell).bc_type_int: default boundary condition code applied to every cell.gwflow.array_bccan override per cell.conn_type: 1 for HRU-cell connection, 2 for LSU-cell.- Feature flags:
gw_soil_flag,gw_satx_flag,gw_pumpex_flag,gw_tile_flag,gw_res_flag,gw_wet_flag,gw_fp_flag,gw_canal_flag,gw_solute_flag. gw_time_step: groundwater solver time step.gwflag_day,gwflag_mon,gwflag_yr,gwflag_aa: water-balance output aggregation flags.- Aquifer and streambed zone parameters: hydraulic conductivity, specific yield, streambed K and thickness, recharge delay, ET extinction depth, initial head. Each is given as a list of zone values with optional per-cell array overrides (
gwflow.array_*).
If conn_type = 1 but gwflow.hrucell is missing, the reader falls back to gwflow.lsucell and disables gw-to-soil and gw-to-wetland transfers. The reverse fallback also exists. If neither file is present the run stops.
Channel exchange¶
Three files configure the channel-aquifer coupling:
gwflow.chancellslists each cell that intersects a channel with the bed elevation, channel id, channel length within the cell, and a depth zone index.gwflow_chan_readreads it, allocates the channel-cell arrays, and writes the connection filegwflow.conconsumed by the standardhyd_read_connectpath.gwflow.chancells_depth(optional) supplies a per-cell depth-zone index and, for each simulation day, the depth in each zone. Enables daily varying channel stage along the network.gwflow.chancells_obs(optional) selects channel cells for which daily flow and NO3 mass are written togwflow_chan_obs_*output files.
Feature sub-files¶
Each feature is gated by the matching flag in gwflow.input and by the presence of the input file.
gwflow.tiles: tile drainage. Header gives default tile depth, drain area, and tile K; per-cell overrides come fromgwflow.array_tiledepth,gwflow.array_tilearea, andgwflow.array_tileK. An optional tile-cell group block defines aggregated output groups, followed by a per-cell tile flag (0 or 1).gwflow.rescells: reservoir-aquifer exchange. Bed thickness and bed K (m/day), number of reservoir cells, then one line per cell with cell id, reservoir id, and stage.gwflow.floodplain: floodplain exchange. Cell id, channel id, floodplain K, contact area per cell.gwflow_canal.con: canal-cell connections per canal. For each canal row gives canal id, number of cells, then triples of (cell id, length in cell, stage). Canal properties (width, depth, bed K, bed thickness, dates) come fromwater_canal.walvia thecanalarray.gwflow.ponds: recharge ponds. One record per pond with id, area, target channel and canal ids, unsaturated flag, bed K, number of pond cells, weather station, evap coefficient, divert start date, and unsaturated-zone solute concentrations. Followed by a block of pond-cell entries giving pond id, cell id, and contact area.gwflow.pumpex: per-pump external pumping schedule with one or more (start day, end day, rate) periods.gwflow.phreatophytes: a depth-rate curve (depth in m, transpiration rate) followed by the cell ids and areas where it applies.gwflow.tvheads: time-varying boundary heads. Number of cells, then for each cell id one head value per year of the simulation.gwflow.transit: list of cells for transit time tracking (structured grids only). Output goes togwflow_transit_cell,gwflow_transit_chan, andgwflow_transit_tile.gwflow.gwsw_groups: cell groups for daily aggregated gw-sw exchange ingwflow_gwsw_group_day.txt.gwflow.hru_pump_observe: HRUs to track for the daily pumping observation file.
Solutes¶
Set gw_solute_flag = 1 in gwflow.input and provide gwflow.solutes. The reader cross-checks the solute list against constituents.cs, allocates per-cell solute state, and reads dispersivity and reaction rate parameters. Initial concentrations can be supplied per zone or per cell. When salt minerals are simulated, gwflow.solutes.minerals adds the mineral phase parameters used by the equilibrium solver.
Heat¶
Provide gwflow.heat to enable groundwater heat transport. The file gives one thermal conductivity per aquifer zone, then initial groundwater temperature either as a single value, a grid_nrow x grid_ncol array for structured grids, or one value per cell for unstructured grids. Source/sink heat arrays are allocated for every flux pathway already active in the water balance.
Examples¶
Neither refdata/Ames_sub1 nor refdata/Osu_1hru ships a gwflow-enabled project. The excerpts below are minimal synthetic examples derived directly from the readers, valid as inputs against the source at the pinned commit. Use them as a shape reference, not as parameter values for a real watershed.
gwflow.input¶
A structured grid, HRU-cell connection, water-only run with no tiles, reservoirs, canals, or solutes. The two leading lines are skipped headers. Inline comments here are illustrative; the reader uses list-directed reads and accepts any whitespace.
gwflow.input: synthetic example, 50 x 80 structured grid, 100 m cells
written for documentation; not a calibrated dataset
structured ! grid_type ("structured" or "unstructured")
100.0 ! cell_size, m
50 80 ! grid_nrow, grid_ncol
3 ! bc_type_int (per-cell BC code; 1=no-flow, 2=specified-head, 3=...)
1 ! conn_type (1=HRU-cell, 2=LSU-cell)
1 ! gw_soil_flag
1 ! gw_satx_flag
0 ! gw_pumpex_flag
0 ! gw_tile_flag
0 ! gw_res_flag
0 ! gw_wet_flag
0 ! gw_fp_flag
0 ! gw_canal_flag
0 ! gw_solute_flag
1.0 ! gw_time_step, days
1 1 1 1 ! gwflag_day, _mon, _yr, _aa
1 ! deprecated columns count (kept for input compatibility)
aquifer hydraulic conductivity
zone K (m/day)
2 ! nzones_aquK
1 5.0
2 0.8
aquifer specific yield
2 ! nzones_aquSy
1 0.18
2 0.06
streambed hydraulic conductivity
2 ! nzones_strK
1 0.40
2 0.05
streambed thickness (m)
1 ! nzones_strbed
1 0.50
The reader continues past this excerpt with recharge delay, ET extinction depth, initial head, and the per-cell grid layout (grid_nrow x grid_ncol rows of nrow x ncol values for the structured branch). The grid_type keyword selects whether the cell block is read as a rectangular array or as ncell single-cell records.
gwflow.chancells¶
One line per cell that intersects a channel. Three header lines are skipped. Fields are cell id, bed elevation (m), channel id (matches chandeg.con numbering), channel length within the cell (m), and a depth-zone index used by gwflow.chancells_depth when present.
gwflow.chancells: channel-cell intersections (synthetic)
generated alongside chandeg.con
CELL BED_ELEV CHAN LENGTH DEPZONE
142 295.50 1 85.20 1
175 294.10 1 118.60 1
208 292.80 1 96.40 1
241 291.40 2 72.10 2
274 290.20 2 109.30 2
The reader allocates arrays of size sp_ob%gwflow (the channel-cell count set by basin_read_objs) and stops after that many records. The file count must match.
gwflow.hrucell¶
The HRU-cell mapping has two blocks. The first lists every HRU that is connected to one or more cells (one HRU id per line). The second lists each HRU-cell pair with the contact area in m^2. The reader counts cells per HRU on a first pass, allocates, then rewinds and reads.
gwflow.hrucell: HRU-cell connections (synthetic, 12-HRU project)
header
header
nhru_connected
12
1
2
3
4
5
6
7
8
9
10
11
12
header
header
HRU CELL AREA_M2
1 142 5000.0
1 143 4800.0
1 175 4200.0
2 176 5100.0
2 208 4600.0
...
gwflow.tiles (enabled with gw_tile_flag = 1)¶
Header gives default tile depth, drainage area, and tile K; the per-cell flag (0 or 1) follows. gwflow.array_tiledepth, gwflow.array_tilearea, and gwflow.array_tileK can override the defaults per cell.
gwflow.tiles: tile drainage parameters
TILE_DEPTH_M TILE_AREA_M2 TILE_K_MDAY
1.20 50.0 0.30
NCELLS
14
CELL_ID
142
143
175
208
...
gwflow.solutes (enabled with gw_solute_flag = 1)¶
Cross-checked against the solutes declared in constituents.cs. The file lists the species the gwflow module should transport, their dispersivity, and reaction rate parameters. Initial concentrations can be supplied per zone or per cell.
The full format is best read alongside the cross-check loop in gwflow_read.f90; do not assume column order from this skeleton without confirming against the source.
Related¶
codes.bsn.gwflow = 1activates the module.object.cnt.sp_ob%gwflowis set from the channel-cell count and replacessp_ob%aqu.aquifer.aqu,initial.aqu: not used when gwflow is active.basin_read_objsnullsaqu_conand zeroessp_ob%aquonce gwflow is confirmed.