Skip to content

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 (uses cell_size, grid_nrow, grid_ncol) or unstructured (uses ncell).
  • bc_type_int: default boundary condition code applied to every cell. gwflow.array_bc can 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.chancells lists each cell that intersects a channel with the bed elevation, channel id, channel length within the cell, and a depth zone index. gwflow_chan_read reads it, allocates the channel-cell arrays, and writes the connection file gwflow.con consumed by the standard hyd_read_connect path.
  • 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 to gwflow_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 from gwflow.array_tiledepth, gwflow.array_tilearea, and gwflow.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 from water_canal.wal via the canal array.
  • 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 to gwflow_transit_cell, gwflow_transit_chan, and gwflow_transit_tile.
  • gwflow.gwsw_groups: cell groups for daily aggregated gw-sw exchange in gwflow_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.

  • codes.bsn. gwflow = 1 activates the module.
  • object.cnt. sp_ob%gwflow is set from the channel-cell count and replaces sp_ob%aqu.
  • aquifer.aqu, initial.aqu: not used when gwflow is active. basin_read_objs nulls aqu_con and zeroes sp_ob%aqu once gwflow is confirmed.