Grid

Grid collection for managing multiple Block objects with connectivity analysis.

This module provides the Grid class which serves as the top-level container for multi-block structured CFD simulations. The Grid manages collections of Block objects with support for label-based access, automatic connectivity detection between blocks, and methods for computing domain-wide flow statistics. Key features include spatial indexing using KD-trees for efficient neighbor finding, detection and tracking of periodic and mixing-plane patch pairs, computation of circumferentially-averaged flow properties, and utilities for extracting boundary flows at inlets and outlets. The connectivity property provides detailed inter-block topology information essential for implementing multi-block boundary conditions, while the averaging capabilities enable efficient turbomachinery performance analysis across blade rows.

class ember.grid.Convergence(residual, mdot, ho, s, mdot_target=0.0, mdot_throttle=0.0, P_throttle=0.0, dP_P=0.0, dP_I=0.0, dP_D=0.0)

Bases: tuple

Create new instance of Convergence(residual, mdot, ho, s, mdot_target, mdot_throttle, P_throttle, dP_P, dP_I, dP_D)

P_throttle

Alias for field number 6

count(value, /)

Return number of occurrences of value.

dP_D

Alias for field number 9

dP_I

Alias for field number 8

dP_P

Alias for field number 7

ho

Alias for field number 2

index(value, start=0, stop=9223372036854775807, /)

Return first index of value.

Raises ValueError if the value is not present.

mdot

Alias for field number 1

mdot_target

Alias for field number 4

mdot_throttle

Alias for field number 5

residual

Alias for field number 0

s

Alias for field number 3

exception ember.grid.SolverDivergedError[source]

Bases: RuntimeError

Raised when a block’s conserved field contains a NaN.

A dedicated type lets a solver loop catch divergence precisely and exit cleanly (leaving the invalid field in place for debugging) while genuinely unexpected errors still propagate. See Grid.check_nan().

add_note(object, /)

Exception.add_note(note) – add a note to the exception

args
with_traceback(object, /)

Exception.with_traceback(tb) – set self.__traceback__ to tb and return self.

class ember.grid.Grid(blocks=None)[source]

Bases: _LabelledList

Initialize grid with optional list of blocks.

Parameters:

blocks (list, optional) – Initial list of blocks to add to the grid.

classmethod read_emb(filename)[source]

Read grid from EMB binary format file.

Automatically detects and handles both uncompressed and gzip-compressed EMB files.

Parameters:

filename (str) – Input EMB file to read

Returns:

New grid containing all blocks, patches, flow data, and metadata from EMB file

Return type:

Grid

Raises:

FileNotFoundError – If file does not exist

classmethod read_plot3d(p3d_file, fvbnd_file=None, flip_k=True)[source]

Read grid from Plot3D format file with optional boundary patches.

Parameters:
  • p3d_file (str) – Input Plot3D grid file to read

  • fvbnd_file (str) – Input FVBND boundary file to read patches from

  • flip_k (bool) – Whether to flip the k-axis to match write_plot3d behavior (default True)

Returns:

New grid containing blocks with coordinates and optional patches from files

Return type:

Grid

classmethod read_ts3(filename)[source]

Read grid from TS3 format file.

Parameters:

filename (str) – Input TS3 file to read

Returns:

New grid containing blocks with coordinates and flow data from TS3 file

Return type:

Grid

set_conserved_cart_unstr(xyz, conserved_cart)[source]

Set conserved variables from Cartesian unstructured data.

Useful for importing flow solutions from unstructured CFD solvers that store data on arbitrary point clouds in Cartesian coordinates.

Automatically detects the coordinate permutation and sign mapping that aligns the Cartesian data with the structured grid, converts coordinates to polar, and transforms the momentum vector accordingly.

The input conserved state vector is:

\[\mathcal{U}_{\mathrm{cart}} = \begin{pmatrix} \rho,\ \rho V_x,\ \rho V_y,\ \rho V_z,\ \rho e \end{pmatrix}\]

The Cartesian momentum components are first converted to velocities, rotated into the polar frame \((x, r, \theta)\), then reassembled as polar conserved variables:

\[\mathcal{U} = \begin{pmatrix} \rho,\ \rho V_x,\ \rho V_r,\ \rho r V_\theta,\ \rho e \end{pmatrix}\]

where the polar velocity components are:

\[\begin{split}V_r &= V_y \cos\theta - V_z \sin\theta \\ V_\theta &= -V_y \sin\theta - V_z \cos\theta\end{split}\]

with \(\theta = \mathrm{atan2}(-z,\, y)\).

Parameters:
  • xyz (array_like, shape (N, 3)) – Cartesian coordinates [x, y, z] with components on last axis

  • conserved_cart (array_like, shape (N, 5)) – Cartesian conserved flow variables [rho, rhoVx, rhoVy, rhoVz, rhoe] with components on last axis

set_fluid(fluid_obj)[source]

Set equation of state on all blocks, preserving any existing flow field.

The fluid object specifies the reference scales used to normalise stored thermodynamic quantities. This method rescales the stored nondimensional flow field so that the underlying dimensional state is unchanged. See ember.block.Block.set_fluid() for full details.

Parameters:

fluid_obj (Fluid) – New fluid / equation of state object.

set_L_ref(L_ref)[source]

Set reference length scale on all blocks, preserving dimensional geometry and flow field.

The reference length scale is used to normalise stored coordinates. This method rescales the stored nondimensional values so that the underlying dimensional geometry and flow field are unchanged. See ember.block.Block.set_L_ref() for full details of the nondimensionalisation.

Parameters:

L_ref (float) – Reference length scale [m].

set_primitive_cart_unstr(xyz, primitive_cart)[source]

Set primitive variables from Cartesian unstructured data.

Useful for importing flow solutions from unstructured CFD solvers that store data on arbitrary point clouds in Cartesian coordinates.

Automatically detects the coordinate permutation and sign mapping that aligns the Cartesian data with the structured grid, converts coordinates to polar, and rotates the velocity vector accordingly.

The input primitive state vector is:

\[\mathcal{P}_{\mathrm{cart}} = \begin{pmatrix} \rho,\ V_x,\ V_y,\ V_z,\ p \end{pmatrix}\]

The Cartesian velocity components are rotated into the polar frame \((x, r, \theta)\) to give the polar primitive state:

\[\mathcal{P} = \begin{pmatrix} \rho,\ V_x,\ V_r,\ V_\theta,\ p \end{pmatrix}\]

where:

\[\begin{split}V_r &= V_y \cos\theta - V_z \sin\theta \\ V_\theta &= -V_y \sin\theta - V_z \cos\theta\end{split}\]

with \(\theta = \mathrm{atan2}(-z,\, y)\).

Parameters:
  • xyz (array_like, shape (N, 3)) – Cartesian coordinates [x, y, z] with components on last axis

  • primitive_cart (array_like, shape (N, 5)) – Cartesian primitive flow variables [rho, Vx, Vy, Vz, P] with components on last axis

get_convergence()[source]

Grid-representative convergence monitors at one step, non-dimensional.

Stations are taken from row_station_bid_pid, derived from the grid’s own topology.

Returns:

  • Convergence – Namedtuple (residual, mdot, ho, s, mdot_target, mdot_throttle, P_throttle, dP_P, dP_I, dP_D). residual is the block-mean |residual_nd| per conserved variable, shape (5,). mdot, ho, s are shape (2*n_row,) station vectors at each row’s upstream then downstream face, inlet to outlet ([row0_up, row0_dn, row1_up, row1_dn, ...]), all non-dimensionalised by the fluid reference scales. The remaining scalar fields are the outlet PID throttle state from ember.outlet.OutletPatch.get_throttle_stats().

  • The rhorVt (angular-momentum) residual is divided per block by

  • block.r_mid_nd so its reported magnitude is a tangential-momentum

  • scale comparable to the rhoVx/rhoVr residuals. This rescaling is

  • for monitoring only; residual_nd itself (which drives the RK sweep)

  • is untouched.

get_r_ref()[source]

Calculate reference radial coordinates for each row of blocks.

For each element in Grid.rows, calculates the maximum and minimum r coordinates across all blocks, then stores the mean value in Grid.r_ref as a numpy array with the same length as rows.

accumulate_avg(n_step_avg)[source]

Add the current conserved field into the running time-average.

Accumulates each block’s conserved_nd / n_step_avg into its conserved_avg_nd buffer via the Fortran kernel. Called once per step over the final n_step_avg steps of a march, this builds the mean of the converged limit cycle. The buffer is a read-only cached array, so its flags.writeable is toggled around the in-place kernel write (mirrors update_sources()).

Returns:

self, for method chaining.

Return type:

Grid

apply_bconds()[source]

Apply all boundary conditions across the grid once.

Refreshes the mixing-plane targets, imposes the physical inlet, outlet, and mixing patch conditions on every block (each using its own relaxation factor rf), then closes the point-matched periodic seams.

Unlike the time-marching stepper this always applies the full set with no freeze or multigrid-level gating. The first call builds the periodic and mixing communicators lazily via connectivity; subsequent calls reuse the cached communicators until connectivity.clear().

Returns:

self, for method chaining.

Return type:

Grid

apply_guess_meridional(block_guess, refine_factor=1)[source]

Apply meridional flow field guess using curvilinear interpolation.

Uses a 1D meridional block as initial guess, interpolating flow properties to all blocks in the grid using nearest-neighbor search in the (x, r) meridional plane. Optionally refines the guess using curvilinear arc-length coordinates for improved interpolation quality.

Parameters:
  • block_guess (Block) – Block containing the 1D guess flow field with shape (ni,). Use block_guess.squeeze() first if your block has singleton dimensions.

  • refine_factor (int, optional) – Refinement factor for the guess block (default=1, no refinement). If > 1, the guess is interpolated along curvilinear arc length, providing a denser point cloud and smoother results.

Raises:

ValueError – If block_guess does not have shape (ni,)

apply_guess_quasi3d(block_guess)[source]

Apply quasi-3D flow field guess by interpolating between two meridional planes.

Uses two 2D meridional faces as boundary conditions on the low- and high-theta k-faces of each block, then linearly interpolates conserved variables across k as a function of the circumferential coordinate theta.

Parameters:

block_guess (Block, shape (ni, nj, 2)) – A single block whose k=0 face is the low-theta meridional plane and k=1 face is the high-theta meridional plane. i is streamwise, j is radial.

Raises:

ValueError – If block_guess does not have shape (ni, nj, 2).

apply_guess_restart(restarts)[source]

Apply a list of BlockRestart objects to this Grid, block by block.

Use this to initialize a fresh grid from a previously-saved solution. Same-shape blocks are set directly; differing shapes are trilinearly interpolated in index space. Only conserved variables are transferred; mu_turb is untouched.

Parameters:

restarts (list of BlockRestart) – One BlockRestart per block in this Grid.

Returns:

self, for method chaining.

Return type:

Grid

apply_rotation(row_types, Omega)[source]

Apply rotation settings to blocks based on row types.

Sets angular velocity and adds appropriate rotating wall patches to blocks based on the specified row type configuration. Supports stationary, tip_gap, and shroud configurations for turbomachinery applications.

Parameters:
  • row_types (list of str) – List of row type strings, one per row in the grid. Valid values: - “stationary”: No rotating patches (fixed frame) - “tip_gap”: Rotating patches on i=0, i=-1, j=0, k=0, k=-1 - “shroud”: Rotating patches on all boundaries (i=0, i=-1, j=0, j=-1, k=0, k=-1)

  • Omega (list of float) – List of angular velocities [rad/s], one per row in the grid. Positive values indicate rotation direction.

Raises:

Examples

>>> grid = Grid([block1, block2])
>>> grid.apply_rotation(["tip_gap"], [1000.0])  # Single rotating row
calculate_wdist(limit_pitch=inf)[source]

This method creates a pitchwise-repeated grid to include neighboring passages, extracts all wall nodes from the repeated blocks, builds a KDTree for efficient nearest neighbor search, and calculates the distance from each node to the nearest wall surface. The results are stored in each block using set_wdist().

The method uses real Cartesian coordinates (xyz) for accurate 3D distance calculations in turbomachinery applications.

Parameters:

limit_pitch (float, optional) – Cap the wall distance at limit_pitch times each row’s reference blade pitch (2*pi*r_ref/Nb). This bakes the mixing-length limit directly into the stored wall distance, so downstream turbulence models need no separate cap. Defaults to np.inf (no limit).

Examples

>>> grid = Grid([block1, block2])
>>> # Wall distances are now available as block.wdist for each block
check_nan()[source]

Scan every block’s density field for NaN; report the first bad block.

Cheap enough to call each solver step: only the density component conserved_nd[..., 0] is inspected, since a NaN in any conserved variable propagates into density within a step through the pressure/flux coupling. On the duct smoke test this costs ~0.5% of a single full-field residual evaluation.

Raises:

SolverDivergedError – If any block contains a NaN, naming the first such block (index and label). The grid is left untouched so the invalid field can be inspected.

copy(keep_patches=True)[source]

Create a deep copy of the grid with copied blocks.

Returns:

New Grid instance containing copies of all blocks.

Return type:

Grid

Example

>>> grid_copy = grid.copy()
>>> grid_copy[0].conserved[...] = 0  # Does not affect original grid
finalise_average()[source]

Commit the accumulated time-average as the solution.

Copies each block’s conserved_avg_nd into conserved_nd, refreshes the conserved-dependent caches, then re-zeros the accumulator so any subsequent averaging window starts clean. Owns the flags.writeable toggle on the read-only average buffer.

Returns:

self, for method chaining.

Return type:

Grid

flat()[source]

Return concatenated flattened view of all blocks.

Returns:

Single block containing concatenated flat data from all blocks

Return type:

Block

interp_from(src)[source]

Interpolate solution from src Grid onto this one, block by block.

Parameters:

src (Grid) – Source Grid providing the solution.

Returns:

self, for method chaining.

Return type:

Grid

resample(factors)[source]

Resample all blocks, returning a new Grid at the new resolution.

smooth(sf4, sf2)[source]

Apply constant-coefficient artificial dissipation to every block.

Fans the fixed-sf2/sf4 ember.fortran.smooth3d_const() kernel across the grid, filtering each block’s conserved_nd in place. Unlike the adaptive (P/T-weighted) smoother it has no thermodynamic input at all and never touches the pressure cache, so it is safe to run on the post-march solution while P/T are frozen (Denton-style “smooth with the old pressure”). Purely per-block; the nodal work array is borrowed from each block’s transient scratch buffer.

sf4/sf2 are the final coefficients – any CFL scaling is the caller’s responsibility.

update_bconds(freeze=False)[source]

Refresh boundary-condition targets across the grid once.

Advances the slowly-varying BC state that the per-substep apply_bconds() then imposes: exchanges mixing-plane data, snapshots the inlet pressure datum, and re-derives the outlet PID/spanwise pressure target. Should be called once per outer timestep, before the Runge-Kutta stages.

When freeze is True the targets are held stationary – the mixing exchange and the outlet target re-derivation are skipped – so an averaging window sees a fixed boundary. The update_soln snapshots still run so backflow density relaxation stays anchored to the current step.

Returns:

self, for method chaining.

Return type:

Grid

update_cached_conserved()[source]

Refresh conserved-dependent caches on every block.

Fans update_cached_conserved() out across the grid, forcing each block’s cached properties keyed on the conserved variables to recompute on next access. Needed after writing conserved_nd directly (bypassing the setters), e.g. the explicit scree march.

Returns:

self, for method chaining.

Return type:

Grid

update_filter(delta_filt, cfl)[source]
update_residual(dampin=None, sf=0.0)[source]

Rebuild the unintegrated net-flow residual on every block.

Fans the fused set_residual kernel across the grid, writing each block’s residual_nd from its frozen P/T cache, face areas, and body force. Purely per-block (no inter-block exchange), so it simply loops.

Optional post-processing runs in place on each block’s residual, in order: implicit residual smoothing (sf), then the change limiter (dampin).

Parameters:
  • dampin (float, optional) – Negative-feedback change limiter (multall’s DAMP). When given, each block’s residual is passed through damp_residual, which soft-clips cells whose per-step change residual * dt_vol is a large outlier relative to the per-variable block mean, shrinking them by 1/(1 + fdamp/dampin) with fdamp = |change|/mean. Large outliers saturate towards dampin * mean. None (the default) disables it. multall recommends 2..100. Requires dt_vol_nd to have been populated by update_timestep().

  • sf (float, optional) – Implicit residual-smoothing (IRS) coefficient (epsilon). 0 (the default) disables IRS; > 0 applies the exact factored-tridiagonal smoother to each block via smooth_residual_tri_tiled. IRS damps high-frequency residual content so the explicit march tolerates a higher CFL; because it acts only on the residual (which vanishes at convergence) it does not change the steady-state solution. Per-block only: block/periodic interfaces are treated as zero-gradient. Borrows block.scratch as its work buffer – free at this point, since set_residual has finished using it as flow_i and the march reuses it only afterwards.

Returns:

self, for method chaining.

Return type:

Grid

update_sources(inviscid, gain_filt)[source]

Zero and rebuild the body force on every block of this grid level.

Assembles, into each block.F_body_nd, the viscous shear stresses (unless inviscid), the polar source, and the optional SFD force (when gain_filt is nonzero) – in that order, so the viscous momentum/energy negation does not flip the polar source added afterwards.

The viscous calculation is phased across the whole grid: every block’s tau/q is computed first, then a single periodic seam halo exchange runs, then the face fluxes are accumulated. This keeps the seam consistent for block-to-block periodic interfaces, where a per-block exchange would read a stale neighbour halo.

Parameters:
  • inviscid (bool) – Skip the viscous shear-stress/heat-flux terms when True.

  • gain_filt (float) – Selective-frequency-damping gain; the SFD force is added only when nonzero.

Returns:

self, for method chaining.

Return type:

Grid

update_timestep(rf, fac_visc=1.0)[source]

Recompute the volumetric time step on every block.

Uses the JST/Blazek multidimensional definition dt_vol = 1 / max(lam_conv, lam_diff), where lam_conv sums the convective spectral radii Lambda_d = |V_rel . dA_d| + a*||dA_d|| over the three directions and lam_diff = fac_visc * (mu_turb/rho)*sum_d||dA_d||^2/vol is the turbulent-diffusion radius over the same faces (set_timestep_spectral()). Building both from the directional face areas makes the stable CFL aspect-ratio-independent (pinned near 2*sqrt(2) for the 4-stage RK march) for the viscous limit too.

rf is the relaxation factor blending the new dt_vol with the existing buffer as rf*new + (1-rf)*old (pass rf=1.0 for a fresh recompute). This is the lone writer of each block’s read-only dt_vol_nd buffer, so it owns the flags.writeable toggle.

fac_visc (>= 1) multiplies the diffusion radius so the viscous march tolerates the same cfl as the inviscid one; 1.0 leaves the bare directional radius untouched.

Returns:

self, for method chaining.

Return type:

Grid

write_emb(filename, compress=False)[source]

Write grid to EMB binary format file.

Parameters:
  • filename (str) – Output filename for EMB file

  • compress (bool, optional) – If True, compress the file using gzip (default False)

Raises:

ValueError – If grid is empty (contains no blocks)

write_fvbnd(filename, region_id=0)[source]

Write boundary conditions in FieldView boundary (.fvbnd) format.

The FVBND format is used by FieldView to specify boundary regions for visualization purposes. See FieldView Reference Manual page 520.

Parameters:
  • filename (str) – Output filename for FieldView boundary file

  • region_id (int, optional) – Region identifier for labeling patches (default 0)

Raises:

ValueError – If grid is empty (contains no blocks)

write_plot3d(p3d_filename, fvbnd_filename=None, flip_k=True, iregion=0)[source]

Write grid to Plot3D format with optional FVBND boundary file.

Parameters:
  • p3d_filename (str) – Output filename for Plot3D grid file

  • fvbnd_filename (str) – Output filename for FVBND boundary file. If None, no boundary file is written

  • flip_k (bool) – Whether to flip the k-axis for proper volume orientation in Pointwise (default True)

  • iregion (int) – Region number for labeling in FVBND file (default 0)

Raises:

ValueError – If grid is empty (contains no blocks)

Return type:

None

write_ts3(filename, strict=False)[source]

Write grid to TS3 format file.

Parameters:
  • filename (str) – Output filename for TS3 file

  • strict (bool, optional) – Whether to strictly validate all variables (default False)

Raises:

ValueError – If grid is empty (contains no blocks)

property connectivity

Get the cached connectivity manager for this grid.

The manager is built once and cached on the grid, so the pairings and communicators it owns are computed lazily and reused. Call grid.connectivity.clear() to invalidate the cache after changing the grid topology (adding/removing blocks or patches).

Returns:

Connectivity manager providing access to patch connections via patch-type-specific properties and methods.

Return type:

GridConnectivityManager

property n_row

Get the number of blade rows in the grid.

Returns:

Number of blade rows (groups of blocks connected by periodic patches).

Return type:

int

Examples

>>> grid = Grid([block1, block2])  # Single row
>>> grid.n_row  # Returns 1
>>>
>>> grid_multi = Grid([stator_blocks, rotor_blocks])  # Two rows
>>> grid_multi.n_row  # Returns 2
property patches

Get read-only view of all patches across all blocks.

Returns:

Read-only collection providing access to all patches from all blocks with patch type filtering (periodic, mixing, inlet, outlet, wall).

Return type:

GridPatchCollection

property row_station_bid_pid

Per-row upstream/downstream measurement-station patch identifiers.

Returns:

[(up_idx, dn_idx), ...], one pair per blade row ordered inlet to outlet. Each entry is a list of (bid, pid) patch identifiers: the row’s upstream face (inlet for the first row, otherwise mixing) then its downstream face (outlet for the last row, otherwise mixing). Consumed by get_convergence() and ember.convergence_history.ConvergenceHistory.from_grid().

Return type:

list of (list of (int, int), list of (int, int))

property rows

Get blade rows by grouping blocks connected by periodic patches.

Blocks connected by periodic patches are in the same blade row. Multiple rows are separated by mixing patches. Rows are ordered from inlet to outlet based on mixing patch connectivity.

Returns:

List of blade rows, where each row is a list of Block objects. Blocks within a row are connected by periodic patches. Rows are ordered from inlet (upstream) to outlet (downstream).

Return type:

List[List[Block]]

Examples

>>> # Single-row grid
>>> grid = Grid([block1, block2])
>>> rows = grid.rows  # Returns [[block1, block2]]
>>>
>>> # Multi-row grid with mixing patches
>>> grid = Grid([stator_blocks, rotor_blocks])
>>> rows = grid.rows  # Returns [[stator_blocks...], [rotor_blocks...]]
property size

Total number of grid points across all blocks.

Returns:

Sum of all block sizes in the grid

Return type:

int

append(item)

Add item to collection.

Parameters:

item (Any) – Item to add to the collection. The item manages its own label.

Raises:

ValueError – If item’s label already exists in the collection.

clear()

Remove all items from collection.

extend(items)

Add multiple items to collection.

Parameters:

items (list) – List of items to add. Each item manages its own label.

Raises:

ValueError – If any item’s label already exists in the collection.

index(item, start=0, stop=None)

Return index of first occurrence of item.

Parameters:
  • item (Any) – Item to find.

  • start (int, optional) – Start index for search.

  • stop (int, optional) – Stop index for search.

Returns:

Index of the item.

Return type:

int

insert(index, item)

Insert item at specific index.

Parameters:
  • index (int) – Index at which to insert the item.

  • item (Any) – Item to insert. The item manages its own label.

property labels

List of item labels, in order, including None for unlabelled items.

Returns:

The label of each item in the collection. Entries are None where an item has no label.

Return type:

list

pop(index=-1)

Remove and return item at index (default last).

Parameters:

index (int, optional) – Index of item to remove and return. Default is -1 (last item).

Returns:

The removed item.

Return type:

Any

remove(item)

Remove first occurrence of item.

Parameters:

item (Any) – Item to remove.

class ember.grid.GridConnectivity(grid, patch_class)[source]

Bases: object

Initialize connectivity manager for a specific patch type.

Parameters:
  • grid (Grid) – The grid containing blocks with patches to analyze for connectivity

  • patch_class (type) – Subclass of Patch to filter and operate on

apply()[source]

Apply the communicator’s averaging (periodic and non-matching patches).

clear()[source]

Drop cached pairings and communicator so they rebuild on next use.

exchange()[source]

Exchange in/out flux state across mixing-plane patches.

exchange_halos()[source]

Exchange halo data across periodic patches.

pair(rtol=1e-06)[source]

Pair patches of the specified type, caching the result.

Filters patches to only include instances of self.patch_class, then uses spatial proximity (KDTree in x,r coordinates) to find potential matches and delegates to each patch’s check_match method for validation. The result is cached; call clear() to recompute after topology changes.

Parameters:

rtol (float, optional) – Relative tolerance for matching (passed to patch check_match methods)

Returns:

Dictionary where keys are (bid, pid) tuples and values are ((matching_bid, matching_pid), transform) tuples. Both patches in each pair are included as separate keys.

Return type:

dict

Raises:

ValueError – If any patch does not have a matching pair

class ember.grid.GridConnectivityManager(grid)[source]

Bases: object

Initialize connectivity manager for a grid.

Parameters:

grid (Grid) – The grid containing blocks with patches

clear()[source]

Drop all cached pairings and communicators across every patch type.

pair(rtol=1e-06)[source]

Pair all patch types and return combined connectivity dictionary.

Parameters:

rtol (float, optional) – Relative tolerance for matching (passed to patch check_match methods)

Returns:

Combined dictionary where keys are (bid, pid) tuples and values are ((matching_bid, matching_pid), transform) tuples for all patch types.

Return type:

dict

property cusp

Get connectivity manager for cusp patches.

property mixing

Get connectivity manager for mixing patches.

property nonmatch

Get connectivity manager for non-matching patches.

property periodic

Get connectivity manager for periodic patches.