78 This will serve as a face marker to communicate with neighbouring cells whether
79 a given cell is troubled, is neighbouring a troubled cell, or is fine.
80 Cells that are troubled or neighbouring a troubled cell must rollback their solution
81 to the previous one and perform one timestep using a more robust FV scheme.
82 Therefore these and their neighbours must convert the DG representation of their
83 previous solution to an FV representation and project it to their faces so that these
84 can be exchanged with their neighbours.
86 Variants = [
"REGULAR",
"REGULAR_TO_LIMITER",
"LIMITER_TO_REGULAR",
"TROUBLED"]
89 self.
_cell_label.data.add_attribute(dastgen2.attributes.Enumeration( name=
"Troubled_Marker", variants=Variants, initval=
"Troubled_Marker::REGULAR" ) )
90 self.
_face_label.data.add_attribute(dastgen2.attributes.Enumeration( name=
"Troubled_Marker", variants=Variants, initval=
"Troubled_Marker::REGULAR" ) )
92 self.
_face_label.peano4_mpi_and_storage_aspect.merge_implementation +=
"\n _Troubled_Marker = std::max(_Troubled_Marker, neighbour.getTroubled_Marker());"
94 compute_time_step_size =
"""
114 guard = (
"not marker.willBeRefined() and not marker.hasBeenRefined() and" +
124 guard = (
"not marker.willBeRefined() and not marker.hasBeenRefined()"
131 checking troubledness needs to happen in the initialization after the regular solver
132 has computed its initial condition.
133 spreading limiter status happens once in its own dedicated step after initialization
134 but before either solvers are allowed to start computing, and once in the first
135 timestep before any other operations are performed
136 copying and converting the data from regular to limiter and from limiter to regular
137 happens before they are used in the first grid traversal, so either at the very
138 beginning of the first grid traversal or at the end of the second, so that
139 regular-to-limiter and limiter-to-regular cells both have access to either version
140 and can therefore project both variants of their faces
147 " and fineGridCell" + self.
_name +
"CellLabel.getTroubled_Marker()==celldata::" + self.
_name +
"CellLabel::Troubled_Marker::REGULAR"
151 " and fineGridCell" + self.
_name +
"CellLabel.getTroubled_Marker()==celldata::" + self.
_name +
"CellLabel::Troubled_Marker::REGULAR"
159 " and fineGridCell" + self.
_name +
"CellLabel.getTroubled_Marker()==celldata::" + self.
_name +
"CellLabel::Troubled_Marker::TROUBLED"
163 " and fineGridCell" + self.
_name +
"CellLabel.getTroubled_Marker()==celldata::" + self.
_name +
"CellLabel::Troubled_Marker::TROUBLED"
167 " and fineGridFace" + self.
_name +
"FaceLabel.getTroubled_Marker()>=facedata::" + self.
_name +
"FaceLabel::Troubled_Marker::LIMITER_TO_REGULAR"
221 def _load_cell_data_default_guard(self):
223 "not marker.hasBeenRefined() "
224 + "and repositories::"
225 + self.get_name_of_global_instance()
226 + ".getSolverState()!="
228 + "::SolverState::GridConstruction "
229 + "and repositories::"
230 + self.get_name_of_global_instance()
231 + ".getSolverState()!="
233 + "::SolverState::GridInitialisation"
246 def _load_face_data_default_guard(self):
248 "not marker.hasBeenRefined() "
249 + "and repositories::"
250 + self.get_name_of_global_instance()
251 + ".getSolverState()!="
253 + "::SolverState::GridConstruction "
254 + "and repositories::"
255 + self.get_name_of_global_instance()
256 + ".getSolverState()!="
258 + "::SolverState::GridInitialisation"
261 def _store_boundary_data_default_guard(self):
263 self._store_face_data_default_guard()
264 + " and not repositories::"
265 + self.get_name_of_global_instance()
266 + ".PeriodicBC[marker.getSelectedFaceNumber()%DIMENSIONS]"
267 + " and not marker.hasBeenRefined() and fineGridFace"
269 + "FaceLabel.getBoundary()"
348 def _generate_kernels(self, namespace, output, subdirectory, dimensions):
350 self._init_dictionary_with_default_parameters(d)
351 self.add_entries_to_text_replacement_dictionary(d)
352 # d["DIMENSIONS"] = dimensions
353 # d["NUMBER_OF_DOF_3D"] = 1 if dimensions == 2 else d["NUMBER_OF_DOF"]
354 # d["NUMBER_OF_DOF_LIMITER_3D"] = 1 if dimensions == 2 else d["NUMBER_OF_DOF_LIMITER"]
355 # d["GHOST_LAYER_WIDTH_3D"] = 0 if dimensions == 2 else d["GHOST_LAYER_WIDTH"]
356 # d["FULL_QUALIFIED_SOLVER_NAME"] ="::".join(namespace) + "::" + self._name
358 kernels_namespace = namespace + ["kernels", self._name]
359 kernels_output_path = subdirectory + "kernels/" + self._name
360 kernels_templates_prefix = os.path.dirname(os.path.realpath(__file__)) + "/kernels/"
362 if not os.path.exists(kernels_output_path):
363 os.makedirs(kernels_output_path)
365 kernels.Limiter(d).generate_kernels(
366 kernels_namespace, output, subdirectory,
367 kernels_templates_prefix, kernels_output_path,
368 regular_solver_quadpoints = self._regular_solver._basis.quadrature_points(render=False),
369 limiter_solver_quadpoints = self._limiter_solver._basis.quadrature_points(render=False)
377 def add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory=""):
379 The ExaHyPE2 project will call this operation when it sets
380 up the overall environment.
382 This routine is typically not invoked by a user.
384 output: peano4.output.Output
387 HeaderDictionary = {}
388 self._init_dictionary_with_default_parameters(HeaderDictionary)
390 generated_abstract_files = (
391 peano4.output.Jinja2TemplatedHeaderImplementationFilePair(
392 os.path.dirname(os.path.realpath(__file__)) + "/StaticCouplingAbstract.template.h",
393 os.path.dirname(os.path.realpath(__file__)) + "/StaticCouplingAbstract.template.cpp",
394 "Abstract" + self._name,
403 generated_solver_files = (
404 peano4.output.Jinja2TemplatedHeaderImplementationFilePair(
405 os.path.dirname(os.path.realpath(__file__)) + "/StaticCoupling.template.h",
406 os.path.dirname(os.path.realpath(__file__)) + "/StaticCoupling.template.cpp",
416 output.add(generated_abstract_files)
417 output.makefile.add_cpp_file(subdirectory + "Abstract" + self._name + ".cpp", generated=True)
418 output.makefile.add_h_file(subdirectory + "Abstract" + self._name + ".h", generated=True)
420 output.add(generated_solver_files)
421 output.makefile.add_cpp_file(subdirectory + self._name + ".cpp", generated=True)
422 output.makefile.add_h_file(subdirectory + self._name + ".h", generated=True)
424 self._generate_kernels(namespace, output, subdirectory, dimensions)
434 def _init_dictionary_with_default_parameters(self, d):
436 d["SOLVER_INSTANCE"] = self.get_name_of_global_instance()
437 d["REGULAR_SOLVER_INSTANCE"] = self._regular_solver.get_name_of_global_instance()
438 d["LIMITER_SOLVER_INSTANCE"] = self._limiter_solver.get_name_of_global_instance()
440 d["SOLVER_NAME"] = self._name
441 d["REGULAR_SOLVER_NAME"] = self._regular_solver._name
442 d["LIMITER_SOLVER_NAME"] = self._limiter_solver._name
444 d["UNKNOWN_IDENTIFIER"] = self._unknown_identifier()
445 d["REGULAR_SOLVER_UNKNOWN_IDENTIFIER"] = self._regular_solver._unknown_identifier()
446 d["LIMITER_SOLVER_UNKNOWN_IDENTIFIER"] = self._limiter_solver._unknown_identifier()
448 d["SOLVER_INCLUDES"] = self.get_user_solver_includes()
450 d["REGULAR_SOLVER_ORDER"] = self._regular_solver._order
451 d["LIMITER_SOLVER_ORDER"] = self._limiter_solver._order
453 d["REGULAR_SOLVER_STORAGE_PRECISION"] = self._regular_solver._solution_persistent_storage_precision
455 d["REGULAR_SOLVER_CORRECTION_PRECISION"] = self._regular_solver._corrector_computation_precision
456 d["LIMITER_SOLVER_CORRECTION_PRECISION"] = self._limiter_solver._corrector_computation_precision
458 d["NUMBER_OF_DOFS_PER_CELL_2D"] = (
459 (self._regular_solver.unknowns + self._regular_solver.auxiliary_variables)
460 * (self._regular_solver.order+1) * (self._regular_solver.order+1) )
461 d["NUMBER_OF_DOFS_PER_CELL_3D"] = (
462 (self._regular_solver.unknowns + self._regular_solver.auxiliary_variables)
463 * (self._regular_solver.order+1) * (self._regular_solver.order+1) * (self._regular_solver.order+1) )
465 d["SOLVER_USER_DECLARATIONS"] = jinja2.Template(
466 self._solver_user_declarations, undefined=jinja2.DebugUndefined
468 d["SOLVER_USER_DEFINITIONS"] = jinja2.Template(
469 self._solver_user_definitions, undefined=jinja2.DebugUndefined
472 d["START_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
473 self._start_time_step_implementation, undefined=jinja2.DebugUndefined
475 d["FINISH_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
476 self._finish_time_step_implementation, undefined=jinja2.DebugUndefined
478 d["PRINT_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
479 self._print_time_step_implementation, undefined=jinja2.DebugUndefined
482 d["CONSTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
483 self._constructor_implementation, undefined=jinja2.DebugUndefined
486 d["ADMISSIBILITY_IMPLEMENTATION"] = self._physical_admissibility_criterion