fdtdx.RectilinearGrid#
- class fdtdx.RectilinearGrid(*, x_edges=null, y_edges=null, z_edges=null)[source]#
Bases:
TreeClassRealized rectilinear simulation grid described by physical cell edges.
This is the canonical solver-facing grid representation used by fdtdx internals. A uniform grid is represented by equally spaced edge arrays, not by a separate scalar code path. Keeping one realized representation is important for the non-uniform grid migration: placement, PML profiles, mode-solver coordinates, detector weights, and Yee update metrics should all ask the grid for physical distances instead of deriving them from a global
resolutionvalue.The arrays store cell edges in metres. For a grid with
nxcells along x,x_edgeshas shape(nx + 1,)and must be strictly increasing. Cell widths, centers, face areas, and volumes are derived from these arrays.Notes
This class intentionally does not encode automatic mesh generation policy. Future policy objects such as
AutoGridorQuasiUniformGridshould resolve toRectilinearGridbefore the solver runs.
Quick Reference#
Attributes
Methods
Attributes#
- RectilinearGrid.dx#
Cell widths along x in metres.
- RectilinearGrid.dy#
Cell widths along y in metres.
- RectilinearGrid.dz#
Cell widths along z in metres.
- RectilinearGrid.is_uniform#
Whether all cell widths match a single spacing within numerical tolerance.
- RectilinearGrid.min_spacing#
Smallest cell width in the grid.
This value is the conservative spacing used for staged CFL migration. The full non-uniform update should eventually use explicit local metric arrays, but stability remains controlled by the smallest cell.
- RectilinearGrid.min_spacings#
Smallest cell width along each axis in metres.
- RectilinearGrid.shape#
Number of cells along each axis.
- RectilinearGrid.uniform_spacing#
Return the scalar spacing for a uniform grid or raise for non-uniform grids.
This compatibility escape hatch should only be used by code that has not yet been migrated to metric-aware helpers. It deliberately raises for non-uniform grids so unsupported paths fail loudly.
-
RectilinearGrid.x_edges:
Array# Physical edge coordinates along x in metres, shape
(nx + 1,).
-
RectilinearGrid.y_edges:
Array# Physical edge coordinates along y in metres, shape
(ny + 1,).
-
RectilinearGrid.z_edges:
Array# Physical edge coordinates along z in metres, shape
(nz + 1,).
Methods#
- RectilinearGrid.anchor_coordinate(axis, bounds, position)[source]#
Return a physical anchor coordinate inside an interval.
positionfollows fdtdx object-anchor convention:-1is the lower side,0is the center, and+1is the upper side.- Return type:
float
- RectilinearGrid.aset(attr_name, val, create_new_ok=False)#
Sets an attribute of this class. In contrast to the classical .at[].set(), this method updates the class attribute directly and does not only operate on jax pytree leaf nodes. Instead, replaces the full attribute with the new value.
The attribute can either be the attribute name of this class, or for nested classes it can also be the attribute name of a class, which itself is an attribute of this class. The syntax for this operation could look like this: “a->b->[0]->[‘name’]”. Here, the current class has an attribute a, which has an attribute b, which is a list, which we index at index 0, which is an element of type dictionary, which we index using the dictionary key ‘name’.
Note that dictionary keys cannot contain square brackets or single quotes (even if they are escaped).
- Parameters:
attr_name (str) – Name of attribute to set
val (Any) – Value to set the attribute to
create_new_ok (bool, optional) – If false (default), throw an error if the attribute does not exist. If true, creates a new attribute if the attribute name does not exist yet.
- Returns:
Updated instance with new attribute value
- Return type:
Self
- RectilinearGrid.axis_extent(axis, bounds)[source]#
Physical length covered by an index interval on one axis.
- Return type:
float
- RectilinearGrid.bounds_for_anchor(axis, size, anchor, position)[source]#
Choose a cell interval whose object anchor is closest to
anchor.- Parameters:
axis (
int) – Grid axis.size (
int) – Number of cells in the interval.anchor (
float) – Desired physical anchor coordinate in metres.position (
float) – Object-relative anchor position, where-1is lower side,0is center, and+1is upper side.
- Return type:
tuple[int,int]- Returns:
(lower, upper)edge indices withupper - lower == size.
- RectilinearGrid.bounds_for_center(axis, center, size)[source]#
Choose a cell interval whose physical center is closest to
center.- Parameters:
axis (
int) – Grid axis.center (
float) – Desired physical center coordinate in metres.size (
int) – Number of cells in the interval.
- Return type:
tuple[int,int]- Returns:
(lower, upper)edge indices withupper - lower == size.
Notes
This operation is used by object placement when a physical center position and an already-resolved grid-cell size are known. On a non-uniform grid there is no exact analogue of
round(x / dx); selecting the closest physical interval center gives deterministic snapping while preserving the requested grid-cell size.
- RectilinearGrid.cell_volume(slice_tuple)[source]#
Return per-cell volume weights broadcast to a 3D slice shape.
- Return type:
Array
- RectilinearGrid.cfl_time_step(courant_factor)[source]#
Return the CFL-limited time step for a rectilinear 3D grid.
The stability limit for an orthogonal FDTD grid is controlled by the smallest spacing on each axis:
dt <= courant_factor / (c * sqrt(1/dx_min^2 + 1/dy_min^2 + 1/dz_min^2)).For uniform grids this is exactly the existing
courant_factor/sqrt(3)behavior. For anisotropic or stretched grids it avoids using one global spacing for all three axes.- Return type:
float
- RectilinearGrid.coord_to_index(axis, coord, snap='nearest')[source]#
Map a physical coordinate to a grid edge index.
- Parameters:
axis (
int) – Grid axis.coord (
float) – Coordinate in metres.snap (
str) – Snapping rule."nearest"chooses the closest edge,"lower"chooses the previous edge, and"upper"chooses the next edge.
- Return type:
int- Returns:
Edge index after applying the requested snapping rule.
- classmethod RectilinearGrid.custom(x_edges, y_edges, z_edges)[source]#
Create a realized rectilinear grid from explicit edge arrays.
This constructor is equivalent to calling
RectilinearGrid(...)directly, but it makes the user-facing intent explicit: the caller is supplying the final grid coordinates, not an automatic meshing policy.
- RectilinearGrid.face_area(axis, slice_tuple)[source]#
Return per-cell face-area weights for a detector plane.
- Parameters:
axis (
int) – Normal axis of the face.slice_tuple (
tuple[tuple[int,int],tuple[int,int],tuple[int,int]]) – Grid slice containing the detector volume. The normal axis is expected to have width one for a plane detector.
- Return type:
Array- Returns:
Area weights broadcast to the detector’s 3D slice shape.
- RectilinearGrid.get_class_fields()#
- Return type:
list[TreeClassField]
- RectilinearGrid.get_public_fields()#
- Return type:
list[TreeClassField]
- RectilinearGrid.length_to_cell_count(axis, length, snap='nearest')[source]#
Convert a physical length to a number of cells from the lower domain edge.
This helper preserves the old uniform-grid behavior when
snapis"nearest". For non-uniform placement,"upper"is usually the safer rule because it chooses enough cells to cover the requested metric size from the lower domain edge.- Return type:
int
- RectilinearGrid.reduce_symmetric(symmetry)[source]#
Return the grid reduced onto the kept (upper) half along each symmetric axis.
Used by
place_objectswhenconfig.symmetryis set on a non-uniform grid: the simulation runs on the reduced (half/quarter/octant) domain and the result is unfolded afterwards. For every axis withsymmetry[a] != 0this keeps the upper-half edgesedges(a)[n // 2:](absolute coordinates preserved — the FDTD metrics depend only on cell widths, which are translation-invariant). Non-symmetric axes are returned unchanged.Two conditions must hold on each symmetric axis so that mirroring the kept half exactly reconstructs the full domain:
an even cell count, so the split lands on a cell edge, and
mirror-symmetric cell widths about the center (
dx[i] == dx[n - 1 - i]), so the discarded lower half is the exact mirror of the kept half.
- Parameters:
symmetry (tuple[int, int, int]) – Per-axis symmetry condition
(x, y, z);0means no reduction on that axis (any nonzero value reduces it).- Returns:
The reduced grid (a new instance; the original is unchanged).
- Return type:
- Raises:
ValueError – If a symmetric axis has an odd (or < 2) cell count, or cell widths that are not mirror-symmetric about the center.
- RectilinearGrid.slice_extent(slice_tuple)[source]#
Physical side lengths covered by a 3D grid slice.
- Return type:
tuple[float,float,float]
- RectilinearGrid.subgrid(grid_slice)[source]#
Convenience wrapper to get the sub-grid of a placed fdtdx.SimulationObject given its grid_slice
- classmethod RectilinearGrid.uniform(shape, spacing, origin=None, center=(0.0, 0.0, 0.0))[source]#
Create a realized rectilinear grid for a uniform grid.
The grid is centered at
centerby default, so edge arrays span[center[a] - shape[a] * spacing / 2, center[a] + shape[a] * spacing / 2]along each axis. Negative and positive coordinates are used symmetrically around the center of the simulation domain.Passing an explicit
origin(lower-corner coordinate) overridescenterand restores the legacy lower-corner behaviour. This is used internally byUniformGrid.resolveafter it has already computed the lower corner from the center.- Parameters:
shape (
tuple[int,int,int]) – Number of cells in(x, y, z).spacing (
float) – Uniform cell width in metres.center (
tuple[float,float,float]) – Physical coordinate of the domain center. Defaults to(0, 0, 0)so the domain spans equally into negative and positive coordinates.origin (
tuple[float,float,float] |None) – Physical coordinate of the lower domain corner. When provided this takes priority overcenter.
- Returns:
A grid whose edge arrays are equally spaced and centered on
center(or anchored atoriginwhen given).
If you find any errors in the documentation, please report them in the Github Issues!