Forcings

Rainfall and a prescribed water level, the two forcings this module carries. Both bisect the time_s array they are handed, so both refuse one that steps backwards; the CSV constructors sort instead and warn, on the grounds that the file is not the caller’s to fix. A river hydrograph is not here: it enters through add_inflow(). See Forcings: rainfall and coastal stage for the physics and the units.

class geoswe.RainfallForcing(time_s, rate_mm_h)[source]

Bases: object

Time-varying rainfall forcing.

time_s: 1-D array of times [s] at which rain intensity changes

(cell-centred; intensity is constant between consecutive times). Must be non-decreasing: the lookup is a bisect, so a time out of order would read another segment’s rate. Equal times are allowed.

rate_mm_h: rainfall intensity in mm/h.
  • If 1-D of shape (nt,): spatially uniform; each entry is the intensity over [time_s[k], time_s[k+1]]. The k-th entry applies until time_s[k+1]; the last entry applies indefinitely.

  • If 3-D of shape (nt, nx, ny): spatially varying, same time convention.

The solver reads this via rate_at_time(t), which returns the rate in m/s.

Parameters:
time_s: ndarray
rate_mm_h: ndarray
classmethod from_uniform_constant(rate_mm_h, t_end=1000000000.0)[source]

Backwards-compatible constant uniform rate.

The constant rate holds all the way through the window (the rate at t=t_end is NOT zero, so the last sim step still sees rainfall); callers expecting zero past t_end can pass an explicit two-segment time series instead.

Parameters:
classmethod from_time_series_csv(path, time_col='time_s', rate_col='rate_mm_h')[source]

Load a (time, rate) time series from a CSV (uniform in space).

Rows out of time order are sorted here, with a warning naming the first one, since the constructor itself refuses them.

Parameters:
rate_at_time(t)[source]

Return rainfall rate in m/s at time t.

For uniform forcing returns a scalar. For spatially-varying forcing, returns an array (nx, ny) on the configured backend.

Cache the converted m/s device frames keyed by time-index so we don’t pay an H→D transfer + /3.6e6 divide on every solver step. For Pinellas 10m fp32, the per-frame is ~94 MB so this saves tens of GB/s of unnecessary PCIe traffic.

Parameters:

t (float)

class geoswe.StageBoundary(cells, time_s, stage_m, bed_b)[source]

Bases: object

Time-varying stage (water surface elevation η) boundary on a set of cells.

Fields:

  • cells – array of shape (M, 2) of (i, j) cell indices on the padded solver grid whose state is overwritten each step. Under MPI these are LOCAL padded indices on each rank, so filter to the rank’s interior+halo region and shift global indices by the rank’s (i0, j0) origin minus ngh before constructing the boundary.

  • time_s – 1-D array of times [s] (same convention as RainfallForcing), non-decreasing; equal times are allowed.

  • stage_m – 1-D water-surface elevation η in metres (same length as time_s); the depth is set so h + b = η on each marked cell.

  • bed_b – bed elevation at each marked cell (1-D, length M), so h = η - b.

Operational use: read a NOAA tide-gauge CSV (CO-OPS API), align times to simulation t=0 (e.g. landfall − 24 h), select coastline cells, and enforce the stage Dirichlet condition at every step.

Parameters:
cells: ndarray
time_s: ndarray
stage_m: ndarray
bed_b: ndarray
classmethod from_mask(mask, mesh, bed, time_s, stage_m)[source]

Build a stage boundary from a boolean cell mask.

mask and bed are unpadded (nx, ny) arrays, as passed to the solver: mask is True on the cells that take the stage (a coastline band, a river mouth, one edge of the grid), and bed is the bed elevation. time_s and stage_m give the water-surface elevation over time, interpolated linearly. This fills in the padded cell indices and the bed values that the plain constructor expects.

classmethod from_noaa_csv(csv_path, t0_iso, cells, bed_b, time_col='Date Time', stage_col='Water Level')[source]

Build a StageBoundary from a NOAA CO-OPS CSV (downloaded via API).

t0_iso is the simulation t=0 wallclock time in ISO format (e.g. “2024-09-25T00:00:00Z”). Stage values in the CSV are interpreted as metres above MSL (NOAA default); they should be converted to the DEM’s vertical datum (NAVD88 etc.) externally if needed.

Samples out of time order are sorted here, with a warning naming the first one, since the constructor itself refuses them.

Parameters:
stage_at_time(t)[source]

Linear interpolation of stage at time t. (Bisect-based; avoids CuPy dispatch when t or self.time_s happen to be on the device.)

Parameters:

t (float)

Return type:

float

apply(q, t, h_min=1e-10, freeze_momentum=True)[source]

Enforce stage η(t) on the marked cells.

Sets h = max(η - bed, 0). By default also zeros (hu, hv); this is the stable choice for surge BCs because h and momentum need to be consistent in a Dirichlet sense (an h-only update with arbitrary residual momentum creates an inconsistent state that destabilises the unlimited reconstruction).

Setting freeze_momentum=False lets waves radiate inward but requires a smaller CFL (typically 0.2 or below) and Manning damping to remain stable; it can give a slightly higher peak surge inside bays at the cost of robustness.

Parameters:

Fetching a tide-gauge record

download_noaa_tide_csv is not re-exported at the top level: import it as from geoswe.forcing import download_noaa_tide_csv. It needs the forcings extra, for the two CO-OPS date strings it formats with pandas.

geoswe.forcing.download_noaa_tide_csv(station_id, begin_iso, end_iso, out_path, product='water_level', datum='NAVD')[source]

Download a NOAA CO-OPS tide-gauge CSV via the public API.

station_id: e.g. “8726520” (St. Petersburg, FL). Returns the local CSV path.

Parameters:
Return type:

str