SFI.statefunc.layout package

Structured-dimensions layout sub-package.

Re-exports for backward compatibility with from SFI.statefunc.layout import ....

class SFI.statefunc.layout.GridLayout(*, dim, ndim, bc='pbc', order='C', key_grid_shape='box/grid_shape', key_dx='box/dx', **sectors)[source]

Bases: _BaseLayout

Layout for SPDE systems on regular Cartesian grids.

Provides differential operator methods and an embed() compiler that turns inner-world StructuredExpr trees into outer-world Basis / PSF objects.

Parameters:
  • ndim (int) – Number of spatial dimensions.

  • bc ({"pbc", "noflux"}) – Boundary condition for stencil operators.

  • order (str) – Grid flattening order ("C" default).

  • key_grid_shape (str) – Extras key for the grid shape array.

  • key_dx (str) – Extras key for the grid spacing.

  • **sectors (Sector) – Named sectors (keyword arguments).

  • dim (int)

Examples

>>> layout = GridLayout(
...     velocity=VectorSector([0, 1], sdim=2, spatial=True),
...     Q=SymTensorSector([2, 3], sdim=2, traceless=True),
...     dim=4, ndim=2, bc="pbc",
... )
>>> v = layout.velocity
>>> Q = layout.Q
>>> force = layout.embed(rank=1,
...     velocity=layout.lap(v),
...     Q=layout.lap(Q),
... )
advection_by(velocity, transported)[source]

Advection \((\mathbf{v}\cdot\nabla)\phi\).

velocity must have sdims (…, ndim) and transported is arbitrary. Contracts the spatial gradient with the velocity vector.

Parameters:
Return type:

StructuredExpr

property bc: Literal['pbc', 'noflux']

Boundary condition.

biharmonic(expr)[source]

Biharmonic ∇⁴. Rank-preserving. Requires ndim >= 2.

Parameters:

expr (StructuredExpr)

Return type:

StructuredExpr

const(value=1, label=None)

Scalar constant compatible with this layout.

Parameters:
  • value (float or int) – The constant value (default 1).

  • label (str, optional) – Human-readable label. Defaults to str(int(value)) for integer-valued numbers, str(value) otherwise.

Return type:

StructuredExpr

property dim: int
div(expr)[source]

Divergence. Contracts the last axis (must be ndim).

Input sdims (*S, ndim) → output sdims S.

Parameters:

expr (StructuredExpr)

Return type:

StructuredExpr

embed(rank=1, **named_fields)[source]

Compile inner-world expressions into an outer-world Basis/PSF.

Parameters:
  • rank (int) – Output rank (1 for forces, 2 for diffusion matrices).

  • **named_fieldssector_name=expression pairs. Each expression’s sdims must match the corresponding sector’s sdims.

Returns:

Outer-world expression ready for inference.

Return type:

Basis

grad(expr)[source]

Spatial gradient. Adds an (ndim,) trailing axis.

Input sdims S → output sdims S + (ndim,).

Parameters:

expr (StructuredExpr)

Return type:

StructuredExpr

lap(expr)[source]

Laplacian ∇². Rank-preserving (same sdims as input).

Parameters:

expr (StructuredExpr)

Return type:

StructuredExpr

lap_of_grad_sq(expr)[source]

∇²(|∇f|²) — the Active Model B+ term.

Convenience sugar for self.lap(self.grad(expr).dot(self.grad(expr))). Compiles to the biharmonic-radius stencil automatically via footprint computation. Requires ndim >= 2.

Parameters:

expr (StructuredExpr)

Return type:

StructuredExpr

property ndim: int

Number of spatial dimensions.

property sectors: dict[str, ScalarSector | VectorSector | SymTensorSector | TensorSector]

Read-only mapping name Sector.

strain_rate(v_expr)[source]

Symmetric strain rate \(E = (\nabla v + (\nabla v)^T)/2\).

Input: vector (ndim,). Output: symmetric tensor (ndim, ndim).

Parameters:

v_expr (StructuredExpr)

Return type:

StructuredExpr

unpack()

Return a dict of named symbolic field leaves.

Return type:

dict[str, StructuredExpr]

vorticity(v_expr)[source]

Antisymmetric vorticity \(\Omega = (\nabla v - (\nabla v)^T)/2\).

Input: vector (ndim,). Output: antisymmetric tensor (ndim, ndim).

Parameters:

v_expr (StructuredExpr)

Return type:

StructuredExpr

class SFI.statefunc.layout.IdentityLayout(dim)[source]

Bases: _BaseLayout

Trivial layout with a single state field spanning all of dim.

Example:

layout = IdentityLayout(dim=3)
x = layout.state  # StructuredExpr(sdims=(3,), n_features=1)
Parameters:

dim (int)

const(value=1, label=None)

Scalar constant compatible with this layout.

Parameters:
  • value (float or int) – The constant value (default 1).

  • label (str, optional) – Human-readable label. Defaults to str(int(value)) for integer-valued numbers, str(value) otherwise.

Return type:

StructuredExpr

property dim: int
embed(rank=1, **named_fields)[source]
Parameters:
Return type:

Any

property sectors: dict[str, ScalarSector | VectorSector | SymTensorSector | TensorSector]

Read-only mapping name Sector.

unpack()

Return a dict of named symbolic field leaves.

Return type:

dict[str, StructuredExpr]

class SFI.statefunc.layout.ScalarSector(indices)[source]

Bases: object

A single scalar field occupying one data index.

sdims = (), n_data = 1.

Parameters:

indices (tuple[int, ...])

indices: tuple[int, ...]
property n_data: int
property sdims: tuple[int, ...]
class SFI.statefunc.layout.StateLayout(*args, **kwargs)[source]

Bases: Protocol

Protocol for all layouts (Grid, Particle, Identity, …).

property dim: int

Total data width (x.shape[-1]).

embed(rank=1, **named_fields)[source]

Compile inner expressions into outer StateExpr.

Parameters:
Return type:

Any

unpack()[source]

Return named symbolic field leaves.

Return type:

dict[str, StructuredExpr]

class SFI.statefunc.layout.SymTensorSector(indices, sdim, traceless=False)[source]

Bases: object

A symmetric tensor field, Voigt-packed in data space.

sdims = (sdim, sdim).

When traceless=False (default), n_data = sdim * (sdim + 1) // 2 (full Voigt packing). When traceless=True, n_data = sdim * (sdim + 1) // 2 - 1 (the trace degree of freedom is removed: the diagonal is constrained so that \(Q_{00} + Q_{11} + \ldots = 0\)).

Parameters:
  • traceless (bool) – When True, the tensor is both symmetric and traceless. Only the independent components are stored in data space; the last diagonal entry is reconstructed as minus the sum of the other diagonal entries.

  • indices (tuple[int, ...])

  • sdim (int)

indices: tuple[int, ...]
property n_data: int
sdim: int
property sdims: tuple[int, ...]
traceless: bool
property voigt_pairs: list[tuple[int, int]]

Upper-triangle (i, j) pairs matching the index order.

When traceless=True the last diagonal pair (sdim-1, sdim-1) is omitted (it is reconstructed from the other diagonal entries).

class SFI.statefunc.layout.TensorSector(indices, sdims)[source]

Bases: object

A general tensor field with arbitrary sdims.

n_data = prod(sdims).

Parameters:
  • indices (tuple[int, ...])

  • sdims (tuple[int, ...])

indices: tuple[int, ...]
property n_data: int
sdims: tuple[int, ...]
class SFI.statefunc.layout.VectorSector(indices, sdim, spatial=False)[source]

Bases: object

A vector field with sdim components.

sdims = (sdim,), n_data = sdim.

Parameters:
  • spatial (bool) – When True, declares that this sector’s components correspond to spatial coordinates. Layouts with ndim validate that sdim == ndim.

  • indices (tuple[int, ...])

  • sdim (int)

indices: tuple[int, ...]
property n_data: int
sdim: int
property sdims: tuple[int, ...]
spatial: bool