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()"
351 def _generate_kernels(self, namespace, output, subdirectory, dimensions):
353 self._init_dictionary_with_default_parameters(d)
354 self.add_entries_to_text_replacement_dictionary(d)
355 # d["DIMENSIONS"] = dimensions
356 # d["NUMBER_OF_DOF_3D"] = 1 if dimensions == 2 else d["NUMBER_OF_DOF"]
357 # d["NUMBER_OF_DOF_LIMITER_3D"] = 1 if dimensions == 2 else d["NUMBER_OF_DOF_LIMITER"]
358 # d["GHOST_LAYER_WIDTH_3D"] = 0 if dimensions == 2 else d["GHOST_LAYER_WIDTH"]
359 # d["FULL_QUALIFIED_SOLVER_NAME"] ="::".join(namespace) + "::" + self._name
361 kernels_namespace = namespace + ["kernels", self._name]
362 kernels_output_path = subdirectory + "kernels/" + self._name
363 kernels_templates_prefix = os.path.dirname(os.path.realpath(__file__)) + "/kernels/"
365 if not os.path.exists(kernels_output_path):
366 os.makedirs(kernels_output_path)
368 kernels.Limiter(d).generate_kernels(
369 kernels_namespace, output, subdirectory,
370 kernels_templates_prefix, kernels_output_path,
371 regular_solver_quadpoints = self._regular_solver._basis.quadrature_points(render=False),
372 limiter_solver_quadpoints = self._limiter_solver._basis.quadrature_points(render=False)
380 def add_implementation_files_to_project(self, namespace, output, dimensions, subdirectory=""):
382 The ExaHyPE2 project will call this operation when it sets
383 up the overall environment.
385 This routine is typically not invoked by a user.
387 output: peano4.output.Output
390 HeaderDictionary = {}
391 self._init_dictionary_with_default_parameters(HeaderDictionary)
393 generated_abstract_files = (
394 peano4.output.Jinja2TemplatedHeaderImplementationFilePair(
395 os.path.dirname(os.path.realpath(__file__)) + "/StaticCouplingAbstract.template.h",
396 os.path.dirname(os.path.realpath(__file__)) + "/StaticCouplingAbstract.template.cpp",
397 "Abstract" + self._name,
406 generated_solver_files = (
407 peano4.output.Jinja2TemplatedHeaderImplementationFilePair(
408 os.path.dirname(os.path.realpath(__file__)) + "/StaticCoupling.template.h",
409 os.path.dirname(os.path.realpath(__file__)) + "/StaticCoupling.template.cpp",
419 output.add(generated_abstract_files)
420 output.makefile.add_cpp_file(subdirectory + "Abstract" + self._name + ".cpp", generated=True)
421 output.makefile.add_h_file(subdirectory + "Abstract" + self._name + ".h", generated=True)
423 output.add(generated_solver_files)
424 output.makefile.add_cpp_file(subdirectory + self._name + ".cpp", generated=True)
425 output.makefile.add_h_file(subdirectory + self._name + ".h", generated=True)
427 self._generate_kernels(namespace, output, subdirectory, dimensions)
437 def _init_dictionary_with_default_parameters(self, d):
439 d["SOLVER_INSTANCE"] = self.get_name_of_global_instance()
440 d["REGULAR_SOLVER_INSTANCE"] = self._regular_solver.get_name_of_global_instance()
441 d["LIMITER_SOLVER_INSTANCE"] = self._limiter_solver.get_name_of_global_instance()
443 d["SOLVER_NAME"] = self._name
444 d["REGULAR_SOLVER_NAME"] = self._regular_solver._name
445 d["LIMITER_SOLVER_NAME"] = self._limiter_solver._name
447 d["UNKNOWN_IDENTIFIER"] = self._unknown_identifier()
448 d["REGULAR_SOLVER_UNKNOWN_IDENTIFIER"] = self._regular_solver._unknown_identifier()
449 d["LIMITER_SOLVER_UNKNOWN_IDENTIFIER"] = self._limiter_solver._unknown_identifier()
451 d["SOLVER_INCLUDES"] = self.get_user_solver_includes()
453 d["REGULAR_SOLVER_ORDER"] = self._regular_solver._order
454 d["LIMITER_SOLVER_ORDER"] = self._limiter_solver._order
456 d["REGULAR_SOLVER_STORAGE_PRECISION"] = self._regular_solver._solution_persistent_storage_precision
458 d["REGULAR_SOLVER_CORRECTION_PRECISION"] = self._regular_solver._corrector_computation_precision
459 d["LIMITER_SOLVER_CORRECTION_PRECISION"] = self._limiter_solver._corrector_computation_precision
461 d["NUMBER_OF_DOFS_PER_CELL_2D"] = (
462 (self._regular_solver.unknowns + self._regular_solver.auxiliary_variables)
463 * (self._regular_solver.order+1) * (self._regular_solver.order+1) )
464 d["NUMBER_OF_DOFS_PER_CELL_3D"] = (
465 (self._regular_solver.unknowns + self._regular_solver.auxiliary_variables)
466 * (self._regular_solver.order+1) * (self._regular_solver.order+1) * (self._regular_solver.order+1) )
468 d["SOLVER_USER_DECLARATIONS"] = jinja2.Template(
469 self._solver_user_declarations, undefined=jinja2.DebugUndefined
471 d["SOLVER_USER_DEFINITIONS"] = jinja2.Template(
472 self._solver_user_definitions, undefined=jinja2.DebugUndefined
475 d["START_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
476 self._start_time_step_implementation, undefined=jinja2.DebugUndefined
478 d["FINISH_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
479 self._finish_time_step_implementation, undefined=jinja2.DebugUndefined
481 d["PRINT_TIME_STEP_IMPLEMENTATION"] = jinja2.Template(
482 self._print_time_step_implementation, undefined=jinja2.DebugUndefined
485 d["CONSTRUCTOR_IMPLEMENTATION"] = jinja2.Template(
486 self._constructor_implementation, undefined=jinja2.DebugUndefined
489 d["ADMISSIBILITY_IMPLEMENTATION"] = self._physical_admissibility_criterion