Parallel and multipatch grids
Inspect decomposition metadata and combine named grid patches. The first section runs on one process; the same constructor accepts an MPI communicator for parallel runs.
Decomposition metadata
Section titled “Decomposition metadata”Choose which axes may be split with domain_decomposition. On one process, the index bounds cover the full grid. num_ghost_points adds ghost nodes on both sides of each local axis.
from simgeometry.grid import Grid, MultiPatchGridComposite
grid = Grid( ndim=2, lower_bound=(0.0, 0.0), upper_bound=(1.0, 1.0), num_gridpoints=(18, 12), domain_decomposition=(True, False), num_ghost_points=1, periodic=(True, False),)print("rank:", grid.mpi_rank)print("process grid:", grid.proc_sizes)print("global index bounds:", grid.proc_index_bounds)print("local shape with ghosts:", grid.num_gridpoints_local_with_ghosts)rank: 0process grid: [1, 1]global index bounds: [(0, 18), (0, 12)]local shape with ghosts: (20, 14)For a multi-process run, install simgeometry[mpi], pass comm=MPI.COMM_WORLD, and launch the script with mpiexec -n 4 python script.py:
from mpi4py import MPIfrom simgeometry.grid import Grid
grid = Grid( ndim=2, lower_bound=(0.0, 0.0), upper_bound=(1.0, 1.0), num_gridpoints=(18, 12), comm=MPI.COMM_WORLD, domain_decomposition=(True, True), num_ghost_points=1,)print(grid.mpi_rank, grid.proc_index_bounds, grid.num_gridpoints_local)proc_index_bounds contains half-open global index ranges. neighbor_ranks gives lower and upper neighbors per axis, using MPI.PROC_NULL at nonperiodic walls. grid.domain_decomposition_class.layout(shape, halo=...) returns a matching mpiarray.Layout for field arrays.
Named patches
Section titled “Named patches”Combine separate Grid instances of the same dimension. Here two patches form an L with a gap in the upper-right region.
patches = { "vertical": Grid(2, (0.0, 0.5), (0.5, 2.0), (6, 16)), "horizontal": Grid(2, (0.5, 0.0), (2.0, 0.5), (16, 6)),}composite = MultiPatchGridComposite(patches)print("patches:", composite.patch_ids)print("upper leg:", composite.find_patch((0.25, 1.0)))print("lower leg:", composite.find_patch((1.0, 0.25)))print("gap:", composite.find_patch((1.0, 1.0)))patches: ('horizontal', 'vertical')upper leg: verticallower leg: horizontalgap: NonePatch coordinates are relative to that patch’s lower bound. global_to_local() can find the patch automatically, then local_to_global() converts back.
patch_id, local = composite.global_to_local((1.25, 0.25))print("patch and local position:", patch_id, local)print("back to global:", composite.local_to_global(local, patch_id))assert patch_id == "horizontal"assert local.tolist() == [0.75, 0.25]patch and local position: horizontal [0.75 0.25]back to global: [1.25 0.25]Use get_patch(id) and get_patch_bounds(id) for each child grid. Inherited single-grid properties on the composite describe its first patch alphabetically. PatchLibrary in simgeometry.multipatch can create descriptors for single, L, T, and cross layouts; check descriptor bounds before composing them because some layouts overlap and find_patch() returns the first match.