pygetm.open_boundaries module

class pygetm.open_boundaries.ArrayOpenBoundaries(array: Array, type=None)[source]

Bases: object

All open boundaries for a single array. The values prescribed at all boundaries combined are accessible as values. The type of open boundary condition can be set for all boundaries at once via the type property.

add_relaxation(slicer: Callable[[ndarray], ndarray], weights: ndarray, target: ndarray, where: ndarray)[source]

Add a boundary-influenced relaxation term, e.g., a sponge zone.

Parameters:
  • slicer – function that extracts the relaxation area from the model values. It must take a 2D or 3D array of model values and return the slice corrresponding to the relaxation area.

  • weights – fraction of the model values replaced by relaxation.

  • target – target values to relax towards.

  • where – boolean array indicating where the relaxation term should be applied.

initialize() Iterable[BoundaryCondition][source]
relaxation: list[Relaxation]
property type
update()[source]

Update the tracer at the open boundaries

updaters: list[Callable[[], None]]
values
class pygetm.open_boundaries.ArrayOpenBoundary(open_boundaries: LocalOpenBoundaryCollection, boundary: OpenBoundary, prescribed_values: ndarray, model_values: ndarray, type: BoundaryCondition)[source]

Bases: object

Single open boundary for a single array. The type of open boundary condition is accessible as type. The values prescribed at the boundary are accessible as values.

property type: BoundaryCondition
property values: ndarray
class pygetm.open_boundaries.BoundaryCondition[source]

Bases: object

Base class for an open boundary condition that can be applied to any open boundary of any array. Specific types of open boundary condition (clamped, zero-gradient, etc.) must subclass this base class and implement get_updater()

static get_setter(array: Array, slc: tuple[slice | int, ...], where: bool | ndarray = True) Callable[[ndarray], None][source]

Takes an array object and a slice, and returns a function that sets values in the array at the slice, respecting the array’s mask and valid range.

Parameters:
  • array – array that will be updated

  • slc – slice of the values in the array that will be updated

  • where – boolean array indicating which points to update

get_updater(boundary: OpenBoundary, array: Array, bdy: ndarray) Callable[[], None][source]

Return a function that updates the model values at the open boundary.

Boundary conditions that use nearby interior values (e.g., zero gradient, flow-dependent relaxation) can only use points with mask=ACTIVE (wet and active). They must skip mask=BOUNDARY to avoid dependence on the order in which boundaries are updated.

Parameters:
  • boundary – the open boundary

  • array – array with all model values

  • bdy – prescribed values at the open boundary. If depth-explicit, its shape is (np, nz), otherwise (np,)

initialize(grid: Grid)[source]

Initialize the boundary condition.

Subclasses for specific types of open boundary condition can perform their own initialization here, e.g., by creating auxiliary arrays. This method is called once for each open boundary of each array that uses this boundary condition.

Parameters:

grid – the T grid on which the boundaries are defined

prepare_depth_explicit()[source]
class pygetm.open_boundaries.Clamped[source]

Bases: BoundaryCondition

Clamped boundary condition

The model values at the open boundary are set to the prescribed values.

get_updater(boundary: OpenBoundary, array: Array, bdy: ndarray) Callable[[], None][source]

Return a function that updates the model values at the open boundary.

Boundary conditions that use nearby interior values (e.g., zero gradient, flow-dependent relaxation) can only use points with mask=ACTIVE (wet and active). They must skip mask=BOUNDARY to avoid dependence on the order in which boundaries are updated.

Parameters:
  • boundary – the open boundary

  • array – array with all model values

  • bdy – prescribed values at the open boundary. If depth-explicit, its shape is (np, nz), otherwise (np,)

class pygetm.open_boundaries.Flather(transport: bool = False)[source]

Bases: BoundaryCondition

Flather boundary condition for elevation.

This infers the elevation at the open boundary from prescribed elevation and from the difference between prescribed and modelled velocity across the boundary.

See also:

Flather, R.A. (1976) A tidal model of the north-west European continental shelf. Mem. Soc. R. Sci. Liege 6 (10), 141-164.

Blayo, E., & Debreu, L. (2005). Revisiting open boundary conditions from the point of view of characteristic variables. Ocean Modelling, 9(3), 231–252. 10.1016/j.ocemod.2004.07.001

Parameters:

transport – use prescribed transport at the boundary instead of prescribed velocity

get_updater(boundary: OpenBoundary, array: Array, bdy: ndarray) Callable[[], None][source]

Return a function that updates the model values at the open boundary.

Boundary conditions that use nearby interior values (e.g., zero gradient, flow-dependent relaxation) can only use points with mask=ACTIVE (wet and active). They must skip mask=BOUNDARY to avoid dependence on the order in which boundaries are updated.

Parameters:
  • boundary – the open boundary

  • array – array with all model values

  • bdy – prescribed values at the open boundary. If depth-explicit, its shape is (np, nz), otherwise (np,)

static update_transport(z_ext: ndarray, tp: ndarray, tp_ext: ndarray, D: ndarray, inflow_sign: float, setter: Callable[[ndarray, ndarray], None])[source]
static update_velocity(z_ext: ndarray, tp: ndarray, vel_ext: ndarray, D: ndarray, inflow_sign: float, setter: Callable[[ndarray], None])[source]
class pygetm.open_boundaries.GlobalOpenBoundaryCollection(nx: int, ny: int, logger: Logger, x: ndarray | None = None, y: ndarray | None = None, lon: ndarray | None = None, lat: ndarray | None = None)[source]

Bases: Sequence[OpenBoundary]

add_bottom_boundary(name: str, j: int, istart: int, istop: int, type_2d: int, type_3d: int)[source]

Add an open boundary with the model exterior below and the model interior above. This is a southern open boundary in a spherical domain.

add_by_index(side: Side, l: int, mstart: int, mstop: int, type_2d: int, type_3d: int, name: str | None = None)[source]

Note that l, mstart, mstop are 0-based indices of a T point in the global domain. mstop indicates the upper limit of the boundary - it is the first index that is EXcluded.

add_left_boundary(name: str, i: int, jstart: int, jstop: int, type_2d: int, type_3d: int)[source]

Add an open boundary with the model exterior to the left and the model interior to the right. This is a western open boundary in a spherical domain.

add_right_boundary(name: str, i: int, jstart: int, jstop: int, type_2d: int, type_3d: int)[source]

Add an open boundary with the model exterior to the right and the model interior to the left. This is an eastern open boundary in a spherical domain.

add_top_boundary(name: str, j: int, istart: int, istop: int, type_2d: int, type_3d: int)[source]

Add an open boundary with the model exterior above and the model interior below. This is a northern open boundary in a spherical domain.

adjust_mask(mask: ndarray)[source]

Adjust the global mask for open boundaries

This assigns mask values: * BOUNDARY: masked T point * MIRROR_INT: velocity point in between open boundary T points * MIRROR_EXT: velocity point just outside the open boundary

Parameters:

mask – writeable mask defined on the supergrid, with shape (1+2*ny, 1+2*nx)

clear()[source]

Delete all open boundaries.

property i: ndarray
property j: ndarray
property lat: ndarray | None
property lon: ndarray | None
property x: ndarray | None
property y: ndarray | None
class pygetm.open_boundaries.LocalOpenBoundary(name: str, side: Side, l: int, mstart: int, mstop: int, mskip: int, type_2d: int, type_3d: int)[source]

Bases: OpenBoundary

Create an open boundary. The supplied indices are global indices in the T grid.

Parameters:
  • name – unique name for this boundary

  • side – side of the domain

  • l – fixed index (i for left/right boundaries, j for top/bottom)

  • mstart – start index (j for left/right boundaries, i for top/bottom)

  • mstop – stop index (exclusive)

  • type_2d – default type of boundary condition for 2D variables

  • type_3d – default type of boundary condition for 3D variables

extract_inward(values: ndarray, start: int, stop: int | None = None) ndarray[source]

Extract one or more rows/columns on the T grid, inward from the open boundary.

Parameters:
  • values – 2D or 3D array of values on the T grid

  • start – index of the first row/column to extract

  • stop – index of the last row/column to extract (exclusive). If not given, only a single row/column is extracted.

Returns:

Extracted of values. This is a view into the input array. If a single row/column is extracted, the shape of the extracted values will be (..., np), where np is the number of points of the open boundary, and ... represents any non-xy dimensions of the input array. If n  = stop - start rows/columns are extracted, the shape will be (..., np, n). The last dimension then runs from the row/column closest to the boundary to the one furthest away.

extract_uv_in(u: ndarray, v: ndarray) ndarray[source]

Extract velocity or transport across the boundary from components at velocity points (U or V) just inward from the boundary.

Parameters:
  • u – 2D or 3D component of velocity or transport in x-direction. It must be defined on the U grid.

  • v – 2D or 3D component of velocity or transport in y-direction. It must be defined on the V grid.

Returns:

2D or 3D array of velocity or transport across the boundary.

class pygetm.open_boundaries.LocalOpenBoundaryCollection(global_collection: GlobalOpenBoundaryCollection, grid: Grid, logger: Logger)[source]

Bases: Sequence[LocalOpenBoundary]

Freeze the open boundary collection. Drop those outside the current subdomain.

property local_to_global_indices: ndarray

Indices of local open boundary points in a global open boundary array.

prepare(macro_active: bool)[source]

Prepare open boundary forcing. This includes rotating prescribed velocity fields, as well as extracting depth-explicit horizontal velocities from which each class of open boundary condition can calculate derived metrics.

start(U: Array | None = None, V: Array | None = None, uk: Array | None = None, vk: Array | None = None)[source]
class pygetm.open_boundaries.OpenBoundary(name: str, side: Side, l: int, mstart: int, mstop: int, type_2d: int, type_3d: int)[source]

Bases: object

A single open boundary. This defines the location of the open boundary, but not the type of boundary condition to apply to the different variables. For that, use core.Array.open_boundaries.

Create an open boundary. The supplied indices are global indices in the T grid.

Parameters:
  • name – unique name for this boundary

  • side – side of the domain

  • l – fixed index (i for left/right boundaries, j for top/bottom)

  • mstart – start index (j for left/right boundaries, i for top/bottom)

  • mstop – stop index (exclusive)

  • type_2d – default type of boundary condition for 2D variables

  • type_3d – default type of boundary condition for 3D variables

to_local_grid(grid: Grid) LocalOpenBoundary | None[source]

Convert global indices to local indices of the current subdomain.

class pygetm.open_boundaries.Relaxation(slicer, weights, target, local, where)[source]

Bases: NamedTuple

Create new instance of Relaxation(slicer, weights, target, local, where)

local: ndarray

Alias for field number 3

slicer: Callable[[ndarray], ndarray]

Alias for field number 0

target: ndarray

Alias for field number 2

weights: ndarray

Alias for field number 1

where: ndarray

Alias for field number 4

class pygetm.open_boundaries.Side(*values)[source]

Bases: IntEnum

EAST = 3
NORTH = 2
SOUTH = 4
WEST = 1
class pygetm.open_boundaries.Sponge(n: int = 3, tmrlx: bool = False, tmrlx_max: float = 0.25, tmrlx_min: float = 0.0, tmrlx_ucut: float = 0.02, tmrlx_umin: float | None = None)[source]

Bases: Clamped

Sponge boundary condition, with n points inward from the open boundary being relaxed to values at the boundary.

If flow-dependent relaxation is used (tmrlx=True), values at the boundary itself will blend the prescribed values and a weighted mean over the sponge zone. The fraction taken from the prescribed values will increase with increasing inward flow velocity.

If flow-dependent relaxation is not used (tmrlx=False), values at the boundary will be set to the prescribed values.

Relaxation rates for the n points are available as sp. They default to the formulation of Martinsen & Engedahl (1987) (Eq 3).

Parameters:
  • n – number of points in the sponge zone; the boundary itself is not included, so n=0 is equivalent to a clamped boundary.

  • tmrlx – make use of prescribed values at the open boundary dependent on flow direction. This is typically used to gradually disable use of prescribed values as the current switches from inflow to outflow over the boundary.

  • tmrlx_max – maximum fraction to take from prescribed values at the open boundary. The remaining fraction will be taken from a weighted mean over the sponge zone. This maximum is reached at strong inflow (>= tmrlx_ucut). Only used if tmrlx is True.

  • tmrlx_min – minimum fraction to take from prescribed values at the open boundary. The remaining fraction will be taken from a weighted mean over the sponge zone. This minimum is reached when water flows outward over the boundary (inflow <= tmrlx_umin). Only used if tmrlx is True.

  • tmrlx_ucut – inward flow velocity (m s-1) at which the use of prescribed boundary values becomes highest. At this inflow, or higher, boundary values are for fraction tmrlx_max based on prescribed values; the remaining 1 - tmrlx_max is taken from a weighted mean over the sponge zone. Only used if tmrlx is True.

  • tmrlx_umin – inward flow velocity (m s-1) at which the use of prescribed boundary values becomes minimal. Use negative values to indicate outflow. At the specified inflow value, or lower, boundary values are for fraction tmrlx_min based on prescribed values; the remaining 1 - tmrlx_min is taken from a weighted mean over the sponge zone. If None, tmrlx_umin is set to -0.25 * tmrlx_ucut. Only used if tmrlx is True.

get_updater(boundary: OpenBoundary, array: Array, bdy: ndarray) Callable[[], None][source]

Return a function that updates the model values at the open boundary.

Boundary conditions that use nearby interior values (e.g., zero gradient, flow-dependent relaxation) can only use points with mask=ACTIVE (wet and active). They must skip mask=BOUNDARY to avoid dependence on the order in which boundaries are updated.

Parameters:
  • boundary – the open boundary

  • array – array with all model values

  • bdy – prescribed values at the open boundary. If depth-explicit, its shape is (np, nz), otherwise (np,)

initialize(grid: Grid)[source]

Create the relaxation coefficient array if using flow-dependent relaxation. This will be called for every open boundary of every array that uses this boundary condition, so we take care to only create the array once.

prepare_depth_explicit()[source]

Update the relaxation coefficient based on the current flow velocity. This is done once per timestep and processes all open boundaries at once.

static update_boundary(sponge_values: ndarray, bdy_values: ndarray, rlxcoef: ndarray, w: ndarray, nonzerow: ndarray, clamp: ndarray, bdy_setter: Callable[[ndarray], None])[source]

Update model values at open boundary. The sponge zone update is done from ArrayOpenBoundary.update(), via the relaxation term added in get_updater()

Parameters:
  • sponge_values – current model values in the sponge zone (inward from open boundary). (nz x np x nsponge)

  • bdy_values – prescribed values at open boundary (nz x np)

  • rlxcoef – fraction of model values at the open boundary to be taken from prescribed values. The remainder will be based on a weighted mean over the sponge. (nz x np)

  • w – weight for sponge mean used as part of new model values at the open boundary. (np x nsponge)

  • nonzerow – boolean array indicating where w is non-zero. Cells with zero weight will be excluded from the sponge mean in order to avoid blending in NaNs.

  • clamp – boolean array indicating where no sponge mean is available. In these cells, the model values will be clamped to the prescribed values.

  • bdy_setter – function that updates values at the boundary, respecting their valid range and mask

class pygetm.open_boundaries.ZeroGradient[source]

Bases: BoundaryCondition

Zero-gradient boundary condition

The model values at the open boundary are set to the values at the first point inward from the boundary.

get_updater(boundary: OpenBoundary, array: Array, bdy: ndarray) Callable[[], None][source]

Return a function that updates the model values at the open boundary.

Boundary conditions that use nearby interior values (e.g., zero gradient, flow-dependent relaxation) can only use points with mask=ACTIVE (wet and active). They must skip mask=BOUNDARY to avoid dependence on the order in which boundaries are updated.

Parameters:
  • boundary – the open boundary

  • array – array with all model values

  • bdy – prescribed values at the open boundary. If depth-explicit, its shape is (np, nz), otherwise (np,)