def boundary_objects_from_config(
config: BoundaryConfig,
volume: SimulationVolume,
) -> tuple[dict[str, Union[PerfectlyMatchedLayer, PeriodicBoundary]], list[PositionConstraint]]:
"""Creates boundary objects from a boundary configuration.
Creates PerfectlyMatchedLayer or PeriodicBoundary objects for all six boundaries
(min/max x/y/z) based on the provided configuration. Also generates position
constraints to properly place the boundary objects relative to the simulation volume.
Args:
config (BoundaryConfig): Configuration object containing boundary parameters
volume (SimulationVolume): The main simulation volume object that the boundaries will surround
Returns:
tuple[dict[str, Union[PerfectlyMatchedLayer, PeriodicBoundary]], list[PositionConstraint]]: tuple containing:
- dict mapping boundary names ('min_x', 'max_x', etc) to boundary objects
- list of PositionConstraint objects for placing the boundaries
"""
boundaries, constraints = {}, []
thickness_dict = config.get_dict()
type_dict = config.get_type_dict()
kappa_start_dict = config.get_kappa_dict("kappa_start")
kappa_end_dict = config.get_kappa_dict("kappa_end")
for kind, thickness in thickness_dict.items():
axis, direction = axis_direction_from_kind(kind)
boundary_type = type_dict[kind]
kappa_start, kappa_end = kappa_start_dict[kind], kappa_end_dict[kind]
grid_shape_list: list[int | None] = [None, None, None]
grid_shape_list[axis] = thickness if boundary_type == "pml" else 1
grid_shape: PartialGridShape3D = tuple(grid_shape_list) # type: ignore
other_axes = [0, 1, 2]
del other_axes[axis]
if boundary_type == "pml":
cur_boundary = PerfectlyMatchedLayer(
axis=axis,
partial_grid_shape=grid_shape,
kappa_start=kappa_start,
kappa_end=kappa_end,
direction=direction,
)
else: # periodic
cur_boundary = PeriodicBoundary(
axis=axis,
partial_grid_shape=grid_shape,
direction=direction,
)
direction_int = -1 if direction == "-" else 1
pos_constraint = cur_boundary.place_relative_to(
volume,
axes=(axis, other_axes[0], other_axes[1]),
own_positions=(direction_int, 0, 0),
other_positions=(direction_int, 0, 0),
)
boundaries[kind] = cur_boundary
constraints.append(pos_constraint)
return boundaries, constraints