Source code for bornsim.medium.base
"""Numerical random-medium statistics, independent of analytical solutions."""
from abc import ABC, abstractmethod
from typing import TYPE_CHECKING
from ..grid import Grid
if TYPE_CHECKING:
from ..volume import Volume
[docs]
class Medium(ABC):
"""Abstract interface for media that can be sampled into a finite volume.
Instantiate :class:`bornsim.GaussianMedium` or :class:`bornsim.StructuredMedium`,
not this base class. Concrete media specify a uniform ``background_refractive_index``
and implement :meth:`to_volume` using cubic voxels, SI spacing, and centred
coordinates. The resulting field stores ``delta_refractive_index = n(r) - n0``;
propagation retains ``epsilon_r = n0**2 + 2*n0*delta_refractive_index``.
"""
background_refractive_index: float | None
@property
def is_random(self) -> bool:
"""Whether independent generation seeds represent random realizations."""
return False
@property
def metadata(self) -> dict[str, object]:
"""Return a fresh JSON-compatible description with numeric SI values.
Concrete media extend this dictionary with their own statistics or
geometry. Generation seeds and grids belong to individual volumes.
"""
return {"background_refractive_index": self.background_refractive_index}
[docs]
def add_background(self, *, refractive_index=None, medium=None, material=None):
"""Configure a composable medium's background in place.
StructuredMedium accepts exactly one of a positive uniform ``refractive_index``
or a RandomFieldMedium supplied as ``medium``. Statistical media describe
homogeneous distributions; use StructuredMedium to compose material.
"""
raise TypeError("Use StructuredMedium to compose backgrounds and structures.")
[docs]
def add_structures(self, *structures):
"""Append positional material shapes to a composable medium in place.
StructuredMedium supports Layer, Sphere, Ellipsoid, Box, and Cylinder.
Later structures replace earlier material wherever their masks overlap.
"""
raise TypeError("Use StructuredMedium to compose backgrounds and structures.")
[docs]
@abstractmethod
def to_volume(self, *, grid: Grid, seed: int = 0) -> "Volume":
"""Voxelize or sample this medium on an explicit Grid."""
raise NotImplementedError