Peano
Loading...
Searching...
No Matches
test_mesh_adaptation.py
Go to the documentation of this file.
1import pytest
2
3import peano4.api
6
7import exahype2.api
9import toolbox.loadbalancing.api.actionsets
10
13Cells = toolbox.blockstructured.api.InterpolateAndRestrictCells
14
15
16def _solver(scheme):
17 solver = exahype2.api.Solver("Probe", 2, 0)
18 solver.add_pde_term(exahype2.api.Flux(implementation="F[0] = Q[0]; F[1] = Q[1];"))
19 solver.add_pde_term(exahype2.api.MaxEigenvalue(implementation="*lambdaMax = 1.0;"))
20 solver.add_pde_term(exahype2.api.InitPointWisely(implementation="Q[0] = 1.0;"))
21 if scheme == "fv":
22 solver.numerical_scheme = exahype2.api.fv.RusanovWithExplicitEuler(solver, 4)
23 solver.grid_construction = exahype2.api.fv.SetupSimulationOverRegularGrid(
24 solver, 0.1
25 )
26 elif scheme == "fv-optimistic":
28 solver, 4
29 )
30 solver.grid_construction = exahype2.api.fv.SetupSimulationOverRegularGrid(
31 solver, 0.1
32 )
33 else:
35 solver, patch_size=4, rk_order=2
36 )
38 solver, 0.1
39 )
40 return solver
41
42
43def _mesh_adaptation_graph(solver, tmp_path):
44 exahype2_project = exahype2.api.Project(
45 ["probe"], "probe", "probe", directory=str(tmp_path)
46 )
47 exahype2_project.set_global_simulation_parameters(
48 dimensions=2,
49 offset=[0.0, 0.0],
50 size=[1.0, 1.0],
51 min_end_time=1.0,
52 periodic_BC=[True, True, True],
53 )
54 peano_project = peano4.api.Project(["probe"], "probe", str(tmp_path))
55 graphs = [peano4.api.taskgraph.Graph() for _ in range(4)]
56 solver.generate_solver_realisation(exahype2_project, peano_project, *graphs)
57 return graphs[3]
58
59
60@pytest.mark.parametrize("scheme", ["fv", "fv-optimistic"])
62 solver = _solver(scheme)
63 graph = _mesh_adaptation_graph(solver, tmp_path)
64 assert isinstance(solver.mesh_adaptation, exahype2.api.fv.AdaptMeshAndBalanceLoad)
65 adapt, project = graph.ordered_tasks()
66 assert adapt.name == "Probe_Adapt mesh and balance load"
67 assert adapt.has_to_repeat is not None
68 assert project.name == "Probe_Project on faces"
69 assert project.dependencies == [adapt]
70 kinds = [type(action_set) for action_set in adapt.action_sets]
72 assert Cells in kinds
73 assert toolbox.loadbalancing.api.actionsets.LoadBalancing in kinds
75 assert discards == (scheme == "fv-optimistic")
76
77
79 solver = _solver("rkfd4")
80 graph = _mesh_adaptation_graph(solver, tmp_path)
81 assert isinstance(
82 solver.mesh_adaptation, exahype2.api.rkfd4.AdaptMeshAndBalanceLoad
83 )
84 adapt, project = graph.ordered_tasks()
85 kinds = [type(action_set) for action_set in adapt.action_sets]
86 assert Cells in kinds
88 projection_kinds = [type(action_set) for action_set in project.action_sets]
90 assert toolbox.blockstructured.api.RestrictHangingFaces in projection_kinds
91
92
93def _time_step_tasks(solver, tmp_path):
94 exahype2_project = exahype2.api.Project(
95 ["probe"], "probe", "probe", directory=str(tmp_path)
96 )
97 exahype2_project.set_global_simulation_parameters(
98 dimensions=2,
99 offset=[0.0, 0.0],
100 size=[1.0, 1.0],
101 min_end_time=1.0,
102 periodic_BC=[True, True, True],
103 )
104 peano_project = peano4.api.Project(["probe"], "probe", str(tmp_path))
105 graphs = [peano4.api.taskgraph.Graph() for _ in range(4)]
106 solver.generate_solver_realisation(exahype2_project, peano_project, *graphs)
107 return {task.name: task for task in graphs[1].tasks}
108
109
111 solver = _solver("rkfd4")
112 tasks = _time_step_tasks(solver, tmp_path)
113 for stage in range(2):
114 reconstruction = tasks[f"Probe_Reconstruct stage {stage}"]
115 assert any(
116 isinstance(a, toolbox.blockstructured.api.InterpolateHangingFaces)
117 for a in reconstruction.action_sets
118 )
119 for name in [
120 "Probe_Project stage 1 onto faces",
121 "Probe_Project solution onto faces",
122 ]:
123 kinds = [type(a) for a in tasks[name].action_sets]
124 restriction = kinds.index(toolbox.blockstructured.api.RestrictHangingFaces)
125 assert (
127 < restriction
128 )
129 # The roll over has to copy the restricted data
130 assert restriction < len(kinds) - 1
131
132
134 solver = _solver("fv")
135 solver.mesh_adaptation = exahype2.api.fv.AdaptMeshAndBalanceLoad(
136 solver, interpolation=Cells.Interpolation.PiecewiseConstant
137 )
138 mine = solver.mesh_adaptation
139 graph = _mesh_adaptation_graph(solver, tmp_path)
140 assert solver.mesh_adaptation is mine
141 adapt = graph.ordered_tasks()[0]
142 [cells] = [a for a in adapt.action_sets if isinstance(a, Cells)]
143 assert "interpolateCell_AoS_piecewise_constant" in cells.get_body_of_operation(
144 ActionSet.OPERATION_CREATE_CELL
145 )
146
147
149 patch = peano4.api.datamodel.Patch((3, 3, 3), 5, "Q")
150 cells = Cells(patch)
151 created = cells.get_body_of_operation(ActionSet.OPERATION_CREATE_CELL)
152 assert "interpolateCell_AoS_linear_with_constant_extrapolation" in created
153 assert "coarseGridCellQ.value,\n fineGridCellQ.value" in created
154 touched = cells.get_body_of_operation(ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME)
155 assert "marker.hasBeenRefined() and not marker.willBeRefined()" in touched
156 assert "clearCell" in touched
157 destroyed = cells.get_body_of_operation(ActionSet.OPERATION_DESTROY_CELL)
158 assert "restrictCell_AoS_averaging" in destroyed
159 assert "fineGridCellQ.value,\n coarseGridCellQ.value" in destroyed
160
161
163 solver = _solver("fv")
165 assert (
166 "RefinementControlService"
167 in consume.get_body_of_createGridControlEventsForNextTraversal()
168 )
169 unprepare = consume.get_body_of_unprepareTraversal()
170 assert "RefinementControlService::getInstance().finishStep()" in unprepare
171 assert "resetTimeStepSize()" in unprepare
172 for operation in [
173 ActionSet.OPERATION_CREATE_CELL,
174 ActionSet.OPERATION_DESTROY_CELL,
175 ]:
176 assert "_meshHasChanged = true" in consume.get_body_of_operation(operation)
The conservative flux F(Q) of a hyperbolic PDE.
Definition Flux.py:8
Point-wise initial condition: given the physical position of a single degree of freedom,...
The maximum absolute eigenvalue of the flux Jacobian in a given direction, i.e.
ExaHyPE 2 project.
Definition Project.py:15
Abstract base class for all ExaHyPE 2 solvers.
Definition Solver.py:17
Hand the refine and erase requests of the last time step over to Peano, and restart the time stepping...
Default mesh adaptation of the Finite Volume schemes.
Finite Volumes with a Rusanov Riemann solver and explicit Euler time stepping, realised over a block-...
Finite Volumes with a Rusanov Riemann solver and optimistic explicit Euler time stepping,...
Setup phase counterpart to RusanovWithExplicitEuler: sets the initial condition for a Finite Volume s...
Default mesh adaptation of the fourth-order finite differences.
Fourth-order central Finite Differences with explicit Runge-Kutta time stepping, realised over a bloc...
Setup phase of the fourth-order Finite Differences with Runge-Kutta time stepping (exahype2....
Project a patch's data onto the overlap held on its surrounding faces, so the halo layers can be reco...
Represents a Peano 4 project.
Definition Project.py:23
Patch implementation of a degree of freedom.
Definition Patch.py:7
Action set (reactions to events)
Definition ActionSet.py:6
Holds a sequence of Task instances.
Definition Graph.py:9
One task within a peano4.api.taskgraph.Graph.
Definition Task.py:8
The Python-side model of "what happens during one mesh sweep".
Definition __init__.py:1
The task graph abstraction allows users to formalise their solver steps over small task graphs which ...
Definition __init__.py:1
test_finite_differences_handle_hanging_faces_in_every_stage(tmp_path)
test_user_defined_mesh_adaptation_is_kept(tmp_path)
test_finite_differences_adapt_mesh_and_balance_load_by_default(tmp_path)
test_consumption_hands_over_requests_and_resets_time_step_size()
_mesh_adaptation_graph(solver, tmp_path)
test_finite_volumes_adapt_mesh_and_balance_load_by_default(scheme, tmp_path)
_time_step_tasks(solver, tmp_path)