Structures =========== All structures are immutable, frame-annotated, and built on plain ``jax.numpy`` arrays internally — every method returns a symbolic :class:`~prophys.symbolic.Expr`, so distances, areas, and interpolated values compose with the rest of the graph and stay differentiable. A singular form (``Point``, ``Line``) is simply a batch-of-one of the plural form (``PointList``, ``LineList``), sharing the same API. Point / PointList -------------------- .. autoclass:: prophys.structures.PointList :members: :undoc-members: .. autoclass:: prophys.structures.Point :members: Line / LineList ------------------ .. autoclass:: prophys.structures.LineList :members: :undoc-members: .. autoclass:: prophys.structures.Line :members: Polyline ----------- An ordered, *connected* vertex chain — a route — as opposed to ``LineList``'s unordered bag of independent segments. Its distinguishing capability is :meth:`~prophys.structures.Polyline.point_at`: a differentiable position at any fractional arc length along the whole chain, gradient flowing to the route's own vertex coordinates. This is the primitive for "a failure can occur anywhere along this route" models — a pipeline leak, a cable fault, a road-defect location — where the failure location itself should be a continuous, reparameterized :class:`~prophys.domain.RandomVariable` rather than a hand-picked set of candidate points: .. code-block:: python import jax import jax.numpy as jnp import prophys as prp site = prp.Frame("site", units="m") route = prp.Polyline(prp.Param("route", shape=(4, 2), init=initial_vertices), site) def expected_exposure(leak_key, receivers, wind_speed, wind_direction): leak_point = route.point_at(jax.random.uniform(leak_key, ())) # ... a plume/dispersion surrogate from leak_point to receivers, # exactly as in the gas-dispersion example, marginalized over the # wind climatology and now also over the leak's own location. Design optimization can then move the route's vertices — via ``prp.optimize`` — to jointly minimize expected exposure and routing cost, with the uncertainty over *where* a leak occurs built into the objective rather than assumed away. .. autoclass:: prophys.structures.Polyline :members: :undoc-members: Ray / RayList ---------------- A half-infinite line ``{origin + t * direction : t >= 0}`` — line-of-sight, sensor exposure, and directional risk (e.g. distance to the nearest hazard along a fixed bearing). .. autoclass:: prophys.structures.RayList :members: :undoc-members: .. autoclass:: prophys.structures.Ray :members: Ellipse / EllipseList ------------------------- A rotatable ellipse. Signed distance is an approximation (there is no closed form for a general ellipse) — exact for a circle, and accurate enough for containment checks and optimization elsewhere. .. autoclass:: prophys.structures.Ellipse :members: :undoc-members: .. autoclass:: prophys.structures.EllipseList :members: :undoc-members: Polygon / PolygonList ------------------------- .. autoclass:: prophys.structures.Polygon :members: :undoc-members: .. autoclass:: prophys.structures.PolygonList :members: :undoc-members: Polyhedron / PolyhedronList ------------------------------- 3D convex bodies given by a halfspace representation :math:`\{x : Ax \le b\}`. Used, e.g., for underground storage-tank exclusion volumes. .. autoclass:: prophys.structures.Polyhedron :members: :undoc-members: .. autoclass:: prophys.structures.PolyhedronList :members: :undoc-members: Field -------- A raster (scalar or vector) defined on a regular grid in a frame, with differentiable bilinear interpolation at arbitrary query points via ``jax.scipy.ndimage.map_coordinates``. .. image:: /_static/generated/gas_dispersion_terrain.png :width: 65% :align: center .. autoclass:: prophys.structures.Field :members: :undoc-members: Grid ------- A fixed rectangular candidate domain — not itself part of the probabilistic model, but the standard way to evaluate an expression densely for a risk-map plot or a design search. .. image:: /_static/generated/gas_dispersion_risk_map.png :width: 75% :align: center .. autoclass:: prophys.structures.Grid :members: :undoc-members: Network ---------- A directed graph in a shared frame: nodes are a :class:`~prophys.structures.PointList` (coordinates may be a ``Param``, so siting is optimizable), edges are a fixed ``(m, 2)`` connectivity array, and each edge carries an optional transmission ``weight`` — any expression, commonly a :class:`~prophys.symbolic.BinaryState` when whether a link is reinforced, open, or online is itself a design decision. ``Network`` models supply chains, power grids, and pipeline networks where risk cascades along edges: :meth:`~prophys.structures.Network.edge_lengths` gives per-edge distances (cable/pipe cost), :meth:`~prophys.structures.Network.as_lines` exposes the edges as a :class:`~prophys.structures.LineList` for proximity queries (e.g. distance from a house to the nearest line), and :meth:`~prophys.structures.Network.propagate` runs a differentiable multi-hop cascade of a per-node signal (a fault, a contamination front, a load spike) along the directed edges, decaying or amplifying at each hop according to the edge weights. .. autoclass:: prophys.structures.Network :members: :undoc-members: Field3D / Grid3 ------------------ The volumetric counterparts of ``Field``/``Grid``: a voxel raster on a regular 3D grid with differentiable trilinear interpolation, and a dense 3D evaluation lattice. Used for subsurface property fields, 3D concentration plumes, and atmospheric or thermal gradients where a single 2D slice isn't enough. .. autoclass:: prophys.structures.Field3D :members: :undoc-members: .. autoclass:: prophys.structures.Grid3 :members: :undoc-members: Mesh ------- An unstructured triangular mesh carrying a per-vertex scalar field, with differentiable barycentric (P1 finite-element) interpolation — the ingestion point for FEM/CFD solver outputs (stress, pressure, concentration) into a ``prophys`` graph. The mesh connectivity and vertex positions are fixed structure; the field values (and query points) stay differentiable, so a mesh-sampled physics surrogate can be calibrated against observations exactly like any other attribute. .. autoclass:: prophys.structures.Mesh :members: :undoc-members: