gwsource.flowstep#

FlowStep: the grid- and simulator-agnostic description of one flow time step.

Everything downstream (assembly, solve, metrics, diagnostics) reads only a FlowStep, so tests can
build graphs by hand without MF6.

Conventions
-----------
- Cells are numbered 0..n_cells-1. For MF6 output this is the *user* node number minus one; the
  binary grid file stores IA/JA in user numbering with empty rows for cells removed by IDOMAIN,
  and FLOW-JA-FACE is aligned with those IA/JA arrays.
- ``ia``/``ja`` are 0-based CSR connectivity. A row may contain its own cell (MF6 stores the
  diagonal first); diagonal entries are ignored for the flow graph. MF6 writes the cell budget
  residual (net inflow) in the diagonal of FLOW-JA-FACE.
- ``flowja[p]`` for connection p = (n, ja[p]) is the flow INTO cell n FROM cell ja[p] (MF6 sign
  convention). It must be antisymmetric over the off-diagonal entries (validate_step checks it
  to FLOWJA_RTOL relative to the largest flow, or 1, whichever is larger; parallel
  connections of one cell pair are summed).
- External terms are one entry per boundary (one row of an MF6 list budget record, or one cell
  of an array record such as STO-SS). ``term_flow`` is positive INTO the cell: a positive entry
  is a source term, a negative entry is a sink term. Entries with zero flow are neither.
- ``packages`` is the term table: ``term_package`` indexes into it.
- ``term_iflowface`` (optional) is the IFLOWFACE auxiliary value of every term entry (0 where
  the package has none): the cell face MF6 PRT assigns the boundary flow to (gwsource.prt).
- ``saturated_thickness`` (optional, per cell) is the saturated thickness of the cell for this
  step; with ``area`` it gives the water volume that travel times need (gwsource.traveltime).

Networks (gwsource.network): the "cells" may be the global nodes of a whole
simulation: the cells of every GWF model, then optional package nodes (SFR reaches, LAK lakes,
MAW wells, UZF cells). ``blocks`` lists the contiguous node ranges (NodeBlock) in order;
an empty list means a plain single-model step whose nodes are its cells. Package nodes have no
area or saturated thickness (NaN); ``fixed_volume`` holds their water volume from the package
output (NaN on cells, whose volume comes from porosity x area x saturated thickness).
class gwsource.flowstep.Package(name, text, parent='', model='', partner='', package_type='')[source]#

Bases: object

One budget record of external terms: unique name (e.g. 'WEL-1'), budget text ('WEL').

parent is the MF6 package that wrote the record when one package writes several records
(e.g. 'DRN' writes DRN and DRN-TO-MVR); empty means the record name itself.
model is the GWF model that owns the record in a multi-model step (the name is then
'<model>/<record name>'); partner is the other model of a GWF-GWF exchange record.
package_type is the MF6 package type of a package-node record (e.g. 'MAW' for 'MAW-1:RATE'),
so a selector can name the type whatever the package is called.
Parameters:
property local_name: str#
Name without the '<model>/' prefix of a multi-model step.
property aliases: set[str]#
Upper-case selector names: name, local name, text, parent, type, text w/o -TO-MVR.
property is_mover: bool#
True for a *-TO-MVR record (water handed to the water mover).
class gwsource.flowstep.NodeBlock(name, kind, model, offset, n, grid_shape, grid_type, package_type='')[source]#

Bases: object

A contiguous range of global nodes: the cells of one GWF model or one package's nodes.

kind is 'model' or 'package'; model is the owning GWF model; name is the model name or the
package name (e.g. 'SFR'); package_type the package type ('SFR', 'LAK', 'MAW', 'UZF').
grid_shape and grid_type describe a model's grid; a package block is (n,) 'package'.
Parameters:
property nodes: ndarray#
Global node indices of the block.
property label: str#
'<model>' for a model block, '<model>/<package>' for a package block.
class gwsource.flowstep.FlowStep(ia, ja, flowja, term_cell, term_flow, term_package, term_bound, packages, term_boundname=None, term_iflowface=None, area=None, saturated_thickness=None, active=None, grid_shape=None, grid_type='graph', kstpkper=None, totim=None, notes=<factory>, blocks=<factory>, fixed_volume=None)[source]#

Bases: object

Cell connectivity, intercell flows and external terms for one time step.
Parameters:
property n_cells: int#
Number of cells (rows of the connectivity).
property n_terms: int#
Number of external term entries.
property package_names: list[str]#
Package names in term-table order.
property is_network: bool#
True if the nodes are split into blocks (several models and/or package nodes).
property model_names: list[str]#
Names of the GWF models whose cells are nodes of this step (empty if not a network).
block(label)[source]#
Return the block with the given label ('<model>' or '<model>/<package>') or name.

An exact match wins over a case-insensitive one (a model 'maw' with a 'MAW' package).
Parameters:

label (str)

Return type:

NodeBlock

gwsource.flowstep.validate_step(step)[source]#
Assert that a FlowStep's arrays are mutually consistent.
Parameters:

step (FlowStep)

Return type:

None

gwsource.flowstep.connection_rows(ia)[source]#
Return the row (cell) index of every CSR entry.
Parameters:

ia (ndarray)

Return type:

ndarray

gwsource.flowstep.csr_from_edges(n_cells, src, dst, q)[source]#
Return (ia, ja, flowja), diagonal first in each row, for directed edges src→dst of flow q.
Parameters:
Return type:

tuple[ndarray, ndarray, ndarray]

gwsource.flowstep.from_edges(n_cells, src, dst, q, term_cell=(), term_flow=(), term_package=(), packages=None, **kwargs)[source]#
Build a FlowStep from directed edges and external terms (bound numbers 1..k per package).
Parameters:
Return type:

FlowStep