Boundary conditions and face selection¶
Morana assigns boundary physics to exposed hex-z faces by combining an
immutable BoundaryCondition
with a topology-based selector. This guide explains how to select faces,
compose a BoundaryConditionSet,
and check that a material layout has complete coverage. The
theory guide derives the
finite-volume equations; the Python reference defines
exact signatures and accepted argument types.
Boundary model¶
Internal active-to-active faces use conservative two-cell diffusion coupling and never receive a boundary assignment. Every other face of an active cell is exposed: it lies on the physical radial, bottom, or top exterior, or it borders an excluded material-mesh position. Every exposed face must resolve to a condition before loss or boundary-source assembly.
Selectors describe topology only; they do not imply boundary physics. The same selector can therefore be paired with any compatible condition. Conversely, one condition can be assigned independently to several selectors.
Select exposed faces¶
Use the fluent methods on a boundary condition for ordinary configurations:
| Fluent method | Selected exposed faces | Does not select |
|---|---|---|
globally() |
Every physical exterior and excluded interface | Internal active-to-active faces |
on_outer() |
Every physical exterior face, radial and axial | Excluded interfaces |
on_radial() |
Physical lateral exterior faces | Bottom, top, and excluded interfaces |
on_bottom() / on_top() |
Physical exterior faces at that axial end | In-stack excluded interfaces in that direction |
on_excluded(...) |
Interfaces adjoining excluded positions, optionally filtered | Physical exterior faces |
The fluent methods construct assignments containing a
BoundarySelector. Direct
selector construction is available when an assignment must be built
explicitly. Its scope uses the closed vocabulary global, outer,
radial, to_excluded, bottom, and top. Only to_excluded accepts
direction, excluded_key, or excluded_kind filters.
An excluded region has no active-cell unknown or material data.
on_excluded(...) selects the face of the adjacent active cell, not the
excluded position itself. Its optional filters are combined:
keyselects one exact excluded-region identity;kindselects every identity represented by thatExcludedRegionkind; anddirectionselects one radial ("x+","x-","u+","u-","v+", or"v-") or axial ("bottom"or"top") face direction.
Specify key or kind, but not both. Omit every filter to select all excluded
interfaces; omit an individual filter to accept any value for it. For example:
from morana import BoundaryCondition
BoundaryCondition.dirichlet([1.0]).on_excluded(
key="beam_port", direction="u+"
)
BoundaryCondition.reflective().on_excluded(kind="reflector")
Define face physics¶
Use the named BoundaryCondition constructors rather than direct
construction. Spectrum arguments are nonempty, finite, nonnegative
one-dimensional vectors in fast-to-thermal order. Morana copies them into
read-only arrays and checks their group count during assembly.
| Constructor | Face condition | Input and limits |
|---|---|---|
reflective() |
\(J_{\mathrm{out}}=0\) | Homogeneous; equivalent to a return ratio of 1. |
vacuum() |
\(J_{\mathrm{out}}=\phi_b/2\) | Homogeneous Marshak vacuum; equivalent to robin(0.5). |
zero_dirichlet() |
\(\phi_b=0\) | Homogeneous zero physical face flux; distinct from Marshak vacuum. |
dirichlet(flux) |
Prescribed \(\phi_b\) | flux is in n / cm^2 / s; nonzero values are a boundary source. |
robin(alpha) |
\(J_{\mathrm{out}}=\alpha\phi_b\) | Finite, nonnegative scalar \(\alpha\); 0 is reflective and 0.5 is Marshak vacuum. |
partial_current_return(beta, current=None) |
\(j^-=\beta j^+ + q_{\mathrm{in}}\) | \(0\leq\beta\leq1\); optional current is a group vector in n / cm^2 / s. |
incoming_current(current) |
\(J_{\mathrm{out}}=\phi_b/2-2q_{\mathrm{in}}\) | current is a group vector in n / cm^2 / s. |
Here \(\phi_b\) is the physical face flux, \(J_{\mathrm{out}}\) is net outward
current, and \(j^+\) and \(j^-\) are outgoing and incoming partial currents.
For partial_current_return, \(\beta=1\) is reflective only when the imposed
current is absent or zero; otherwise it prescribes a net inward current.
Prescribed fluxes and currents are group-resolved. Robin response and partial-current-return coefficients are scalar and energy independent; group-coupled boundary response is not implemented.
solve_keff() accepts only homogeneous resolved boundary data. Reflective,
vacuum, zero-Dirichlet, and Robin conditions qualify directly, as do a zero
Dirichlet spectrum and an absent or zero imposed-current spectrum. Nonzero
prescribed flux or current contributes to a fixed-source right-hand side and
requires solve_fixed_source().
Compose and resolve assignments¶
Construct a boundary set from fluent assignments. A broad fallback followed by more specific rules is easy to read, although construction order does not control resolution:
from morana import BoundaryCondition, BoundaryConditionSet
boundaries = BoundaryConditionSet(
BoundaryCondition.reflective().globally(),
BoundaryCondition.vacuum().on_radial(),
BoundaryCondition.reflective().on_bottom(),
BoundaryCondition.reflective().on_top(),
)
An exact duplicate selector is rejected; overlapping distinct selectors are
intentional refinements. with_assignment(...) returns a new set. When
editing a ProblemConfiguration, use add_boundary(...) to install that new
set on the configuration.
Resolution uses selector specificity, not tuple order. For an excluded interface, precedence is:
- key and direction;
- key only;
- kind and direction;
- kind only;
- direction only;
- unfiltered excluded interface; and
- global fallback.
For a physical exterior face, a radial or matching axial rule takes
precedence over outer, which takes precedence over global.
Call ProblemConfiguration.check_boundary_coverage() to validate the current
material layout; an uncovered face is reported with its topology. Loss
assembly and both solve functions require complete coverage.
BoundaryConditionSet.resolve(face) is useful when inspecting one exposed
DomainFace; it rejects internal and
uncovered faces.
Scope and related guidance¶
The selector hierarchy supports whole-domain fallbacks, physical exteriors, and excluded interfaces filtered by identity, kind, and direction. It does not provide arbitrary per-cell-face maps or separate physical radial rules by direction. Distinct excluded keys and directional filters provide local rules where the supported topology permits them.
See geometry and indexing for face
classification, theory and numerical conventions
for boundary reductions and limiting cases, and the
mixed_boundary_regions.py example for
a solved problem using several selector and condition types.