315def register_auxiliary_variables(solver, peano_project, patch_size: int, overlap: int):
318 Create and register the data of all auxiliary variables of a solver
320 The persistent data of a set (its patch and the face overlaps) exists only
321 once, even if several solvers share it. Each solver gets its own
322 temporary patch with halo per set (solver._auxiliary_variable_halos, a
323 dict from the name of the set to the patch), so concurrently running
324 solvers do not overwrite each other's halos.
327 solver._auxiliary_variable_halos = {}
328 for auxiliary
in solver.auxiliary_variables:
329 auxiliary.create_data_structures(patch_size, overlap, solver.grid_selector)
330 auxiliary.add_to_datamodel(peano_project)
332 (patch_size + 2 * overlap, patch_size + 2 * overlap, patch_size + 2 * overlap),
334 auxiliary.name +
"AuxiliaryVariablesWithHaloOf" + solver.name,
336 halo.grid_selector = solver.grid_selector
338 peano_project.datamodel.add_cell(halo)
339 solver._auxiliary_variable_halos[auxiliary.name] = halo
342def add_reconstruction_of_auxiliary_variables(task, solver):
345 Make a reconstruction task of a solver fill the halos of the solver's
348 @param task: peano4.api.taskgraph.Task
349 The task which also reconstructs the unknowns.
352 Access = peano4.api.taskgraph.Task.DataAccess
353 for auxiliary
in solver.auxiliary_variables:
354 halo = solver._auxiliary_variable_halos[auxiliary.name]
355 task.use_cell(auxiliary.patch, Access.READ_AND_WRITE)
356 task.use_cell(halo, Access.WRITE)
357 task.use_face(auxiliary.patch_overlap_current_time_step, Access.READ_AND_WRITE)
359 toolbox.blockstructured.api.ReconstructPatchWithHalo(
360 patch=auxiliary.patch,
361 patch_overlap=auxiliary.patch_overlap_current_time_step,
362 reconstructed_patch=halo,
363 guard=solver.grid_selector.createCellGuard(),
364 add_assertions_to_halo_exchange=
False,
365 additional_includes=solver._get_default_includes() + solver.user_solver_includes,
370def use_halos_of_auxiliary_variables(task, solver):
371 """! Let a task (typically the update of the cells) read the halos of the auxiliary variables """
372 for auxiliary
in solver.auxiliary_variables:
374 solver._auxiliary_variable_halos[auxiliary.name],
375 peano4.api.taskgraph.Task.DataAccess.READ_AND_DISCARD,
385def code_to_assemble_kernel_input(solver, buffer: str, unknowns: str, halo_size: int, parameters_of=
None) -> str:
388 C++ code which assembles the input buffer of the compute kernels
390 The kernels work on one buffer that holds the unknowns of a volume
391 followed by the entries of all sets of auxiliary variables. The code
392 defines a std::vector<double> named buffer. It is empty if the solver has
393 no auxiliary variables.
396 C++ expression for the unknowns of the patch with halo.
398 @param parameters_of: function
399 Maps a set onto the C++ expression of its patch with halo. Defaults to
400 the halo patches of the solver.
403 if not solver.auxiliary_variables:
405 if parameters_of
is None:
406 parameters_of =
lambda auxiliary: f
"fineGridCell{solver._auxiliary_variable_halos[auxiliary.name].name}.value"
408 stride = solver.unknowns + solver.number_of_auxiliary_variables
411 for (int k=0; k<{auxiliary.size}; k++) {{
412 {buffer}[volume*{stride} + {solver.auxiliary_variable_offset(auxiliary)} + k] = {parameters_of(auxiliary)}[volume*{auxiliary.size} + k];
414 for auxiliary
in solver.auxiliary_variables
417 const int {buffer}Volumes = {volumes};
418 std::vector<double> {buffer}( {buffer}Volumes * {stride}, 0.0 );
419 for (int volume=0; volume<{buffer}Volumes; volume++) {{
420 for (int k=0; k<{solver.unknowns}; k++) {{
421 {buffer}[volume*{stride} + k] = {unknowns}[volume*{solver.unknowns} + k];
427def code_to_allocate_kernel_output(solver, buffer: str) -> str:
428 """! C++ code which defines the output buffer (a std::vector<double>) of the compute kernels """
429 if not solver.auxiliary_variables:
432 stride = solver.unknowns + solver.number_of_auxiliary_variables
434 const int {buffer}Volumes = {volumes};
435 std::vector<double> {buffer}( {buffer}Volumes * {stride}, 0.0 );
453def add_auxiliary_variables_to_setup(
454 solver, initial_condition_task, project_on_faces_task, project_patch_onto_faces, roll_over_updated_face
458 Let the setup of a solver write its auxiliary variables
460 Auxiliary variables are written once, by their owner: the owner
461 initialises them in its initial condition task and projects them onto the
462 faces, so the halos can be reconstructed later on. A solver that merely
463 shares a set reads it after the owner has written it.
465 @param project_patch_onto_faces: class
466 The action set that projects a patch onto the faces
467 (exahype2.api.fv.actionsets.ProjectPatchOntoFaces).
469 @param roll_over_updated_face: class
470 The action set that rolls the projection over
471 (exahype2.api.fv.actionsets.RollOverUpdatedFace).
474 Access = peano4.api.taskgraph.Task.DataAccess
475 includes = solver._get_default_includes() + solver.user_solver_includes
476 for auxiliary
in solver.auxiliary_variables:
478 auxiliary.create_data_structures(
479 solver.numerical_scheme.patch_size,
480 solver.numerical_scheme.halo_size,
481 solver.grid_selector,
483 if auxiliary.owner
is solver:
484 initial_condition_task.use_cell(auxiliary.patch, Access.WRITE)
485 project_on_faces_task.use_cell(auxiliary.patch, Access.READ_AND_WRITE)
486 project_on_faces_task.use_face(auxiliary.patch_overlap_update, Access.TEMPORARY)
487 project_on_faces_task.use_face(auxiliary.patch_overlap_current_time_step, Access.WRITE)
488 project_on_faces_task.add_action_set(
489 project_patch_onto_faces(
491 auxiliary.patch_overlap_update,
492 guard=solver.grid_selector.createCellGuard(),
496 project_on_faces_task.add_action_set(
497 roll_over_updated_face(
498 auxiliary.patch_overlap_current_time_step,
499 auxiliary.patch_overlap_update,
500 guard=solver.grid_selector.createFaceGuard(),
504 auxiliary._setup_initial_condition_task = initial_condition_task
506 owners_task = getattr(auxiliary,
"_setup_initial_condition_task",
None)
507 if owners_task
is None:
509 f
"Solver {solver.name} shares the auxiliary variables {auxiliary.name} with "
510 f
"{auxiliary.owner.name}, but the setup of {auxiliary.owner.name} has not been created yet. "
511 f
"Add {auxiliary.owner.name} to the project before {solver.name}."
513 initial_condition_task.add_dependency(owners_task)
514 initial_condition_task.use_cell(auxiliary.patch, Access.READ_AND_DISCARD)
515 project_on_faces_task.use_cell(auxiliary.patch, Access.READ_AND_WRITE)