salvus.mesh.layered_meshing.meshing_protocol.coarsening_policy.interlayer_detail
salvus.mesh.layered_meshing.meshing_protocol.coarsening_policy.interlayer_detail salvus mesh layered_meshing meshing_protocol coarsening_policy interlayer_detail Solvers for the interlayer coarsening problem.
Adjacent layers must have element counts that differ by an exact power of their shared coarsening factor, so that a connector block can join them. The task is to choose, for every layer, the number of elements along each horizontal dimension that minimizes the total number of elements while respecting those relations, the requested (minimum) counts, and any modulo constraints.
Two exact solvers are provided:
solve_via_shortest_pathtreats the problem as a shortest path over(layer, element count)states. It applies whenever a single element count per layer describes the solution — either because there is one horizontal dimension, or because all horizontal dimensions request the same counts, as happens for full spherical shells. It is linear in the number of layers.solve_via_enumerationsearches over the relative shapes of the solution. It handles the general case in which the horizontal dimensions request different counts.
Both are dispatched from solve_interlayer_coarsening, and both minimize the
total number of elements first and the number of coarsenings second, so that a
mesh is never coarsened more often than it needs to be. Which solver runs
follows from the requested element counts alone, so a given model always takes
the same one.
Functions
solve_interlayer_coarsening()
solve_interlayer_coarsening()def solve_interlayer_coarsening(
nh: list[tuple[int, ...]],
boundaries: list[Boundary],
layer_modulo_constraint: int = 1,
bottom_layer_modulo_constraint: int = 1,
) -> list[list[int]]: ...Compute the number of horizontal elements across successive layers.
nhlist[tuple[int, ...]] — The requested number of elements in each dimension, per layer.boundarieslist[Boundary] — The coarsening factor and maximum coarsening per boundary. Must have one entry fewer thannh.layer_modulo_constraintint — Ensure that all layers include elements along each dimension that are multiples of this number.bottom_layer_modulo_constraintint — Ensure that the bottom layer (i.e. the last entry innh) is a multiple of this number.
solve_via_enumeration()
solve_via_enumeration()def solve_via_enumeration(
nh: list[tuple[int, ...]], boundaries: list[Boundary], moduli: list[int]
) -> list[list[int]]: ...Solve the coarsening problem for arbitrary requested element counts.
Searches over the relative shapes the boundaries admit, computing the cheapest element counts for each in closed form. A shape is abandoned as soon as no scaling of it can satisfy every layer’s bounds, which for more than one horizontal dimension has to hold in all of them at once and hence prunes the search sharply.
Where several solutions use equally many elements, the one coarsening the fewest times is chosen, and among those the one coarsening the least in the upper layers. This is a property of the result rather than of the order the search happens to take, so it does not change if the traversal does.
nhlist[tuple[int, ...]] — The requested number of elements in each dimension, per layer.boundarieslist[Boundary] — The coarsening factor and maximum coarsening per boundary.modulilist[int] — The number each layer’s element counts must be a multiple of.
solve_via_shortest_path()
solve_via_shortest_path()def solve_via_shortest_path(
nh: list[tuple[int, ...]], boundaries: list[Boundary], moduli: list[int]
) -> list[list[int]]: ...Solve the coarsening problem when all horizontal dimensions agree.
A single element count then describes each layer, the constraints couple only adjacent layers, and the total number of elements is a sum over layers. The problem is thus a shortest path through the layers, which is solved here in a single sweep per boundary.
Where several solutions use equally many elements, the one coarsening the
fewest times is chosen. Should several of those coarsen equally often, the
winner is fixed but arbitrary, and need not be the one
solve_via_enumeration settles on: both stay optimal and coarsen equally
often, but may place the coarsenings at different boundaries.
nhlist[tuple[int, ...]] — The requested number of elements in each dimension, per layer. All dimensions of a layer must request the same count.boundarieslist[Boundary] — The coarsening factor and maximum coarsening per boundary.modulilist[int] — The number each layer’s element counts must be a multiple of.