diff --git a/src/DataStructures/Variables.hpp b/src/DataStructures/Variables.hpp index 17f355366ded..722126c2d096 100644 --- a/src/DataStructures/Variables.hpp +++ b/src/DataStructures/Variables.hpp @@ -594,6 +594,11 @@ class Variables> { template Variables(const T* /*pointer*/, const size_t /*size*/) {} static constexpr size_t size() { return 0; } + static constexpr size_t number_of_grid_points() { return 0; } + void assign_subset(const Variables>& /*unused*/) {} + void assign_subset(const tuples::TaggedTuple<>& /*unused*/) {} + // Initialization for empty variables should ignore any input. + void initialize(size_t /*number_of_grid_points*/) {} }; // gcc8 screams when the empty Variables has pup as a member function, so we diff --git a/src/Evolution/DgSubcell/Actions/Initialize.hpp b/src/Evolution/DgSubcell/Actions/Initialize.hpp index 01cf8fb10c53..81bfb48edb72 100644 --- a/src/Evolution/DgSubcell/Actions/Initialize.hpp +++ b/src/Evolution/DgSubcell/Actions/Initialize.hpp @@ -103,7 +103,8 @@ struct SetSubcellGrid { subcell::Tags::ReconstructionOrder, evolution::dg::subcell::Tags::InterpolatorsFromFdToNeighborFd, evolution::dg::subcell::Tags::InterpolatorsFromDgToNeighborFd, - evolution::dg::subcell::Tags::InterpolatorsFromNeighborDgToFd>; + evolution::dg::subcell::Tags::InterpolatorsFromNeighborDgToFd, + typename System::variables_tag>; using compute_tags = tmpl::list, Tags::LogicalCoordinatesCompute, ::domain::Tags::MappedCoordinates< diff --git a/src/Evolution/DgSubcell/BackgroundGrVars.hpp b/src/Evolution/DgSubcell/BackgroundGrVars.hpp index 3863c5e6a6c4..abae1b80d90a 100644 --- a/src/Evolution/DgSubcell/BackgroundGrVars.hpp +++ b/src/Evolution/DgSubcell/BackgroundGrVars.hpp @@ -142,10 +142,13 @@ struct BackgroundGrVars : tt::ConformsTo { cell_centered_impl(active_gr_vars, time, subcell_inertial_coords, solution_or_data); } - - face_centered_impl(subcell_face_gr_vars, time, functions_of_time, - logical_to_grid_map, grid_to_inertial_map, - subcell_mesh, solution_or_data); + if constexpr (not std::is_same_v< + typename SubcellFaceGrVars::value_type::tags_list, + tmpl::list<>>){ + face_centered_impl(subcell_face_gr_vars, time, functions_of_time, + logical_to_grid_map, grid_to_inertial_map, + subcell_mesh, solution_or_data); + } } } @@ -158,19 +161,23 @@ struct BackgroundGrVars : tt::ConformsTo { "The subcell mesh must have isotropic basis, quadrature. and " "extents but got " << subcell_mesh); - const size_t num_face_centered_mesh_grid_pts = - (subcell_mesh.extents(0) + 1) * subcell_mesh.extents(1) * - subcell_mesh.extents(2); - for (size_t d = 0; d < volume_dim; ++d) { - gsl::at(*subcell_face_gr_vars, d) - .initialize(num_face_centered_mesh_grid_pts); + if constexpr (not std::is_same_v< + typename SubcellFaceGrVars::value_type::tags_list, + tmpl::list<>>){ + const size_t num_face_centered_mesh_grid_pts = + (subcell_mesh.extents(0) + 1) * subcell_mesh.extents(1) * + subcell_mesh.extents(2); + for (size_t d = 0; d < volume_dim; ++d) { + gsl::at(*subcell_face_gr_vars, d) + .initialize(num_face_centered_mesh_grid_pts); + } + face_centered_impl(subcell_face_gr_vars, time, functions_of_time, + logical_to_grid_map, grid_to_inertial_map, + subcell_mesh, solution_or_data); } cell_centered_impl(inactive_gr_vars, time, subcell_inertial_coords, solution_or_data); - face_centered_impl(subcell_face_gr_vars, time, functions_of_time, - logical_to_grid_map, grid_to_inertial_map, - subcell_mesh, solution_or_data); } } diff --git a/src/ParallelAlgorithms/Events/ObserveTimeStep.hpp b/src/ParallelAlgorithms/Events/ObserveTimeStep.hpp index 9b727f56ca56..ee7797de4c2a 100644 --- a/src/ParallelAlgorithms/Events/ObserveTimeStep.hpp +++ b/src/ParallelAlgorithms/Events/ObserveTimeStep.hpp @@ -175,7 +175,13 @@ class ObserveTimeStep : public Event { const ArrayIndex& array_index, const ParallelComponent* const /*meta*/, const ObservationValue& observation_value) const { - const size_t number_of_grid_points = variables.number_of_grid_points(); + // For empty vars, we use 1 grid point to avoid divisions by zero + // after reduction. + size_t number_of_grid_points = 1; + if constexpr (not std::is_same_v>) { + number_of_grid_points = variables.number_of_grid_points(); + } const double slab_size = time_step.slab().duration().value(); const double step_size = abs(time_step.value()); const double wall_time = sys::wall_time(); diff --git a/tests/Unit/DataStructures/Test_Variables.cpp b/tests/Unit/DataStructures/Test_Variables.cpp index 397700c1bcd3..14a32cc3afb2 100644 --- a/tests/Unit/DataStructures/Test_Variables.cpp +++ b/tests/Unit/DataStructures/Test_Variables.cpp @@ -78,6 +78,12 @@ void test_empty_variables() { CHECK(get_output(tuple_with_empty_vars) == "(3,hello,{})"); CHECK(not contains_allocations(empty_vars)); + // Functions do nothing, but need to compile + empty_vars.initialize(0); + const Variables> input_vars; + empty_vars.assign_subset(input_vars); + CHECK(empty_vars.number_of_grid_points() == 0); + CHECK(empty_vars.size() == 0); } template