Peano
Loading...
Searching...
No Matches
test_dynamic_mesh_refinement.py
Go to the documentation of this file.
1import types
2
3import pytest
4
5import peano4.api
8
9import exahype2.api
10import toolbox.loadbalancing.api.actionsets
11
14
15SCHEMES = {
16 "fv": lambda solver, **bounds: exahype2.api.fv.RusanovWithExplicitEuler(
17 solver, 4, **bounds
18 ),
19 "fv-optimistic": lambda solver, **bounds: exahype2.api.fv.RusanovWithOptimisticExplicitEuler(
20 solver, 4, **bounds
21 ),
22 "rkfd4": lambda solver, **bounds: exahype2.api.rkfd4.CentralDifferencesWithRungeKutta(
23 solver, patch_size=4, rk_order=2, **bounds
24 ),
25}
26
27
28def _solver(scheme, criterion=True, **bounds):
29 solver = exahype2.api.Solver("Probe", 2, 0)
30 solver.add_pde_term(exahype2.api.Flux(implementation="F[0] = Q[0]; F[1] = Q[1];"))
31 solver.add_pde_term(exahype2.api.MaxEigenvalue(implementation="*lambdaMax = 1.0;"))
32 if criterion:
33 solver.add_pde_term(exahype2.api.RefineErasePointwisely(implementation=""))
34 solver.numerical_scheme = SCHEMES[scheme](solver, **bounds)
35 return solver
36
37
38def _last_task(solver, tmp_path):
39 """! The one task of the time step on which no other task depends"""
40 exahype2_project = types.SimpleNamespace(periodic_BC=[True, True, True])
41 peano_project = peano4.api.Project(["probe"], "probe", str(tmp_path))
42 time_step = peano4.api.taskgraph.Graph()
43 solver.numerical_scheme.construct_output(exahype2_project, peano_project, time_step)
44 dependencies = {
45 id(dependency) for task in time_step.tasks for dependency in task.dependencies
46 }
47 [last] = [task for task in time_step.tasks if id(task) not in dependencies]
48 return last
49
50
51def _criterion_body(action_set):
52 return action_set.get_body_of_operation(ActionSet.OPERATION_TOUCH_CELL_FIRST_TIME)
53
54
55@pytest.mark.parametrize("scheme", SCHEMES)
57 last = _last_task(_solver(scheme), tmp_path)
58 assert last.name == "Probe_Dynamic mesh refinement"
59 assert last.entity == Task.GridEntity.CELL
60 dynamic_mesh_refinement, load_balancing = last.action_sets
61 assert isinstance(
63 )
64 assert isinstance(
65 load_balancing, toolbox.loadbalancing.api.actionsets.LoadBalancing
66 )
67 body = load_balancing.get_body_of_unprepareTraversal()
68 assert body.index("enable(true)") < body.index("finishStep()")
69
70
71@pytest.mark.parametrize("scheme", SCHEMES)
73 [dynamic_mesh_refinement, _] = _last_task(_solver(scheme), tmp_path).action_sets
74 assert "RefinementControlService" not in (
75 dynamic_mesh_refinement.get_body_of_createGridControlEventsForNextTraversal()
76 )
77 assert "refineErasePointwisely" in _criterion_body(dynamic_mesh_refinement)
78 assert "RefinementControlService::getInstance().finishStep()" in (
79 dynamic_mesh_refinement.get_body_of_unprepareTraversal()
80 )
81
82
83@pytest.mark.parametrize("scheme", SCHEMES)
85 last = _last_task(_solver(scheme, criterion=False), tmp_path)
86 assert last.name == "Probe_Dynamic mesh refinement"
87 [load_balancing] = last.action_sets
88 assert isinstance(
89 load_balancing, toolbox.loadbalancing.api.actionsets.LoadBalancing
90 )
91
92
93@pytest.mark.parametrize("scheme", SCHEMES)
95 solver = _solver(scheme, criterion=False)
96 solver.add_pde_term(exahype2.api.GradientRefinement(implementation=""))
97 [dynamic_mesh_refinement, _] = _last_task(solver, tmp_path).action_sets
98 assert isinstance(
99 dynamic_mesh_refinement,
101 )
102 body = _criterion_body(dynamic_mesh_refinement)
103 assert "refineErasePointwisely" not in body
104 assert "for (int normal=0; normal<Dimensions; normal++)" in body
105 assert "for (int side=0; side<2; side++)" in body
106 assert "::exahype2::fv::computeOneSidedGradient(" in body
107 assert "refineEraseWithGradient(" in body
108 assert "double gradient[2 + 0];" in body
109 assert "anyVolumeWantsToRefine or command" in body
110 assert "allVolumesWantToErase and command" in body
111 assert "finishStep()" in dynamic_mesh_refinement.get_body_of_unprepareTraversal()
112
113
114@pytest.mark.parametrize("scheme", SCHEMES)
116 [dynamic_mesh_refinement, _] = _last_task(_solver(scheme), tmp_path).action_sets
117 assert "RefinementCommand::Erase," in _criterion_body(dynamic_mesh_refinement)
118
119
121 solver = _solver("fv")
122 solver.add_pde_term(exahype2.api.GradientRefinement(implementation=""))
123 with pytest.raises(ValueError):
124 _last_task(solver, tmp_path)
125
126
128 [dynamic_mesh_refinement, _] = _last_task(_solver("fv"), tmp_path).action_sets
129 body = _criterion_body(dynamic_mesh_refinement)
130 assert "tarch::la::max( marker.h() ) >=" not in body
131 assert "3.0 * tarch::la::max( marker.h() ) <" not in body
132
133
134@pytest.mark.parametrize("scheme", SCHEMES)
136 solver = _solver(scheme, min_volume_size=0.25, max_volume_size=1.0)
137 [dynamic_mesh_refinement, _] = _last_task(solver, tmp_path).action_sets
138 body = _criterion_body(dynamic_mesh_refinement)
139 # Volume sizes times patch size 4
140 assert "tarch::la::max( marker.h() ) >= 1.0" in body
141 assert "3.0 * tarch::la::max( marker.h() ) < 4.0" in body
142
143
144@pytest.mark.parametrize("scheme", SCHEMES)
146 with pytest.raises(AssertionError):
147 _solver(scheme, min_volume_size=1.0, max_volume_size=0.5)
The conservative flux F(Q) of a hyperbolic PDE.
Definition Flux.py:8
Gradient-based refinement criterion: given a one-sided difference quotient of the solution along one ...
The maximum absolute eigenvalue of the flux Jacobian in a given direction, i.e.
Point-wise refinement criterion: given the solution Q at a single degree of freedom,...
Abstract base class for all ExaHyPE 2 solvers.
Definition Solver.py:17
Evaluate the gradient-based refinement criterion and collect the outcome as refine and erase requests...
Evaluate the point-wise refinement criterion and collect the outcome as refine and erase requests.
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,...
Fourth-order central Finite Differences with explicit Runge-Kutta time stepping, realised over a bloc...
Represents a Peano 4 project.
Definition Project.py:23
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_gradient_criterion_yields_gradient_action_set(scheme, tmp_path)
_last_task(solver, tmp_path)
The one task of the time step on which no other task depends.
test_last_task_evaluates_criterion_and_switches_on_load_balancing(scheme, tmp_path)
_solver(scheme, criterion=True, **bounds)
test_time_step_never_hands_events_to_peano(scheme, tmp_path)