Communicators¶
A communicator exchanges data across the seam between blocks for one patch
type. connectivity builds and caches one per patch
type on first use – reached as grid.connectivity.periodic, .mixing
and .nonmatch – pairing each patch to its partner on a neighbouring
block the first time it is used. Pairing is therefore automatic, triggered by
the first exchange, e.g. a call to apply_bconds(). See
Connectivity for how the pairing cache is invalidated on a
topology change.
The pairings can be inspected directly, by calling say
grid.connectivity.periodic.pair() for periodic patches. It returns a dict
keyed by the (bid, pid) identifier of each patch, indexing like
grid[bid].patches[pid]. The dict values are the corresponding (bid,
pid) of the patch it matches and the geometric transform between the two.
Both halves of a pair appear as keys, so the mapping can be followed from
either side:
pairs = grid.connectivity.periodic.pair()
# block 0 patch 0 is paired with block 1 patch 0, and vice versa
pairs[(0, 0)] # ((1, 0), transform)
pairs[(1, 0)] # ((0, 0), transform)
Each communicator below is built lazily by
GridConnectivity from the pairing above, and exposes
apply() (write the exchange straight into block.conserved) and,
where the patch type needs it, exchange() (compute the cross-plane
targets without applying them).
Periodic boundary condition communication and data averaging utilities.
This module provides the PeriodicCommunicator class which manages data exchange and averaging between periodic patch pairs in multi-block grids. The communicator takes connectivity information from the grid and sets up efficient index mappings that account for arbitrary coordinate transformations (permutations and flips) between matching periodic patches. The class prunes bidirectional connectivity to create unidirectional pairs, precomputes transformed index arrays for fast access, and applies periodic boundary conditions by averaging conserved flow variables at corresponding spatial locations using Fortran-accelerated routines. This ensures consistency across periodic boundaries in turbomachinery simulations with blade row periodicity or other rotationally symmetric configurations.
- class periodic_communicator.PeriodicCommunicator(grid, periodic_pairs)[source]¶
Manages data communication between periodic patches.
Takes the output of grid.connectivity.periodic.pair() and sets up matching ijk indices for efficient periodic boundary condition communication.
- Parameters:
- ijk_node_flat¶
Flattened ijk indices: {(bid, pid): indices.reshape(-1, 3)} for both source patches (untransformed) and target patches (transformed)
- Type:
- apply()[source]¶
Apply periodic boundary conditions by averaging conserved variables.
Loops over all patch pairs and calls Fortran average_by_ijk to average the conserved variables at corresponding ijk locations between patches.
- exchange_faces()[source]¶
Fill each block’s face-buffer halo layer from its periodic partner.
The one seam exchange the viscous pass needs, run between
set_tau_q_facesandset_visc_force: it fills the halo layer of each block’stau_q_faceswith the adjacent block’s owned edge-cell tau/q, so the face flux there averages two real cell values instead of the -edge ghost the producer seeded. Reads layer 0 (the partner’s own edge cells) and writes layer 1 (this side’s halo), so it never reads and writes the same storage and needs no temporary.TWO CALLS PER PAIR, one each way, because
self.pairsis pruned to a single key per pair, and a copy cannot move both directions at once. A block periodic to itself cannot catch a regression here – both ends are the same block – which is why the gate for this is a two-block case.
Mixing plane boundary condition communication.
MixingCommunicator pairs the two sides of the mixing plane of
MixingPatch, holds the relaxation factor and the per-pair diagnostics,
and carries out the exchange itself: it takes the cross-plane flux mismatch,
splits it by direction of propagation after Saxer and Giles [2], and writes the
result in the mix variables \([h_0, s, V_r, V_\theta, p]\) its patches
take their pitchwise-mean residuals against.
A run with mix_reflective set bypasses all of
that, exchanging the plain average of the two circumferential means instead.
- class mixing_communicator.MixingCommunicator(grid, mixing_pairs)[source]¶
Initialize with grid and mixing patch pairs.
- Parameters:
- Raises:
ValueError – If the two sides of a plane disagree on
rf_exchange.
- leak = 0.0¶
Anti-windup leak on the integrating relaxation, as a fraction of
rf_exchangeper exchange.The exchange accumulates its correction onto the previous target rather than re-anchoring to the live interface baseline every step, so that the fixed point is exact flux balance rather than the proportional form’s standing offset (Holmes [3] Eq. 15, applied to the auxiliary cells rather than re-derived each step). A pure integrator can wind up while the mismatch has not yet resolved – most a reversed station whose own boundary condition has not caught up with a target that has already moved past what the flow was ever in. A positive leak bleeds the target back toward the live baseline each step, trading a
leak/rf_exchange-scaled residual flux mismatch for a bound on how far the target can wander. Zero is exact Holmes; engage only if a station is seen to wind up.
- Ma_clip = 0.05¶
Floor on \(\lvert \mathit{Ma}_x \rvert\) of the symmetrised mean state the Jacobians are evaluated on.
Holmes [3] Eq. 16: as the mean normal velocity tends to zero the eigenvalues of the transformation matrices grow, so the interface over-controls to make up for the slow advection the small velocity implies. Bounding the magnitude – not the direction, which a reversed station keeps – is his remedy and this is ember’s form of it. It also keeps
flux_to_primitive(), which divides by the axial velocity, away from zero.See
Ma_clip_maxfor the other end of the same band.
- Ma_clip_max = 0.9¶
Ceiling on \(\lvert \mathit{Ma}_x \rvert\) of that same state, the other end of
Ma_clip’s band.Holmes bounds the normal velocity only from below, because that is where his eigenvalues blow up. The upper end matters here for a different reason: the plane’s whole characteristic treatment is derived for a mean state subsonic normal to it (see
MixingPatch), and a station that briefly runs past sonic during a transient would otherwise be linearised with the wrong number of incoming characteristics rather than merely inaccurately. Clipping keeps such a station inside the theory until the flow brings it back.
- get_stats(bid, pid)[source]¶
Return last-step relaxation increment for one pair.
- Returns:
Key
du(last relaxation increment in the exchanged target’s own variables, shape(nspan, 5)). ReturnsNoneif the pair has not been exchanged yet.- Return type:
dict or None
- exchange()[source]¶
Compute and write targets for all pairs (no apply step).
Under
mix_reflectivea pair is instead given the plain average of the two circumferential means.
Non-matching patch boundary condition communication.
This module provides the NonMatchCommunicator class which manages data exchange between non-matching patch pairs in multi-block grids. Unlike periodic patches that require identical node distributions, non-matching patches allow arbitrary mesh refinement changes across block boundaries.
The communicator uses parametric interpolation to transfer conserved variables between patches with different nodal distributions but identical physical locations. It precomputes parametric (u,v) coordinates during initialization and uses bilinear interpolation to transfer data at each timestep.
- class nonmatch_communicator.NonMatchCommunicator(grid, nonmatch_pairs)[source]¶
Manages data communication between non-matching patches.
Takes the output of grid.connectivity.nonmatch.pair() and sets up parametric interpolation for efficient non-matching boundary condition communication.
Unlike PeriodicCommunicator which averages at matching ijk indices, this communicator interpolates between patches with different node distributions.
- Parameters:
- uv_coords¶
Cached parametric coordinates: {(bid, pid): uv_array} where uv_array has shape (…, …, 2) with [u, v] ∈ [0,1]^2
- Type: