From: Wolfgang Bangerth Date: Thu, 27 Feb 2025 22:00:51 +0000 (-0700) Subject: Where possible, replace '#ifdef DEBUG' by 'if constexpr(...debug mode...'). X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e1ce5ae25b2b54c82f3aae2c6555bccd4c6c6e4;p=dealii.git Where possible, replace '#ifdef DEBUG' by 'if constexpr(...debug mode...'). --- diff --git a/include/deal.II/base/aligned_vector.h b/include/deal.II/base/aligned_vector.h index 8b34da278e..09be5577c0 100644 --- a/include/deal.II/base/aligned_vector.h +++ b/include/deal.II/base/aligned_vector.h @@ -1499,10 +1499,11 @@ template inline void AlignedVector::shrink_to_fit() { -# ifdef DEBUG - Assert(replicated_across_communicator == false, - ExcAlignedVectorChangeAfterReplication()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(replicated_across_communicator == false, + ExcAlignedVectorChangeAfterReplication()); + } const size_type used_size = used_elements_end - elements.get(); const size_type allocated_size = allocated_elements_end - elements.get(); if (allocated_size > used_size) @@ -2015,13 +2016,15 @@ AlignedVector::replicate_across_communicator(const MPI_Comm communicator, // **** Consistency check **** // At this point, each process should have a copy of the data. // Verify this in some sort of round-about way -# ifdef DEBUG - replicated_across_communicator = true; - const std::vector packed_data = Utilities::pack(*this); - const int hash = - std::accumulate(packed_data.begin(), packed_data.end(), int(0)); - Assert(Utilities::MPI::max(hash, communicator) == hash, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + replicated_across_communicator = true; + const std::vector packed_data = Utilities::pack(*this); + const int hash = + std::accumulate(packed_data.begin(), packed_data.end(), int(0)); + Assert(Utilities::MPI::max(hash, communicator) == hash, + ExcInternalError()); + } # else // No MPI -> nothing to replicate diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h index 213382e17f..010e6b7a2b 100644 --- a/include/deal.II/base/array_view.h +++ b/include/deal.II/base/array_view.h @@ -505,12 +505,14 @@ template inline ArrayView::ArrayView( value_type *starting_element, const std::size_t n_elements) - : -#ifdef DEBUG - starting_element(n_elements > 0 ? starting_element : nullptr) -#else - starting_element(starting_element) -#endif + : // In debug mode, make sure that n_elements>0 and if it is not, set + // the pointer to a nullptr to trigger segfaults if anyone ever wanted + // to access elements of the array. In release mode, just take the + // pointer as given. + starting_element((library_build_mode == LibraryBuildMode::release) || + (n_elements > 0) ? + starting_element : + nullptr) , n_elements(n_elements) {} @@ -521,14 +523,17 @@ inline void ArrayView::reinit(value_type *starting_element, const std::size_t n_elements) { -#ifdef DEBUG - if (n_elements > 0) - this->starting_element = starting_element; + if constexpr (running_in_debug_mode()) + { + if (n_elements > 0) + this->starting_element = starting_element; + else + this->starting_element = nullptr; + } else - this->starting_element = nullptr; -#else - this->starting_element = starting_element; -#endif + { + this->starting_element = starting_element; + } this->n_elements = n_elements; } diff --git a/include/deal.II/base/hdf5.h b/include/deal.II/base/hdf5.h index 888833edb2..4ccc052ee8 100644 --- a/include/deal.II/base/hdf5.h +++ b/include/deal.II/base/hdf5.h @@ -193,9 +193,8 @@ DEAL_II_NAMESPACE_OPEN * The following code can be used to query the I/O method. * @code * auto dataset = group.create_dataset("name", dimensions); - * #ifdef DEBUG - * dataset.set_query_io_mode(true); - * #endif + * if constexpr (running_in_debug_mode()) + * dataset.set_query_io_mode(true); * * if (Utilities::MPI::this_mpi_process(mpi_communicator) == 0) * { diff --git a/include/deal.II/base/index_set.h b/include/deal.II/base/index_set.h index 5a27e69514..4a2ff05797 100644 --- a/include/deal.II/base/index_set.h +++ b/include/deal.II/base/index_set.h @@ -1954,12 +1954,13 @@ IndexSet::n_elements() const v = r.nth_index_in_set + r.end - r.begin; } -#ifdef DEBUG - size_type s = 0; - for (const auto &range : ranges) - s += (range.end - range.begin); - Assert(s == v, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + size_type s = 0; + for (const auto &range : ranges) + s += (range.end - range.begin); + Assert(s == v, ExcInternalError()); + } return v; } diff --git a/include/deal.II/base/mpi.templates.h b/include/deal.II/base/mpi.templates.h index 8cc731768b..2e827ee477 100644 --- a/include/deal.II/base/mpi.templates.h +++ b/include/deal.II/base/mpi.templates.h @@ -47,35 +47,37 @@ namespace Utilities #ifdef DEAL_II_WITH_MPI if (job_supports_mpi()) { -# ifdef DEBUG - { - const unsigned int rank = this_mpi_process(mpi_communicator); - unsigned int size = values.size(); - unsigned int size_min = 0; - unsigned int size_max = 0; - int ierr2 = 0; - ierr2 = MPI_Reduce(&size, - &size_min, - 1, - MPI_UNSIGNED, - MPI_MIN, - 0, - mpi_communicator); - AssertThrowMPI(ierr2); - ierr2 = MPI_Reduce(&size, - &size_max, - 1, - MPI_UNSIGNED, - MPI_MAX, - 0, - mpi_communicator); - AssertThrowMPI(ierr2); - if (rank == 0) - Assert(size_min == size_max, - ExcMessage( - "values has different size across MPI processes.")); - } -# endif + if constexpr (running_in_debug_mode()) + { + { + const unsigned int rank = this_mpi_process(mpi_communicator); + unsigned int size = values.size(); + unsigned int size_min = 0; + unsigned int size_max = 0; + int ierr2 = 0; + ierr2 = MPI_Reduce(&size, + &size_min, + 1, + MPI_UNSIGNED, + MPI_MIN, + 0, + mpi_communicator); + AssertThrowMPI(ierr2); + ierr2 = MPI_Reduce(&size, + &size_max, + 1, + MPI_UNSIGNED, + MPI_MAX, + 0, + mpi_communicator); + AssertThrowMPI(ierr2); + if (rank == 0) + Assert( + size_min == size_max, + ExcMessage( + "values has different size across MPI processes.")); + } + } const int ierr = MPI_Allreduce(values != output ? values.data() : MPI_IN_PLACE, static_cast(output.data()), diff --git a/include/deal.II/base/mpi_consensus_algorithms.h b/include/deal.II/base/mpi_consensus_algorithms.h index 9f6de11f53..2d3d846f23 100644 --- a/include/deal.II/base/mpi_consensus_algorithms.h +++ b/include/deal.II/base/mpi_consensus_algorithms.h @@ -1801,12 +1801,13 @@ namespace Utilities AssertThrowMPI(ierr); } -# ifdef DEBUG - // note: IBarrier seems to make problem during testing, this - // additional Barrier seems to help - ierr = MPI_Barrier(comm); - AssertThrowMPI(ierr); -# endif + if constexpr (running_in_debug_mode()) + { + // note: IBarrier seems to make problem during testing, this + // additional Barrier seems to help + ierr = MPI_Barrier(comm); + AssertThrowMPI(ierr); + } } # endif } diff --git a/include/deal.II/base/observer_pointer.h b/include/deal.II/base/observer_pointer.h index 6cb352c1dc..8471394c95 100644 --- a/include/deal.II/base/observer_pointer.h +++ b/include/deal.II/base/observer_pointer.h @@ -611,13 +611,16 @@ template inline void ObserverPointer::swap(ObserverPointer &other) { -#ifdef DEBUG - ObserverPointer aux(pointer, id); - *this = other; - other = aux; -#else - std::swap(pointer, other.pointer); -#endif + if constexpr (running_in_debug_mode()) + { + ObserverPointer aux(pointer, id); + *this = other; + other = aux; + } + else + { + std::swap(pointer, other.pointer); + } } diff --git a/include/deal.II/differentiation/ad/ad_helpers.h b/include/deal.II/differentiation/ad/ad_helpers.h index 4fd48e5c96..18ddc2c16c 100644 --- a/include/deal.II/differentiation/ad/ad_helpers.h +++ b/include/deal.II/differentiation/ad/ad_helpers.h @@ -3818,24 +3818,25 @@ namespace Differentiation // function, in the sense that we simply populate our array of independent // values with a meaningful number. However, in this case we need to // double check that we're not registering these variables twice -# ifdef DEBUG - const std::vector index_set( - internal::extract_field_component_indices(extractor)); - for (const unsigned int index : index_set) + if constexpr (running_in_debug_mode()) { - Assert( - this->registered_independent_variable_values[index] == false, - ExcMessage( - "Overlapping indices for independent variables. " - "One or more indices associated with the field that " - "is being registered as an independent variable have " - "already been associated with another field. This suggests " - "that the component offsets used to construct their counterpart " - "extractors are incompatible with one another. Make sure that " - "the first component for each extractor properly takes into " - "account the dimensionality of the preceding fields.")); + const std::vector index_set( + internal::extract_field_component_indices(extractor)); + for (const unsigned int index : index_set) + { + Assert( + this->registered_independent_variable_values[index] == false, + ExcMessage( + "Overlapping indices for independent variables. " + "One or more indices associated with the field that " + "is being registered as an independent variable have " + "already been associated with another field. This suggests " + "that the component offsets used to construct their counterpart " + "extractors are incompatible with one another. Make sure that " + "the first component for each extractor properly takes into " + "account the dimensionality of the preceding fields.")); + } } -# endif set_independent_variable(value, extractor); } diff --git a/include/deal.II/dofs/dof_accessor.h b/include/deal.II/dofs/dof_accessor.h index 72ea3db6e5..69c8ebeecc 100644 --- a/include/deal.II/dofs/dof_accessor.h +++ b/include/deal.II/dofs/dof_accessor.h @@ -4451,10 +4451,11 @@ DoFCellAccessor::neighbor( this->neighbor_index(i), this->dof_handler); -#ifdef DEBUG - if (q.state() != IteratorState::past_the_end) - Assert(q->used(), ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + if (q.state() != IteratorState::past_the_end) + Assert(q->used(), ExcInternalError()); + } return q; } @@ -4469,10 +4470,11 @@ DoFCellAccessor::child( TriaIterator> q(this->tria, this->level() + 1, this->child_index(i), this->dof_handler); -#ifdef DEBUG - if (q.state() != IteratorState::past_the_end) - Assert(q->used(), ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + if (q.state() != IteratorState::past_the_end) + Assert(q->used(), ExcInternalError()); + } return q; } diff --git a/include/deal.II/fe/fe_coupling_values.h b/include/deal.II/fe/fe_coupling_values.h index a79e26fc58..6529dc99ac 100644 --- a/include/deal.II/fe/fe_coupling_values.h +++ b/include/deal.II/fe/fe_coupling_values.h @@ -1086,17 +1086,18 @@ namespace FEValuesViews , dof_renumbering(dof_renumbering) , quadrature_renumbering(quadrature_renumbering) { -// Check that the renumbering vectors are valid. -# ifdef DEBUG - // While for dofs we admit invalid values, this is not the case for - // quadrature points. - for (const auto i : dof_renumbering) - Assert(i < n_inner_dofs || i == numbers::invalid_unsigned_int, - ExcIndexRange(i, 0, n_inner_dofs)); - - for (const auto q : quadrature_renumbering) - AssertIndexRange(q, n_inner_quadrature_points); -# endif + // Check that the renumbering vectors are valid. + if constexpr (running_in_debug_mode()) + { + // While for dofs we admit invalid values, this is not the case for + // quadrature points. + for (const auto i : dof_renumbering) + Assert(i < n_inner_dofs || i == numbers::invalid_unsigned_int, + ExcIndexRange(i, 0, n_inner_dofs)); + + for (const auto q : quadrature_renumbering) + AssertIndexRange(q, n_inner_quadrature_points); + } } diff --git a/include/deal.II/fe/fe_tools.templates.h b/include/deal.II/fe/fe_tools.templates.h index 77442f4897..1f3ec76b14 100644 --- a/include/deal.II/fe/fe_tools.templates.h +++ b/include/deal.II/fe/fe_tools.templates.h @@ -2238,23 +2238,24 @@ namespace FETools if (name_end < name.size()) name.erase(name_end); - // Ensure that the element we are looking for isn't in the map - // yet. This only requires us to read the map, so it can happen - // in a shared locked state -#ifdef DEBUG - { - std::shared_lock lock( - internal::FEToolsAddFENameHelper::fe_name_map_lock); - - Assert( - internal::FEToolsAddFENameHelper::get_fe_name_map()[dim][spacedim].find( - name) == - internal::FEToolsAddFENameHelper::get_fe_name_map()[dim][spacedim] - .end(), - ExcMessage( - "Cannot change existing element in finite element name list")); - } -#endif + // Ensure that the element we are looking for isn't in the map + // yet. This only requires us to read the map, so it can happen + // in a shared locked state + if constexpr (running_in_debug_mode()) + { + { + std::shared_lock lock( + internal::FEToolsAddFENameHelper::fe_name_map_lock); + + Assert( + internal::FEToolsAddFENameHelper::get_fe_name_map()[dim][spacedim] + .find(name) == + internal::FEToolsAddFENameHelper::get_fe_name_map()[dim][spacedim] + .end(), + ExcMessage( + "Cannot change existing element in finite element name list")); + } + } // Insert the normalized name into the map. This changes the map, so it diff --git a/include/deal.II/fe/fe_tools_interpolate.templates.h b/include/deal.II/fe/fe_tools_interpolate.templates.h index bfb50b7b1d..791596f377 100644 --- a/include/deal.II/fe/fe_tools_interpolate.templates.h +++ b/include/deal.II/fe/fe_tools_interpolate.templates.h @@ -87,17 +87,20 @@ namespace FETools const IndexSet u2_elements = u2.locally_owned_elements(); -#ifdef DEBUG - const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); - const IndexSet &dof2_local_dofs = dof2.locally_owned_dofs(); - const IndexSet u1_elements = u1.locally_owned_elements(); - Assert(u1_elements == dof1_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); - Assert(u2_elements == dof2_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); -#endif + if constexpr (running_in_debug_mode()) + { + const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); + const IndexSet &dof2_local_dofs = dof2.locally_owned_dofs(); + const IndexSet u1_elements = u1.locally_owned_elements(); + Assert(u1_elements == dof1_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + Assert(u2_elements == dof2_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + } // allocate vectors at maximal // size. will be reinited in inner @@ -148,20 +151,21 @@ namespace FETools ExcDimensionMismatch(cell1->get_fe().n_components(), cell2->get_fe().n_components())); -#ifdef DEBUG - // For continuous elements on grids with hanging nodes we need - // hanging node constraints. Consequently, when the elements are - // continuous no hanging node constraints are allowed. - const bool hanging_nodes_not_allowed = - ((cell2->get_fe().n_dofs_per_vertex() != 0) && - (constraints.n_constraints() == 0)); - - if (hanging_nodes_not_allowed) - for (const unsigned int face : cell1->face_indices()) - Assert(cell1->at_boundary(face) || - cell1->neighbor(face)->level() == cell1->level(), - ExcHangingNodesNotAllowed()); -#endif + if constexpr (running_in_debug_mode()) + { + // For continuous elements on grids with hanging nodes we need + // hanging node constraints. Consequently, when the elements are + // continuous no hanging node constraints are allowed. + const bool hanging_nodes_not_allowed = + ((cell2->get_fe().n_dofs_per_vertex() != 0) && + (constraints.n_constraints() == 0)); + + if (hanging_nodes_not_allowed) + for (const unsigned int face : cell1->face_indices()) + Assert(cell1->at_boundary(face) || + cell1->neighbor(face)->level() == cell1->level(), + ExcHangingNodesNotAllowed()); + } const unsigned int dofs_per_cell1 = cell1->get_fe().n_dofs_per_cell(); const unsigned int dofs_per_cell2 = cell2->get_fe().n_dofs_per_cell(); @@ -267,18 +271,21 @@ namespace FETools Assert(u1_interpolated.size() == dof1.n_dofs(), ExcDimensionMismatch(u1_interpolated.size(), dof1.n_dofs())); -#ifdef DEBUG - const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); - const IndexSet u1_elements = u1.locally_owned_elements(); - const IndexSet u1_interpolated_elements = - u1_interpolated.locally_owned_elements(); - Assert(u1_elements == dof1_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); - Assert(u1_interpolated_elements == dof1_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); -#endif + if constexpr (running_in_debug_mode()) + { + const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); + const IndexSet u1_elements = u1.locally_owned_elements(); + const IndexSet u1_interpolated_elements = + u1_interpolated.locally_owned_elements(); + Assert(u1_elements == dof1_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + Assert(u1_interpolated_elements == dof1_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + } Vector u1_local( dof1.get_fe_collection().max_dofs_per_cell()); @@ -302,20 +309,21 @@ namespace FETools if ((cell->subdomain_id() == subdomain_id) || (subdomain_id == numbers::invalid_subdomain_id)) { -#ifdef DEBUG - // For continuous elements on grids with hanging nodes we need - // hanging node constraints. Consequently, when the elements are - // continuous no hanging node constraints are allowed. - const bool hanging_nodes_not_allowed = - (cell->get_fe().n_dofs_per_vertex() != 0) || - (fe2.n_dofs_per_vertex() != 0); - - if (hanging_nodes_not_allowed) - for (const unsigned int face : cell->face_indices()) - Assert(cell->at_boundary(face) || - cell->neighbor(face)->level() == cell->level(), - ExcHangingNodesNotAllowed()); -#endif + if constexpr (running_in_debug_mode()) + { + // For continuous elements on grids with hanging nodes we need + // hanging node constraints. Consequently, when the elements are + // continuous no hanging node constraints are allowed. + const bool hanging_nodes_not_allowed = + (cell->get_fe().n_dofs_per_vertex() != 0) || + (fe2.n_dofs_per_vertex() != 0); + + if (hanging_nodes_not_allowed) + for (const unsigned int face : cell->face_indices()) + Assert(cell->at_boundary(face) || + cell->neighbor(face)->level() == cell->level(), + ExcHangingNodesNotAllowed()); + } const unsigned int dofs_per_cell1 = cell->get_fe().n_dofs_per_cell(); @@ -604,18 +612,21 @@ namespace FETools Assert(u1_difference.size() == dof1.n_dofs(), ExcDimensionMismatch(u1_difference.size(), dof1.n_dofs())); -#ifdef DEBUG - const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); - const IndexSet u1_elements = u1.locally_owned_elements(); - const IndexSet u1_difference_elements = - u1_difference.locally_owned_elements(); - Assert(u1_elements == dof1_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); - Assert(u1_difference_elements == dof1_local_dofs, - ExcMessage("The provided vector and DoF handler should have the same" - " index sets.")); -#endif + if constexpr (running_in_debug_mode()) + { + const IndexSet &dof1_local_dofs = dof1.locally_owned_dofs(); + const IndexSet u1_elements = u1.locally_owned_elements(); + const IndexSet u1_difference_elements = + u1_difference.locally_owned_elements(); + Assert(u1_elements == dof1_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + Assert(u1_difference_elements == dof1_local_dofs, + ExcMessage( + "The provided vector and DoF handler should have the same" + " index sets.")); + } const unsigned int dofs_per_cell = dof1.get_fe().n_dofs_per_cell(); @@ -636,20 +647,21 @@ namespace FETools if ((cell->subdomain_id() == subdomain_id) || (subdomain_id == numbers::invalid_subdomain_id)) { -#ifdef DEBUG - // For continuous elements on grids with hanging nodes we need - // hanging node constraints. Consequently, when the elements are - // continuous no hanging node constraints are allowed. - const bool hanging_nodes_not_allowed = - (dof1.get_fe().n_dofs_per_vertex() != 0) || - (fe2.n_dofs_per_vertex() != 0); - - if (hanging_nodes_not_allowed) - for (const unsigned int face : cell->face_indices()) - Assert(cell->at_boundary(face) || - cell->neighbor(face)->level() == cell->level(), - ExcHangingNodesNotAllowed()); -#endif + if constexpr (running_in_debug_mode()) + { + // For continuous elements on grids with hanging nodes we need + // hanging node constraints. Consequently, when the elements are + // continuous no hanging node constraints are allowed. + const bool hanging_nodes_not_allowed = + (dof1.get_fe().n_dofs_per_vertex() != 0) || + (fe2.n_dofs_per_vertex() != 0); + + if (hanging_nodes_not_allowed) + for (const unsigned int face : cell->face_indices()) + Assert(cell->at_boundary(face) || + cell->neighbor(face)->level() == cell->level(), + ExcHangingNodesNotAllowed()); + } cell->get_dof_values(u1, u1_local); difference_matrix.vmult(u1_diff_local, u1_local); diff --git a/include/deal.II/grid/connectivity.h b/include/deal.II/grid/connectivity.h index caec0fc926..98a74449ce 100644 --- a/include/deal.II/grid/connectivity.h +++ b/include/deal.II/grid/connectivity.h @@ -1489,22 +1489,24 @@ namespace internal // loop over cells and create CRS for (const auto &cell : cells) { -#ifdef DEBUG - auto vertices_unique = cell.vertices; - std::sort(vertices_unique.begin(), vertices_unique.end()); - vertices_unique.erase(std::unique(vertices_unique.begin(), - vertices_unique.end()), - vertices_unique.end()); - - Assert(vertices_unique.size() == cell.vertices.size(), - ExcMessage( - "The definition of a cell refers to the same vertex several " - "times. This is not possible. A common reason is that " - "CellData::vertices has a size that does not match the " - "size expected from the reference cell. Please resize " - "CellData::vertices or use the appropriate constructor of " - "CellData.")); -#endif + if constexpr (running_in_debug_mode()) + { + auto vertices_unique = cell.vertices; + std::sort(vertices_unique.begin(), vertices_unique.end()); + vertices_unique.erase(std::unique(vertices_unique.begin(), + vertices_unique.end()), + vertices_unique.end()); + + Assert( + vertices_unique.size() == cell.vertices.size(), + ExcMessage( + "The definition of a cell refers to the same vertex several " + "times. This is not possible. A common reason is that " + "CellData::vertices has a size that does not match the " + "size expected from the reference cell. Please resize " + "CellData::vertices or use the appropriate constructor of " + "CellData.")); + } const ReferenceCell reference_cell = ReferenceCell::n_vertices_to_type(dim, cell.vertices.size()); diff --git a/include/deal.II/grid/tria_accessor.h b/include/deal.II/grid/tria_accessor.h index 9ea31ea620..c5230a14c2 100644 --- a/include/deal.II/grid/tria_accessor.h +++ b/include/deal.II/grid/tria_accessor.h @@ -6473,21 +6473,22 @@ TriaAccessor::enclosing_ball() const // outside the old ball. } } -# ifdef DEBUG - bool all_vertices_within_ball = true; + if constexpr (running_in_debug_mode()) + { + bool all_vertices_within_ball = true; - // Set all_vertices_within_ball false if any of the vertices of the object - // are geometrically outside the ball - for (const unsigned int v : this->vertex_indices()) - if (center.distance(this->vertex(v)) > - radius + 100. * std::numeric_limits::epsilon()) - { - all_vertices_within_ball = false; - break; - } - // If all the vertices are not within the ball throw error - Assert(all_vertices_within_ball, ExcInternalError()); -# endif + // Set all_vertices_within_ball false if any of the vertices of the object + // are geometrically outside the ball + for (const unsigned int v : this->vertex_indices()) + if (center.distance(this->vertex(v)) > + radius + 100. * std::numeric_limits::epsilon()) + { + all_vertices_within_ball = false; + break; + } + // If all the vertices are not within the ball throw error + Assert(all_vertices_within_ball, ExcInternalError()); + } return std::make_pair(center, radius); } diff --git a/include/deal.II/grid/tria_iterator.h b/include/deal.II/grid/tria_iterator.h index a2e2e2660c..b4089f5131 100644 --- a/include/deal.II/grid/tria_iterator.h +++ b/include/deal.II/grid/tria_iterator.h @@ -1136,16 +1136,17 @@ inline TriaIterator::TriaIterator( const TriaRawIterator &i) : TriaRawIterator(i.accessor) { -#ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -#endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } } template @@ -1153,16 +1154,17 @@ template TriaIterator::TriaIterator(const OtherAccessor &a) : TriaRawIterator(a) { -#ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -#endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } } template @@ -1180,17 +1182,18 @@ inline TriaActiveIterator::TriaActiveIterator( const TriaRawIterator &i) : TriaIterator(i) { -#ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -#endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } } @@ -1351,16 +1354,17 @@ template inline TriaIterator::TriaIterator(const TriaRawIterator &i) : TriaRawIterator(i.accessor) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } } @@ -1372,16 +1376,17 @@ inline TriaIterator::TriaIterator( const typename Accessor::AccessorData *local_data) : TriaRawIterator(parent, level, index, local_data) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } } @@ -1393,16 +1398,17 @@ inline TriaIterator::TriaIterator( const typename Accessor::AccessorData *local_data) : TriaRawIterator(tria_accessor, local_data) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } } @@ -1430,16 +1436,17 @@ inline TriaIterator & TriaIterator::operator=(const TriaRawIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } return *this; } @@ -1450,16 +1457,17 @@ inline TriaIterator & TriaIterator::operator=(const TriaRawIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || used)" - // used() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || used)" + // used() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used(), ExcAssignmentOfUnusedObject()); + } return *this; } @@ -1531,17 +1539,18 @@ inline TriaActiveIterator::TriaActiveIterator( const TriaRawIterator &i) : TriaIterator(i) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } } @@ -1550,17 +1559,18 @@ inline TriaActiveIterator::TriaActiveIterator( const TriaIterator &i) : TriaIterator(i) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } } @@ -1572,17 +1582,18 @@ inline TriaActiveIterator::TriaActiveIterator( const typename Accessor::AccessorData *local_data) : TriaIterator(parent, level, index, local_data) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } } @@ -1594,17 +1605,18 @@ inline TriaActiveIterator::TriaActiveIterator( const typename Accessor::AccessorData *local_data) : TriaIterator(tria_accessor, local_data) { -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } } @@ -1633,17 +1645,18 @@ inline TriaActiveIterator & TriaActiveIterator::operator=(const TriaRawIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used() && this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used() && this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } return *this; } @@ -1654,17 +1667,18 @@ inline TriaActiveIterator & TriaActiveIterator::operator=(const TriaRawIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.used() && this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.used() && this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } return *this; } @@ -1675,17 +1689,18 @@ inline TriaActiveIterator & TriaActiveIterator::operator=(const TriaIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } return *this; } @@ -1695,17 +1710,18 @@ inline TriaActiveIterator & TriaActiveIterator::operator=(const TriaIterator &i) { this->accessor.copy_from(i.accessor); -# ifdef DEBUG - // do this like this, because: - // if we write - // "Assert (IteratorState::past_the_end || !has_children())" - // has_children() is called anyway, even if - // state==IteratorState::past_the_end, and will then - // throw the exception! - if (this->state() != IteratorState::past_the_end) - Assert(this->accessor.has_children() == false, - ExcAssignmentOfInactiveObject()); -# endif + if constexpr (running_in_debug_mode()) + { + // do this like this, because: + // if we write + // "Assert (IteratorState::past_the_end || !has_children())" + // has_children() is called anyway, even if + // state==IteratorState::past_the_end, and will then + // throw the exception! + if (this->state() != IteratorState::past_the_end) + Assert(this->accessor.has_children() == false, + ExcAssignmentOfInactiveObject()); + } return *this; } diff --git a/include/deal.II/lac/affine_constraints.templates.h b/include/deal.II/lac/affine_constraints.templates.h index 9b8325f391..43ff7029b7 100644 --- a/include/deal.II/lac/affine_constraints.templates.h +++ b/include/deal.II/lac/affine_constraints.templates.h @@ -98,21 +98,23 @@ AffineConstraints::add_constraint( // of Q4 elements in 3d, and so should cover the vast majority of // cases. If we have a constraint with more dependencies, then // that's just going to require a heap allocation. -#ifdef DEBUG - { - boost::container::small_vector column_indices; - column_indices.reserve(dependencies.size()); - for (const auto &d : dependencies) - column_indices.emplace_back(d.first); - std::sort(column_indices.begin(), column_indices.end()); - Assert(std::adjacent_find(column_indices.begin(), column_indices.end()) == - column_indices.end(), - ExcMessage( - "You are trying to insert a constraint that lists the same " - "degree of freedom more than once on the right hand side. This is " - "not allowed.")); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + boost::container::small_vector column_indices; + column_indices.reserve(dependencies.size()); + for (const auto &d : dependencies) + column_indices.emplace_back(d.first); + std::sort(column_indices.begin(), column_indices.end()); + Assert( + std::adjacent_find(column_indices.begin(), column_indices.end()) == + column_indices.end(), + ExcMessage( + "You are trying to insert a constraint that lists the same " + "degree of freedom more than once on the right hand side. This is " + "not allowed.")); + } + } // The following can happen when we compute with distributed meshes and dof @@ -792,7 +794,6 @@ AffineConstraints::close() -#ifdef DEBUG // In debug mode we are computing an estimate for the maximum number // of constraints so that we can bail out if there is a cycle in the // constraints (which is easier than searching for cycles in the graph). @@ -800,29 +801,29 @@ AffineConstraints::close() // Let us figure out the largest dof index. This is an upper bound for the // number of constraints because it is an approximation for the number of dofs // in our system. - size_type largest_idx = 0; - for (const ConstraintLine &line : lines) - for (const std::pair &entry : line.entries) - largest_idx = std::max(largest_idx, entry.first); -#endif + [[maybe_unused]] size_type largest_idx = 0; + if constexpr (running_in_debug_mode()) + { + for (const ConstraintLine &line : lines) + for (const std::pair &entry : line.entries) + largest_idx = std::max(largest_idx, entry.first); + } - // replace references to dofs that are themselves constrained. note that - // because we may replace references to other dofs that may themselves be - // constrained to third ones, we have to iterate over all this until we - // replace no chains of constraints any more - // - // the iteration replaces references to constrained degrees of freedom by - // second-order references. for example if x3=x0/2+x2/2 and x2=x0/2+x1/2, - // then the new list will be x3=x0/2+x0/4+x1/4. note that x0 appear - // twice. we will throw this duplicate out in the following step, where - // we sort the list so that throwing out duplicates becomes much more - // efficient. also, we have to do it only once, rather than in each - // iteration -#ifdef DEBUG - size_type iteration = 0; -#endif - bool chained_constraint_replaced = false; - std::vector line_finalized(lines.size(), false); + // replace references to dofs that are themselves constrained. note that + // because we may replace references to other dofs that may themselves be + // constrained to third ones, we have to iterate over all this until we + // replace no chains of constraints any more + // + // the iteration replaces references to constrained degrees of freedom by + // second-order references. for example if x3=x0/2+x2/2 and x2=x0/2+x1/2, + // then the new list will be x3=x0/2+x0/4+x1/4. note that x0 appear + // twice. we will throw this duplicate out in the following step, where + // we sort the list so that throwing out duplicates becomes much more + // efficient. also, we have to do it only once, rather than in each + // iteration + [[maybe_unused]] size_type iteration = 0; + bool chained_constraint_replaced = false; + std::vector line_finalized(lines.size(), false); do { chained_constraint_replaced = false; @@ -831,12 +832,10 @@ AffineConstraints::close() { ConstraintLine &line = lines[line_index]; -#ifdef DEBUG // we need to keep track of how many replacements we do in this // line, because we can end up in a cycle A->B->C->A without the // number of entries growing. - size_type n_replacements = 0; -#endif + [[maybe_unused]] size_type n_replacements = 0; // loop over all entries of this line (including ones that we // have appended in this go around) and see whether they are @@ -902,14 +901,17 @@ AffineConstraints::close() constrained_line.entries[i].first, constrained_line.entries[i].second * weight); -#ifdef DEBUG - // keep track of how many entries we replace in this - // line. If we do more than there are constraints or - // dofs in our system, we must have a cycle. - ++n_replacements; - Assert(n_replacements / 2 < largest_idx, - ExcMessage("Cycle in constraints detected!")); -#endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + // keep track of how many entries we replace in this + // line. If we do more than there are constraints or + // dofs in our system, we must have a cycle. + ++n_replacements; + Assert(n_replacements / 2 < largest_idx, + ExcMessage( + "Cycle in constraints detected!")); + } } else // the DoF that we encountered is not constrained by a @@ -950,13 +952,14 @@ AffineConstraints::close() } } -#ifdef DEBUG - // increase iteration count. note that we should not iterate more - // times than there are constraints, since this puts a natural upper - // bound on the length of constraint chains - ++iteration; - Assert(iteration <= lines.size() + 1, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // increase iteration count. note that we should not iterate more + // times than there are constraints, since this puts a natural upper + // bound on the length of constraint chains + ++iteration; + Assert(iteration <= lines.size() + 1, ExcInternalError()); + } } while (chained_constraint_replaced == true); @@ -1170,14 +1173,15 @@ AffineConstraints::shift(const size_type offset) entry.first += offset; } -#ifdef DEBUG - // make sure that lines, lines_cache and local_lines - // are still linked correctly - for (size_type index = 0; index < lines_cache.size(); ++index) - Assert(lines_cache[index] == numbers::invalid_size_type || - calculate_line_index(lines[lines_cache[index]].index) == index, - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // make sure that lines, lines_cache and local_lines + // are still linked correctly + for (size_type index = 0; index < lines_cache.size(); ++index) + Assert(lines_cache[index] == numbers::invalid_size_type || + calculate_line_index(lines[lines_cache[index]].index) == index, + ExcInternalError()); + } } @@ -1214,24 +1218,25 @@ AffineConstraints::get_view(const IndexSet &mask) const for (const ConstraintLine &line : lines) if (mask.is_element(line.index)) { -#ifdef DEBUG - for (const std::pair &entry : line.entries) + if constexpr (running_in_debug_mode()) { - Assert( - mask.is_element(entry.first), - ExcMessage( - "In creating a view of an AffineConstraints " - "object, the constraint on degree of freedom " + - std::to_string(line.index) + " (which corresponds to the " + - std::to_string(mask.index_within_set(line.index)) + - "th degree of freedom selected in the mask) " - "is constrained against degree of freedom " + - std::to_string(entry.first) + - ", but this degree of freedom is not listed in the mask and " - "consequently cannot be transcribed into the index space " - "of the output object.")); + for (const std::pair &entry : line.entries) + { + Assert( + mask.is_element(entry.first), + ExcMessage( + "In creating a view of an AffineConstraints " + "object, the constraint on degree of freedom " + + std::to_string(line.index) + " (which corresponds to the " + + std::to_string(mask.index_within_set(line.index)) + + "th degree of freedom selected in the mask) " + "is constrained against degree of freedom " + + std::to_string(entry.first) + + ", but this degree of freedom is not listed in the mask and " + "consequently cannot be transcribed into the index space " + "of the output object.")); + } } -#endif std::vector> translated_entries = line.entries; @@ -2856,32 +2861,33 @@ AffineConstraints::distribute(VectorType &vec) const } - // Check that the set of indices we will import is a superset of - // the locally-owned ones. This *should* be the case if, as one - // would expect, the AffineConstraint object was initialized - // with a locally-relevant index set that is indeed a superset - // of the locally-owned indices. But you never know what people - // pass as arguments... -#ifdef DEBUG - if (needed_elements_for_distribute != IndexSet()) + // Check that the set of indices we will import is a superset of + // the locally-owned ones. This *should* be the case if, as one + // would expect, the AffineConstraint object was initialized + // with a locally-relevant index set that is indeed a superset + // of the locally-owned indices. But you never know what people + // pass as arguments... + if constexpr (running_in_debug_mode()) { - Assert(vec_owned_elements.size() == - needed_elements_for_distribute.size(), - ExcMessage("You have previously initialized this " - "AffineConstraints object with an index set " - "that stated that vectors have size " + - std::to_string(locally_owned_dofs.size()) + - " entries, but you are now calling " - "AffineConstraints::distribute() with a vector " - "of size " + - std::to_string(vec_owned_elements.size()) + - ".")); - - for (const auto i : vec_owned_elements) - Assert(needed_elements_for_distribute.is_element(i), - ExcInternalError()); + if (needed_elements_for_distribute != IndexSet()) + { + Assert(vec_owned_elements.size() == + needed_elements_for_distribute.size(), + ExcMessage( + "You have previously initialized this " + "AffineConstraints object with an index set " + "that stated that vectors have size " + + std::to_string(locally_owned_dofs.size()) + + " entries, but you are now calling " + "AffineConstraints::distribute() with a vector " + "of size " + + std::to_string(vec_owned_elements.size()) + ".")); + + for (const auto i : vec_owned_elements) + Assert(needed_elements_for_distribute.is_element(i), + ExcInternalError()); + } } -#endif VectorType ghosted_vector; diff --git a/include/deal.II/lac/block_linear_operator.h b/include/deal.II/lac/block_linear_operator.h index 1189df76bf..20dc26828b 100644 --- a/include/deal.II/lac/block_linear_operator.h +++ b/include/deal.II/lac/block_linear_operator.h @@ -599,12 +599,13 @@ block_operator(const BlockMatrixType &block_matrix) return_op.block = [&block_matrix](unsigned int i, unsigned int j) -> BlockType { -#ifdef DEBUG - const unsigned int m = block_matrix.n_block_rows(); - const unsigned int n = block_matrix.n_block_cols(); - AssertIndexRange(i, m); - AssertIndexRange(j, n); -#endif + if constexpr (running_in_debug_mode()) + { + const unsigned int m = block_matrix.n_block_rows(); + const unsigned int n = block_matrix.n_block_cols(); + AssertIndexRange(i, m); + AssertIndexRange(j, n); + } return BlockType(block_matrix.block(i, j)); }; @@ -720,13 +721,14 @@ block_diagonal_operator(const BlockMatrixType &block_matrix) return_op.block = [&block_matrix](unsigned int i, unsigned int j) -> BlockType { -#ifdef DEBUG - const unsigned int m = block_matrix.n_block_rows(); - const unsigned int n = block_matrix.n_block_cols(); - Assert(m == n, ExcDimensionMismatch(m, n)); - AssertIndexRange(i, m); - AssertIndexRange(j, n); -#endif + if constexpr (running_in_debug_mode()) + { + const unsigned int m = block_matrix.n_block_rows(); + const unsigned int n = block_matrix.n_block_cols(); + Assert(m == n, ExcDimensionMismatch(m, n)); + AssertIndexRange(i, m); + AssertIndexRange(j, n); + } if (i == j) return BlockType(block_matrix.block(i, j)); else diff --git a/include/deal.II/lac/block_matrix_base.h b/include/deal.II/lac/block_matrix_base.h index d47f93a25b..8aa638b1fb 100644 --- a/include/deal.II/lac/block_matrix_base.h +++ b/include/deal.II/lac/block_matrix_base.h @@ -1786,14 +1786,15 @@ BlockMatrixBase::set(const size_type row, temporary_data.column_values[col_index.first][local_index] = value; } -# ifdef DEBUG - // If in debug mode, do a check whether - // the right length has been obtained. - size_type length = 0; - for (unsigned int i = 0; i < this->n_block_cols(); ++i) - length += temporary_data.counter_within_block[i]; - Assert(length <= n_cols, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + // If in debug mode, do a check whether + // the right length has been obtained. + size_type length = 0; + for (unsigned int i = 0; i < this->n_block_cols(); ++i) + length += temporary_data.counter_within_block[i]; + Assert(length <= n_cols, ExcInternalError()); + } // Now we found out about where the // individual columns should start and @@ -1929,20 +1930,21 @@ BlockMatrixBase::add(const size_type row, // efficiently. if (col_indices_are_sorted == true) { -# ifdef DEBUG - // check whether indices really are - // sorted. - size_type before = col_indices[0]; - for (size_type i = 1; i < n_cols; ++i) - if (col_indices[i] <= before) - { - Assert(false, - ExcMessage("Flag col_indices_are_sorted is set, but " - "indices appear to not be sorted.")); - } - else - before = col_indices[i]; -# endif + if constexpr (running_in_debug_mode()) + { + // check whether indices really are + // sorted. + size_type before = col_indices[0]; + for (size_type i = 1; i < n_cols; ++i) + if (col_indices[i] <= before) + { + Assert(false, + ExcMessage("Flag col_indices_are_sorted is set, but " + "indices appear to not be sorted.")); + } + else + before = col_indices[i]; + } const std::pair row_index = this->row_block_indices.global_to_local(row); @@ -2045,14 +2047,15 @@ BlockMatrixBase::add(const size_type row, temporary_data.column_values[col_index.first][local_index] = value; } -# ifdef DEBUG - // If in debug mode, do a check whether - // the right length has been obtained. - size_type length = 0; - for (unsigned int i = 0; i < this->n_block_cols(); ++i) - length += temporary_data.counter_within_block[i]; - Assert(length <= n_cols, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + // If in debug mode, do a check whether + // the right length has been obtained. + size_type length = 0; + for (unsigned int i = 0; i < this->n_block_cols(); ++i) + length += temporary_data.counter_within_block[i]; + Assert(length <= n_cols, ExcInternalError()); + } // Now we found out about where the // individual columns should start and diff --git a/include/deal.II/lac/block_sparsity_pattern.h b/include/deal.II/lac/block_sparsity_pattern.h index 72615e8b30..4e3be0e48c 100644 --- a/include/deal.II/lac/block_sparsity_pattern.h +++ b/include/deal.II/lac/block_sparsity_pattern.h @@ -897,15 +897,16 @@ BlockSparsityPatternBase::add_entries( block_column_indices[0].push_back(local_index); // Check that calculation: -#ifdef DEBUG - { - auto check_block_and_col = column_indices.global_to_local(*it); - Assert(current_block == check_block_and_col.first, - ExcInternalError()); - Assert(local_index == check_block_and_col.second, - ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + auto check_block_and_col = column_indices.global_to_local(*it); + Assert(current_block == check_block_and_col.first, + ExcInternalError()); + Assert(local_index == check_block_and_col.second, + ExcInternalError()); + } + } } // add whatever is left over: sub_objects[row_index.first][current_block]->add_entries( diff --git a/include/deal.II/lac/la_parallel_vector.templates.h b/include/deal.II/lac/la_parallel_vector.templates.h index 5cec78da44..0793815015 100644 --- a/include/deal.II/lac/la_parallel_vector.templates.h +++ b/include/deal.II/lac/la_parallel_vector.templates.h @@ -1372,40 +1372,41 @@ namespace LinearAlgebra { #ifdef DEAL_II_WITH_MPI -# ifdef DEBUG - Assert(Utilities::MPI::job_supports_mpi() || - (update_ghost_values_requests.empty() && - compress_requests.empty()), - ExcInternalError()); - - // make sure that there are not outstanding requests from updating - // ghost values or compress - if (update_ghost_values_requests.size() > 0) - { - int flag = 1; - const int ierr = MPI_Testall(update_ghost_values_requests.size(), - update_ghost_values_requests.data(), - &flag, - MPI_STATUSES_IGNORE); - AssertThrowMPI(ierr); - Assert(flag == 1, - ExcMessage( - "MPI found unfinished update_ghost_values() requests " - "when calling swap, which is not allowed.")); - } - if (compress_requests.size() > 0) + if constexpr (running_in_debug_mode()) { - int flag = 1; - const int ierr = MPI_Testall(compress_requests.size(), - compress_requests.data(), - &flag, - MPI_STATUSES_IGNORE); - AssertThrowMPI(ierr); - Assert(flag == 1, - ExcMessage("MPI found unfinished compress() requests " - "when calling swap, which is not allowed.")); + Assert(Utilities::MPI::job_supports_mpi() || + (update_ghost_values_requests.empty() && + compress_requests.empty()), + ExcInternalError()); + + // make sure that there are not outstanding requests from updating + // ghost values or compress + if (update_ghost_values_requests.size() > 0) + { + int flag = 1; + const int ierr = MPI_Testall(update_ghost_values_requests.size(), + update_ghost_values_requests.data(), + &flag, + MPI_STATUSES_IGNORE); + AssertThrowMPI(ierr); + Assert(flag == 1, + ExcMessage( + "MPI found unfinished update_ghost_values() requests " + "when calling swap, which is not allowed.")); + } + if (compress_requests.size() > 0) + { + int flag = 1; + const int ierr = MPI_Testall(compress_requests.size(), + compress_requests.data(), + &flag, + MPI_STATUSES_IGNORE); + AssertThrowMPI(ierr); + Assert(flag == 1, + ExcMessage("MPI found unfinished compress() requests " + "when calling swap, which is not allowed.")); + } } -# endif std::swap(compress_requests, v.compress_requests); std::swap(update_ghost_values_requests, v.update_ghost_values_requests); @@ -1756,32 +1757,34 @@ namespace LinearAlgebra Vector::assert_no_residual_content_in_ghost_region() const { -#ifdef DEBUG - // This should only be called for non-ghosted vectors - Assert(!vector_is_ghosted, ExcInternalError()); + if constexpr (running_in_debug_mode()) + { + // This should only be called for non-ghosted vectors + Assert(!vector_is_ghosted, ExcInternalError()); - // Run a reduction over the ghost range only to find out whether some - // entries are non-zero - real_type sum = real_type(); - dealii::internal::VectorOperations:: - functions::norm_1( - thread_loop_partitioner, - partitioner->n_ghost_indices(), - sum, - data, - partitioner->locally_owned_size()); - - Assert(sum == real_type(), - ExcMessage("You called a vector space operation like add(), " - "scale(), operator* for a non-ghosted vector, which " - "will not update the content in the memory locations " - "reserved for ghost values. However, a non-zero " - "content was detected for some of those entries, which " - "can lead to an invalid state of the vector. Please " - "call Vector::compress(VectorOperation::add) or " - "Vector::zero_out_ghost_values() before calling a " - "vector space operation to avoid this problem.")); -#endif + // Run a reduction over the ghost range only to find out whether some + // entries are non-zero + real_type sum = real_type(); + dealii::internal::VectorOperations:: + functions::norm_1( + thread_loop_partitioner, + partitioner->n_ghost_indices(), + sum, + data, + partitioner->locally_owned_size()); + + Assert(sum == real_type(), + ExcMessage( + "You called a vector space operation like add(), " + "scale(), operator* for a non-ghosted vector, which " + "will not update the content in the memory locations " + "reserved for ghost values. However, a non-zero " + "content was detected for some of those entries, which " + "can lead to an invalid state of the vector. Please " + "call Vector::compress(VectorOperation::add) or " + "Vector::zero_out_ghost_values() before calling a " + "vector space operation to avoid this problem.")); + } } diff --git a/include/deal.II/lac/matrix_block.h b/include/deal.II/lac/matrix_block.h index 1e4df4638d..e47367e7ec 100644 --- a/include/deal.II/lac/matrix_block.h +++ b/include/deal.II/lac/matrix_block.h @@ -716,7 +716,7 @@ MatrixBlock::add(const size_type b_row, // leave it at this. While it may // not be the most efficient way, // it is at least thread safe. - // #ifdef DEBUG + // if constexpr (running_in_debug_mode()){ Assert(bi.first == row, ExcBlockIndexMismatch(bi.first, row)); for (size_type j = 0; j < n_cols; ++j) @@ -727,7 +727,7 @@ MatrixBlock::add(const size_type b_row, matrix.add(bi.second, bj.second, values[j]); } - // #endif + // } } diff --git a/include/deal.II/lac/petsc_block_vector.h b/include/deal.II/lac/petsc_block_vector.h index 067cb79a80..7cb9a01e81 100644 --- a/include/deal.II/lac/petsc_block_vector.h +++ b/include/deal.II/lac/petsc_block_vector.h @@ -619,10 +619,12 @@ namespace PETScWrappers BlockVector::has_ghost_elements() const { bool ghosted = block(0).has_ghost_elements(); -# ifdef DEBUG - for (unsigned int i = 0; i < this->n_blocks(); ++i) - Assert(block(i).has_ghost_elements() == ghosted, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = 0; i < this->n_blocks(); ++i) + Assert(block(i).has_ghost_elements() == ghosted, + ExcInternalError()); + } return ghosted; } diff --git a/include/deal.II/lac/petsc_compatibility.h b/include/deal.II/lac/petsc_compatibility.h index c9e345ba99..e3fde7f83a 100644 --- a/include/deal.II/lac/petsc_compatibility.h +++ b/include/deal.II/lac/petsc_compatibility.h @@ -85,11 +85,14 @@ namespace PETScWrappers inline void close_matrix(Mat &matrix) { -# ifdef DEBUG - set_matrix_option(matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE); -# else - set_matrix_option(matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE); -# endif + if constexpr (running_in_debug_mode()) + { + set_matrix_option(matrix, MAT_NEW_NONZERO_LOCATION_ERR, PETSC_TRUE); + } + else + { + set_matrix_option(matrix, MAT_NEW_NONZERO_LOCATIONS, PETSC_FALSE); + } } diff --git a/include/deal.II/lac/relaxation_block.templates.h b/include/deal.II/lac/relaxation_block.templates.h index efcf92840d..b2752324ea 100644 --- a/include/deal.II/lac/relaxation_block.templates.h +++ b/include/deal.II/lac/relaxation_block.templates.h @@ -269,12 +269,13 @@ RelaxationBlock::do_step( } // Apply inverse diagonal this->inverse_vmult(block, x_cell, b_cell); -#ifdef DEBUG - for (unsigned int i = 0; i < x_cell.size(); ++i) + if constexpr (running_in_debug_mode()) { - AssertIsFinite(x_cell(i)); + for (unsigned int i = 0; i < x_cell.size(); ++i) + { + AssertIsFinite(x_cell(i)); + } } -#endif // Store in result vector row = additional_data->block_list.begin(block); for (size_type row_cell = 0; row_cell < bs; ++row_cell, ++row) diff --git a/include/deal.II/lac/sparse_matrix.templates.h b/include/deal.II/lac/sparse_matrix.templates.h index c32ccb0b7b..9a77659366 100644 --- a/include/deal.II/lac/sparse_matrix.templates.h +++ b/include/deal.II/lac/sparse_matrix.templates.h @@ -521,12 +521,13 @@ SparseMatrix::add(const size_type row, { // check whether the given indices are // really sorted -#ifdef DEBUG - for (size_type i = 1; i < n_cols; ++i) - Assert(col_indices[i] > col_indices[i - 1], - ExcMessage( - "List of indices is unsorted or contains duplicates.")); -#endif + if constexpr (running_in_debug_mode()) + { + for (size_type i = 1; i < n_cols; ++i) + Assert(col_indices[i] > col_indices[i - 1], + ExcMessage( + "List of indices is unsorted or contains duplicates.")); + } const size_type *this_cols = &cols->colnums[cols->rowstart[row]]; const size_type row_length_1 = cols->row_length(row) - 1; @@ -621,13 +622,16 @@ SparseMatrix::add(const size_type row, const number value = number(values[j]); AssertIsFinite(value); -#ifdef DEBUG - if (elide_zero_values == true && value == number()) - continue; -#else - if (value == number()) - continue; -#endif + if constexpr (running_in_debug_mode()) + { + if (elide_zero_values == true && value == number()) + continue; + } + else + { + if (value == number()) + continue; + } // check whether the next index to add is // the next present index in the sparsity @@ -1344,26 +1348,30 @@ namespace internal void AssertNoZerosOnDiagonal(const SparseMatrix &matrix) { -#ifdef DEBUG - for (typename SparseMatrix::size_type row = 0; row < matrix.m(); - ++row) - Assert(matrix.diag_element(row) != number(), - ExcMessage( - "There is a zero on the diagonal of this matrix " - "in row " + - std::to_string(row) + - ". The preconditioner you selected cannot work if that " - "is the case because one of its steps requires " - "division by the diagonal elements of the matrix." - "\n\n" - "You should check whether you have correctly " - "assembled the matrix that you use for this " - "preconditioner. If it is correct that there are " - "zeros on the diagonal, then you will have to chose " - "a different preconditioner.")); -#else - (void)matrix; -#endif + if constexpr (running_in_debug_mode()) + { + for (typename SparseMatrix::size_type row = 0; + row < matrix.m(); + ++row) + Assert(matrix.diag_element(row) != number(), + ExcMessage( + "There is a zero on the diagonal of this matrix " + "in row " + + std::to_string(row) + + ". The preconditioner you selected cannot work if that " + "is the case because one of its steps requires " + "division by the diagonal elements of the matrix." + "\n\n" + "You should check whether you have correctly " + "assembled the matrix that you use for this " + "preconditioner. If it is correct that there are " + "zeros on the diagonal, then you will have to chose " + "a different preconditioner.")); + } + else + { + (void)matrix; + } } } // namespace SparseMatrixImplementation } // namespace internal diff --git a/include/deal.II/lac/trilinos_parallel_block_vector.h b/include/deal.II/lac/trilinos_parallel_block_vector.h index 03344d0378..7ad20b421c 100644 --- a/include/deal.II/lac/trilinos_parallel_block_vector.h +++ b/include/deal.II/lac/trilinos_parallel_block_vector.h @@ -417,10 +417,12 @@ namespace TrilinosWrappers BlockVector::has_ghost_elements() const { bool ghosted = block(0).has_ghost_elements(); -# ifdef DEBUG - for (unsigned int i = 0; i < this->n_blocks(); ++i) - Assert(block(i).has_ghost_elements() == ghosted, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = 0; i < this->n_blocks(); ++i) + Assert(block(i).has_ghost_elements() == ghosted, + ExcInternalError()); + } return ghosted; } diff --git a/include/deal.II/lac/trilinos_tpetra_block_sparse_matrix.templates.h b/include/deal.II/lac/trilinos_tpetra_block_sparse_matrix.templates.h index c1a32f66b5..945513d70a 100644 --- a/include/deal.II/lac/trilinos_tpetra_block_sparse_matrix.templates.h +++ b/include/deal.II/lac/trilinos_tpetra_block_sparse_matrix.templates.h @@ -98,32 +98,33 @@ namespace LinearAlgebra const MPI_Comm communicator, const bool exchange_data) { -# ifdef DEBUG - std::vector> tpetra_maps; - for (size_type i = 0; i < block_sparsity_pattern.n_block_rows(); ++i) - tpetra_maps.push_back( - parallel_partitioning[i] - .template make_tpetra_map< - typename TpetraTypes::NodeType>(communicator, - false)); - - Assert(tpetra_maps.size() == block_sparsity_pattern.n_block_rows(), - ExcDimensionMismatch(tpetra_maps.size(), - block_sparsity_pattern.n_block_rows())); - Assert(tpetra_maps.size() == block_sparsity_pattern.n_block_cols(), - ExcDimensionMismatch(tpetra_maps.size(), - block_sparsity_pattern.n_block_cols())); - - const size_type n_block_rows = tpetra_maps.size(); - (void)n_block_rows; - - Assert(n_block_rows == block_sparsity_pattern.n_block_rows(), - ExcDimensionMismatch(n_block_rows, - block_sparsity_pattern.n_block_rows())); - Assert(n_block_rows == block_sparsity_pattern.n_block_cols(), - ExcDimensionMismatch(n_block_rows, - block_sparsity_pattern.n_block_cols())); -# endif + if constexpr (running_in_debug_mode()) + { + std::vector> tpetra_maps; + for (size_type i = 0; i < block_sparsity_pattern.n_block_rows(); ++i) + tpetra_maps.push_back( + parallel_partitioning[i] + .template make_tpetra_map< + typename TpetraTypes::NodeType>(communicator, + false)); + + Assert(tpetra_maps.size() == block_sparsity_pattern.n_block_rows(), + ExcDimensionMismatch(tpetra_maps.size(), + block_sparsity_pattern.n_block_rows())); + Assert(tpetra_maps.size() == block_sparsity_pattern.n_block_cols(), + ExcDimensionMismatch(tpetra_maps.size(), + block_sparsity_pattern.n_block_cols())); + + const size_type n_block_rows = tpetra_maps.size(); + (void)n_block_rows; + + Assert(n_block_rows == block_sparsity_pattern.n_block_rows(), + ExcDimensionMismatch(n_block_rows, + block_sparsity_pattern.n_block_rows())); + Assert(n_block_rows == block_sparsity_pattern.n_block_cols(), + ExcDimensionMismatch(n_block_rows, + block_sparsity_pattern.n_block_cols())); + } // Call the other basic reinit function, ... diff --git a/include/deal.II/lac/trilinos_tpetra_block_vector.templates.h b/include/deal.II/lac/trilinos_tpetra_block_vector.templates.h index 55448d33e8..f208e881dd 100644 --- a/include/deal.II/lac/trilinos_tpetra_block_vector.templates.h +++ b/include/deal.II/lac/trilinos_tpetra_block_vector.templates.h @@ -199,11 +199,12 @@ namespace LinearAlgebra BlockVector::has_ghost_elements() const { bool ghosted = this->block(0).has_ghost_elements(); -# ifdef DEBUG - for (unsigned int i = 0; i < this->n_blocks(); ++i) - Assert(this->block(i).has_ghost_elements() == ghosted, - ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = 0; i < this->n_blocks(); ++i) + Assert(this->block(i).has_ghost_elements() == ghosted, + ExcInternalError()); + } return ghosted; } diff --git a/include/deal.II/lac/trilinos_tpetra_sparse_matrix.templates.h b/include/deal.II/lac/trilinos_tpetra_sparse_matrix.templates.h index 5c21d55019..d382c19942 100644 --- a/include/deal.II/lac/trilinos_tpetra_sparse_matrix.templates.h +++ b/include/deal.II/lac/trilinos_tpetra_sparse_matrix.templates.h @@ -1602,15 +1602,18 @@ namespace LinearAlgebra { Assert(m() == n(), ExcNotQuadratic()); -# ifdef DEBUG - // use operator() in debug mode because it checks if this is a valid - // element (in parallel) - return operator()(i, i); -# else - // Trilinos doesn't seem to have a more efficient way to access the - // diagonal than by just using the standard el(i,j) function. - return el(i, i); -# endif + if constexpr (running_in_debug_mode()) + { + // use operator() in debug mode because it checks if this is a valid + // element (in parallel) + return operator()(i, i); + } + else + { + // Trilinos doesn't seem to have a more efficient way to access the + // diagonal than by just using the standard el(i,j) function. + return el(i, i); + } } } // namespace TpetraWrappers diff --git a/include/deal.II/lac/trilinos_tpetra_vector.templates.h b/include/deal.II/lac/trilinos_tpetra_vector.templates.h index 1d30fd4265..eb55f93aaa 100644 --- a/include/deal.II/lac/trilinos_tpetra_vector.templates.h +++ b/include/deal.II/lac/trilinos_tpetra_vector.templates.h @@ -168,13 +168,14 @@ namespace LinearAlgebra has_ghost = (vector->getMap()->isOneToOne() == false); -# ifdef DEBUG - MPI_Comm comm = Utilities::Trilinos::teuchos_comm_to_mpi_comm( - vector->getMap()->getComm()); - const size_type n_elements_global = - Utilities::MPI::sum(vector->getLocalLength(), comm); - Assert(has_ghost || n_elements_global == size(), ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + MPI_Comm comm = Utilities::Trilinos::teuchos_comm_to_mpi_comm( + vector->getMap()->getComm()); + const size_type n_elements_global = + Utilities::MPI::sum(vector->getLocalLength(), comm); + Assert(has_ghost || n_elements_global == size(), ExcInternalError()); + } } @@ -1070,20 +1071,21 @@ namespace LinearAlgebra const size_type begin = vector->getMap()->getMinGlobalIndex(); const size_type end = vector->getMap()->getMaxGlobalIndex() + 1; -# ifdef DEBUG - const size_type n_local_elements = -# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0) - vector->getMap()->getLocalNumElements(); -# else - vector->getMap()->getNodeNumElements(); -# endif - Assert( - end - begin == n_local_elements, - ExcMessage( - "This function only makes sense if the elements that this " - "vector stores on the current processor form a contiguous range. " - "This does not appear to be the case for the current vector.")); + if constexpr (running_in_debug_mode()) + { + const size_type n_local_elements = +# if DEAL_II_TRILINOS_VERSION_GTE(14, 0, 0) + vector->getMap()->getLocalNumElements(); +# else + vector->getMap()->getNodeNumElements(); # endif + Assert( + end - begin == n_local_elements, + ExcMessage( + "This function only makes sense if the elements that this " + "vector stores on the current processor form a contiguous range. " + "This does not appear to be the case for the current vector.")); + } return std::make_pair(begin, end); } diff --git a/include/deal.II/matrix_free/face_setup_internal.h b/include/deal.II/matrix_free/face_setup_internal.h index 8a61533105..4121592efd 100644 --- a/include/deal.II/matrix_free/face_setup_internal.h +++ b/include/deal.II/matrix_free/face_setup_internal.h @@ -172,16 +172,17 @@ namespace internal { use_active_cells = mg_level == numbers::invalid_unsigned_int; -# ifdef DEBUG - // safety check - if (use_active_cells) - for (const auto &cell_level : cell_levels) - { - typename dealii::Triangulation::cell_iterator dcell( - &triangulation, cell_level.first, cell_level.second); - Assert(dcell->is_active(), ExcInternalError()); - } -# endif + if constexpr (running_in_debug_mode()) + { + // safety check + if (use_active_cells) + for (const auto &cell_level : cell_levels) + { + typename dealii::Triangulation::cell_iterator dcell( + &triangulation, cell_level.first, cell_level.second); + Assert(dcell->is_active(), ExcInternalError()); + } + } // step 1: add ghost cells for those cells that we identify as // interesting @@ -544,22 +545,23 @@ namespace internal inner_face.second.shared_faces[i]); } -# ifdef DEBUG - // check consistency of faces on both sides - std::vector> check_faces; - check_faces.insert(check_faces.end(), - owned_faces_lower.begin(), - owned_faces_lower.end()); - check_faces.insert(check_faces.end(), - owned_faces_higher.begin(), - owned_faces_higher.end()); - std::sort(check_faces.begin(), check_faces.end()); - AssertDimension(check_faces.size(), - inner_face.second.shared_faces.size()); - for (unsigned int i = 0; i < check_faces.size(); ++i) - Assert(check_faces[i] == inner_face.second.shared_faces[i], - ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + // check consistency of faces on both sides + std::vector> check_faces; + check_faces.insert(check_faces.end(), + owned_faces_lower.begin(), + owned_faces_lower.end()); + check_faces.insert(check_faces.end(), + owned_faces_higher.begin(), + owned_faces_higher.end()); + std::sort(check_faces.begin(), check_faces.end()); + AssertDimension(check_faces.size(), + inner_face.second.shared_faces.size()); + for (unsigned int i = 0; i < check_faces.size(); ++i) + Assert(check_faces[i] == inner_face.second.shared_faces[i], + ExcInternalError()); + } // now only set half of the faces as the ones to keep if (my_domain < inner_face.first) @@ -1398,43 +1400,45 @@ namespace internal faces_type = std::move(new_faces_type); } -# ifdef DEBUG - // final safety checks - for (const auto &face_type : faces_type) - AssertDimension(face_type.size(), 0U); - - AssertDimension(faces_out.size(), face_partition_data.back()); - unsigned int nfaces = 0; - for (unsigned int i = face_partition_data[0]; - i < face_partition_data.back(); - ++i) - for (unsigned int v = 0; v < vectorization_width; ++v) - nfaces += - (faces_out[i].cells_interior[v] != numbers::invalid_unsigned_int); - AssertDimension(nfaces, faces_in.size()); - - std::vector> in_faces, out_faces; - for (const auto &face_in : faces_in) - in_faces.emplace_back(face_in.cells_interior[0], - face_in.cells_exterior[0]); - for (unsigned int i = face_partition_data[0]; - i < face_partition_data.back(); - ++i) - for (unsigned int v = 0; - v < vectorization_width && - faces_out[i].cells_interior[v] != numbers::invalid_unsigned_int; - ++v) - out_faces.emplace_back(faces_out[i].cells_interior[v], - faces_out[i].cells_exterior[v]); - std::sort(in_faces.begin(), in_faces.end()); - std::sort(out_faces.begin(), out_faces.end()); - AssertDimension(in_faces.size(), out_faces.size()); - for (unsigned int i = 0; i < in_faces.size(); ++i) + if constexpr (running_in_debug_mode()) { - AssertDimension(in_faces[i].first, out_faces[i].first); - AssertDimension(in_faces[i].second, out_faces[i].second); + // final safety checks + for (const auto &face_type : faces_type) + AssertDimension(face_type.size(), 0U); + + AssertDimension(faces_out.size(), face_partition_data.back()); + unsigned int nfaces = 0; + for (unsigned int i = face_partition_data[0]; + i < face_partition_data.back(); + ++i) + for (unsigned int v = 0; v < vectorization_width; ++v) + nfaces += (faces_out[i].cells_interior[v] != + numbers::invalid_unsigned_int); + AssertDimension(nfaces, faces_in.size()); + + std::vector> in_faces, + out_faces; + for (const auto &face_in : faces_in) + in_faces.emplace_back(face_in.cells_interior[0], + face_in.cells_exterior[0]); + for (unsigned int i = face_partition_data[0]; + i < face_partition_data.back(); + ++i) + for (unsigned int v = 0; + v < vectorization_width && faces_out[i].cells_interior[v] != + numbers::invalid_unsigned_int; + ++v) + out_faces.emplace_back(faces_out[i].cells_interior[v], + faces_out[i].cells_exterior[v]); + std::sort(in_faces.begin(), in_faces.end()); + std::sort(out_faces.begin(), out_faces.end()); + AssertDimension(in_faces.size(), out_faces.size()); + for (unsigned int i = 0; i < in_faces.size(); ++i) + { + AssertDimension(in_faces[i].first, out_faces[i].first); + AssertDimension(in_faces[i].second, out_faces[i].second); + } } -# endif } #endif // ifndef DOXYGEN diff --git a/include/deal.II/matrix_free/fe_evaluation.h b/include/deal.II/matrix_free/fe_evaluation.h index e4bf3389da..d819941a54 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -3923,9 +3923,10 @@ FEEvaluationBase:: apply_hanging_node_constraints(false); -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -3953,9 +3954,10 @@ FEEvaluationBase:: internal::VectorReader reader; read_write_operation(reader, src_data.first, src_data.second, mask, false); -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -3972,10 +3974,11 @@ FEEvaluationBase:: const unsigned int first_index, const std::bitset &mask) const { -# ifdef DEBUG - Assert(this->dof_values_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized == true, + internal::ExcAccessToUninitializedField()); + } apply_hanging_node_constraints(true); @@ -4006,10 +4009,11 @@ FEEvaluationBase:: const unsigned int first_index, const std::bitset &mask) const { -# ifdef DEBUG - Assert(this->dof_values_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized == true, + internal::ExcAccessToUninitializedField()); + } const auto dst_data = internal::get_vector_data( dst, @@ -4037,10 +4041,11 @@ FEEvaluationBase:: const unsigned int first_index, const std::bitset &mask) const { -# ifdef DEBUG - Assert(this->dof_values_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized == true, + internal::ExcAccessToUninitializedField()); + } const auto dst_data = internal::get_vector_data( dst, @@ -4103,10 +4108,11 @@ inline DEAL_II_ALWAYS_INLINE FEEvaluationBase:: get_value(const unsigned int q_point) const { -# ifdef DEBUG - Assert(this->values_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->values_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); if constexpr (n_components == 1) @@ -4118,10 +4124,11 @@ inline DEAL_II_ALWAYS_INLINE internal::MatrixFreeFunctions::ElementType::tensor_raviart_thomas) { // Piola transform is required -# ifdef DEBUG - Assert(this->values_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->values_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, @@ -4202,10 +4209,11 @@ inline DEAL_II_ALWAYS_INLINE FEEvaluationBase:: get_gradient(const unsigned int q_point) const { -# ifdef DEBUG - Assert(this->gradients_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->gradients_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->jacobian != nullptr, @@ -4219,10 +4227,11 @@ inline DEAL_II_ALWAYS_INLINE internal::MatrixFreeFunctions::ElementType::tensor_raviart_thomas) { // Piola transform is required -# ifdef DEBUG - Assert(this->gradients_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->gradients_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->jacobian != nullptr, @@ -4450,10 +4459,11 @@ inline DEAL_II_ALWAYS_INLINE get_normal_derivative(const unsigned int q_point) const { AssertIndexRange(q_point, this->n_quadrature_points); -# ifdef DEBUG - Assert(this->gradients_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->gradients_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } Assert(this->normal_x_jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -4555,10 +4565,11 @@ inline typename FEEvaluationBase:: get_hessian(const unsigned int q_point) const { -# ifdef DEBUG - Assert(this->hessians_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->hessians_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->jacobian != nullptr, @@ -4700,10 +4711,11 @@ FEEvaluationBase:: get_hessian_diagonal(const unsigned int q_point) const { Assert(!is_face, ExcNotImplemented()); -# ifdef DEBUG - Assert(this->hessians_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->hessians_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->jacobian != nullptr, ExcNotImplemented()); @@ -4797,10 +4809,11 @@ FEEvaluationBase:: get_laplacian(const unsigned int q_point) const { Assert(is_face == false, ExcNotImplemented()); -# ifdef DEBUG - Assert(this->hessians_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->hessians_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); const gradient_type hess_diag = get_hessian_diagonal(q_point); @@ -4839,10 +4852,11 @@ inline typename FEEvaluationBase:: get_normal_hessian(const unsigned int q_point) const { -# ifdef DEBUG - Assert(this->hessians_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->hessians_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->normal_x_jacobian != nullptr, @@ -4919,9 +4933,10 @@ inline DEAL_II_ALWAYS_INLINE void FEEvaluationBase:: submit_dof_value(const value_type val_in, const unsigned int dof) { -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } const std::size_t dofs = this->data->dofs_per_component_on_cell; AssertIndexRange(dof, this->data->dofs_per_component_on_cell); for (unsigned int comp = 0; comp < n_components; ++comp) @@ -4942,16 +4957,18 @@ inline DEAL_II_ALWAYS_INLINE void FEEvaluationBase:: submit_value(const value_type val_in, const unsigned int q_point) { -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_values")); -# ifdef DEBUG - this->values_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->values_quad_submitted = true; + } const std::size_t nqp = this->n_quadrature_points; VectorizedArrayType *values = this->values_quad + q_point; @@ -4973,10 +4990,11 @@ FEEvaluationBase:: Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_value")); -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); - this->values_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + this->values_quad_submitted = true; + } VectorizedArrayType *values = this->values_quad + q_point; const std::size_t nqp = this->n_quadrature_points; @@ -5061,9 +5079,10 @@ inline DEAL_II_ALWAYS_INLINE void FEEvaluationBase:: submit_gradient(const gradient_type grad_in, const unsigned int q_point) { -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5071,9 +5090,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_gradients")); -# ifdef DEBUG - this->gradients_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->gradients_quad_submitted = true; + } if constexpr (dim > 1 && n_components == dim) { @@ -5082,9 +5102,10 @@ FEEvaluationBase:: { // Piola transform is required -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5092,9 +5113,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_gradients")); -# ifdef DEBUG - this->gradients_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->gradients_quad_submitted = true; + } VectorizedArrayType *gradients = this->gradients_quad + q_point * dim; VectorizedArrayType *values = @@ -5348,9 +5370,10 @@ FEEvaluationBase:: Assert(this->normal_x_jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_gradients")); -# ifdef DEBUG - this->gradients_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->gradients_quad_submitted = true; + } const std::size_t nqp_d = this->n_quadrature_points * dim; VectorizedArrayType *gradients = this->gradients_quad + q_point * dim; @@ -5400,9 +5423,10 @@ inline DEAL_II_ALWAYS_INLINE void FEEvaluationBase:: submit_hessian(const hessian_type hessian_in, const unsigned int q_point) { -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5410,9 +5434,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_hessians")); -# ifdef DEBUG - this->hessians_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->hessians_quad_submitted = true; + } // compute hessian_unit = J^T * hessian_in(u) * J const std::size_t nqp = this->n_quadrature_points; @@ -5571,9 +5596,10 @@ FEEvaluationBase:: submit_normal_hessian(const value_type normal_hessian_in, const unsigned int q_point) { -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5581,9 +5607,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_hessians")); -# ifdef DEBUG - this->hessians_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->hessians_quad_submitted = true; + } // compute hessian_unit = J^T * hessian_in(u) * J const std::size_t nqp = this->n_quadrature_points; @@ -5656,11 +5683,12 @@ inline typename FEEvaluationBase:: integrate_value() const { -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); - Assert(this->values_quad_submitted == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + Assert(this->values_quad_submitted == true, + internal::ExcAccessToUninitializedField()); + } Tensor<1, n_components, VectorizedArrayType> return_value; const std::size_t nqp = this->n_quadrature_points; @@ -5689,10 +5717,11 @@ FEEvaluationBase:: "Do not try to modify the default template parameters used for" " selectively enabling this function via std::enable_if!"); -# ifdef DEBUG - Assert(this->gradients_quad_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->gradients_quad_initialized == true, + internal::ExcAccessToUninitializedField()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5855,9 +5884,10 @@ FEEvaluationBase:: "Do not try to modify the default template parameters used for" " selectively enabling this function via std::enable_if!"); -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5865,9 +5895,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_gradients")); -# ifdef DEBUG - this->gradients_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->gradients_quad_submitted = true; + } const std::size_t nqp_d = this->n_quadrature_points * dim; VectorizedArrayType *gradients = this->gradients_quad + q_point * dim; @@ -5960,9 +5991,10 @@ FEEvaluationBase:: // could have used base class operator, but that involves some overhead // which is inefficient. it is nice to have the symmetric tensor because // that saves some operations -# ifdef DEBUG - Assert(this->is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->is_reinitialized, ExcNotInitialized()); + } AssertIndexRange(q_point, this->n_quadrature_points); Assert(this->J_value != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( @@ -5970,9 +6002,10 @@ FEEvaluationBase:: Assert(this->jacobian != nullptr, internal::ExcMatrixFreeAccessToUninitializedMappingField( "update_gradients")); -# ifdef DEBUG - this->gradients_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->gradients_quad_submitted = true; + } const std::size_t nqp_d = this->n_quadrature_points * dim; VectorizedArrayType *gradients = this->gradients_quad + dim * q_point; @@ -6306,151 +6339,159 @@ FEEvaluation(fe_degree) != numbers::invalid_unsigned_int && - static_cast(fe_degree) != - this->data->data.front().fe_degree) || - n_q_points != this->n_quadrature_points) - { - std::string message = - "-------------------------------------------------------\n"; - message += "Illegal arguments in constructor/wrong template arguments!\n"; - message += " Called --> FEEvaluation(fe_degree) != + numbers::invalid_unsigned_int && + static_cast(fe_degree) != + this->data->data.front().fe_degree) || + n_q_points != this->n_quadrature_points) { - message += ", " + Utilities::int_to_string(dof_no) + ", "; - message += Utilities::int_to_string(this->quad_no) + ", "; - message += Utilities::int_to_string(first_selected_component); - } - message += ")\n"; + std::string message = + "-------------------------------------------------------\n"; + message += + "Illegal arguments in constructor/wrong template arguments!\n"; + message += " Called --> FEEvaluationquad_no) + ", "; + message += Utilities::int_to_string(first_selected_component); + } + message += ")\n"; - // check whether some other vector component has the correct number of - // points - unsigned int proposed_dof_comp = numbers::invalid_unsigned_int, - proposed_fe_comp = numbers::invalid_unsigned_int, - proposed_quad_comp = numbers::invalid_unsigned_int; - if (dof_no != numbers::invalid_unsigned_int) - { - if (static_cast(fe_degree) == - this->data->data.front().fe_degree) + // check whether some other vector component has the correct number of + // points + unsigned int proposed_dof_comp = numbers::invalid_unsigned_int, + proposed_fe_comp = numbers::invalid_unsigned_int, + proposed_quad_comp = numbers::invalid_unsigned_int; + if (dof_no != numbers::invalid_unsigned_int) { - proposed_dof_comp = dof_no; - proposed_fe_comp = first_selected_component; + if (static_cast(fe_degree) == + this->data->data.front().fe_degree) + { + proposed_dof_comp = dof_no; + proposed_fe_comp = first_selected_component; + } + else + for (unsigned int no = 0; + no < this->matrix_free->n_components(); + ++no) + for (unsigned int nf = 0; + nf < this->matrix_free->n_base_elements(no); + ++nf) + if (this->matrix_free + ->get_shape_info(no, 0, nf, this->active_fe_index, 0) + .data.front() + .fe_degree == static_cast(fe_degree)) + { + proposed_dof_comp = no; + proposed_fe_comp = nf; + break; + } + if (n_q_points == + this->mapping_data->descriptor[this->active_quad_index] + .n_q_points) + proposed_quad_comp = this->quad_no; + else + for (unsigned int no = 0; + no < + this->matrix_free->get_mapping_info().cell_data.size(); + ++no) + if (this->matrix_free->get_mapping_info() + .cell_data[no] + .descriptor[this->active_quad_index] + .n_q_points == n_q_points) + { + proposed_quad_comp = no; + break; + } } - else - for (unsigned int no = 0; no < this->matrix_free->n_components(); - ++no) - for (unsigned int nf = 0; - nf < this->matrix_free->n_base_elements(no); - ++nf) - if (this->matrix_free - ->get_shape_info(no, 0, nf, this->active_fe_index, 0) - .data.front() - .fe_degree == static_cast(fe_degree)) - { - proposed_dof_comp = no; - proposed_fe_comp = nf; - break; - } - if (n_q_points == - this->mapping_data->descriptor[this->active_quad_index] - .n_q_points) - proposed_quad_comp = this->quad_no; - else - for (unsigned int no = 0; - no < this->matrix_free->get_mapping_info().cell_data.size(); - ++no) - if (this->matrix_free->get_mapping_info() - .cell_data[no] - .descriptor[this->active_quad_index] - .n_q_points == n_q_points) + if (proposed_dof_comp != numbers::invalid_unsigned_int && + proposed_quad_comp != numbers::invalid_unsigned_int) + { + if (proposed_dof_comp != first_selected_component) + message += "Wrong vector component selection:\n"; + else + message += "Wrong quadrature formula selection:\n"; + message += " Did you mean FEEvaluationquad_no) + correct_pos += " ^ "; + else + correct_pos += " "; + if (proposed_fe_comp != first_selected_component) + correct_pos += " ^\n"; + else + correct_pos += " \n"; + message += + " " + + correct_pos; + } + // ok, did not find the numbers specified by the template arguments in + // the given list. Suggest correct template arguments + const unsigned int proposed_n_q_points_1d = static_cast( + std::pow(1.001 * this->n_quadrature_points, 1. / dim)); + message += "Wrong template arguments:\n"; message += " Did you mean FEEvaluationdata->data.front().fe_degree) + ","; + message += Utilities::int_to_string(proposed_n_q_points_1d); message += "," + Utilities::int_to_string(n_components); message += ",Number>(data"; if (dof_no != numbers::invalid_unsigned_int) { + message += ", " + Utilities::int_to_string(dof_no) + ", "; + message += Utilities::int_to_string(this->quad_no); message += - ", " + Utilities::int_to_string(proposed_dof_comp) + ", "; - message += Utilities::int_to_string(proposed_quad_comp) + ", "; - message += Utilities::int_to_string(proposed_fe_comp); + ", " + Utilities::int_to_string(first_selected_component); } message += ")?\n"; std::string correct_pos; - if (proposed_dof_comp != dof_no) - correct_pos = " ^ "; - else - correct_pos = " "; - if (proposed_quad_comp != this->quad_no) - correct_pos += " ^ "; + if (this->data->data.front().fe_degree != + static_cast(fe_degree)) + correct_pos = " ^"; else - correct_pos += " "; - if (proposed_fe_comp != first_selected_component) + correct_pos = " "; + if (proposed_n_q_points_1d != n_q_points_1d) correct_pos += " ^\n"; else correct_pos += " \n"; - message += " " + - correct_pos; + message += " " + correct_pos; + + Assert(static_cast(fe_degree) == + this->data->data.front().fe_degree && + n_q_points == this->n_quadrature_points, + ExcMessage(message)); } - // ok, did not find the numbers specified by the template arguments in - // the given list. Suggest correct template arguments - const unsigned int proposed_n_q_points_1d = static_cast( - std::pow(1.001 * this->n_quadrature_points, 1. / dim)); - message += "Wrong template arguments:\n"; - message += " Did you mean FEEvaluationdata->data.front().fe_degree) + ","; - message += Utilities::int_to_string(proposed_n_q_points_1d); - message += "," + Utilities::int_to_string(n_components); - message += ",Number>(data"; if (dof_no != numbers::invalid_unsigned_int) - { - message += ", " + Utilities::int_to_string(dof_no) + ", "; - message += Utilities::int_to_string(this->quad_no); - message += ", " + Utilities::int_to_string(first_selected_component); - } - message += ")?\n"; - std::string correct_pos; - if (this->data->data.front().fe_degree != - static_cast(fe_degree)) - correct_pos = " ^"; - else - correct_pos = " "; - if (proposed_n_q_points_1d != n_q_points_1d) - correct_pos += " ^\n"; - else - correct_pos += " \n"; - message += " " + correct_pos; - - Assert(static_cast(fe_degree) == - this->data->data.front().fe_degree && - n_q_points == this->n_quadrature_points, - ExcMessage(message)); - } - if (dof_no != numbers::invalid_unsigned_int) - AssertDimension( - n_q_points, - this->mapping_data->descriptor[this->active_quad_index].n_q_points); -# endif + AssertDimension( + n_q_points, + this->mapping_data->descriptor[this->active_quad_index].n_q_points); + } } @@ -6512,13 +6553,14 @@ FEEvaluationmapping_data->quadrature_points [this->mapping_data->quadrature_point_offsets[this->cell]]; -# ifdef DEBUG - this->is_reinitialized = true; - this->dof_values_initialized = false; - this->values_quad_initialized = false; - this->gradients_quad_initialized = false; - this->hessians_quad_initialized = false; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + this->dof_values_initialized = false; + this->values_quad_initialized = false; + this->gradients_quad_initialized = false; + this->hessians_quad_initialized = false; + } } @@ -6775,13 +6817,14 @@ FEEvaluationis_reinitialized = true; - this->dof_values_initialized = false; - this->values_quad_initialized = false; - this->gradients_quad_initialized = false; - this->hessians_quad_initialized = false; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + this->dof_values_initialized = false; + this->values_quad_initialized = false; + this->gradients_quad_initialized = false; + this->hessians_quad_initialized = false; + } } @@ -6816,9 +6859,10 @@ FEEvaluationget_dof_indices(this->local_dof_indices); -# ifdef DEBUG - this->is_reinitialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + } } @@ -6846,9 +6890,10 @@ FEEvaluationmapped_geometry.get() != 0, ExcNotInitialized()); this->mapped_geometry->reinit(cell); -# ifdef DEBUG - this->is_reinitialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + } } @@ -6868,10 +6913,11 @@ FEEvaluation:: evaluate(const EvaluationFlags::EvaluationFlags evaluation_flags) { -# ifdef DEBUG - Assert(this->dof_values_initialized == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized == true, + internal::ExcAccessToUninitializedField()); + } evaluate(this->values_dofs, evaluation_flags); } @@ -6923,14 +6969,15 @@ FEEvaluationvalues_quad_initialized = - evaluation_flag_actual & EvaluationFlags::values; - this->gradients_quad_initialized = - evaluation_flag_actual & EvaluationFlags::gradients; - this->hessians_quad_initialized = - evaluation_flag_actual & EvaluationFlags::hessians; -# endif + if constexpr (running_in_debug_mode()) + { + this->values_quad_initialized = + evaluation_flag_actual & EvaluationFlags::values; + this->gradients_quad_initialized = + evaluation_flag_actual & EvaluationFlags::gradients; + this->hessians_quad_initialized = + evaluation_flag_actual & EvaluationFlags::hessians; + } } @@ -7055,9 +7102,10 @@ FEEvaluationvalues_dofs); -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -7079,17 +7127,18 @@ FEEvaluationvalues_quad_submitted == true, - internal::ExcAccessToUninitializedField()); - if (integration_flag & EvaluationFlags::gradients) - Assert(this->gradients_quad_submitted == true, - internal::ExcAccessToUninitializedField()); - if ((integration_flag & EvaluationFlags::hessians) != 0u) - Assert(this->hessians_quad_submitted == true, - internal::ExcAccessToUninitializedField()); -# endif + if constexpr (running_in_debug_mode()) + { + if (integration_flag & EvaluationFlags::values) + Assert(this->values_quad_submitted == true, + internal::ExcAccessToUninitializedField()); + if (integration_flag & EvaluationFlags::gradients) + Assert(this->gradients_quad_submitted == true, + internal::ExcAccessToUninitializedField()); + if ((integration_flag & EvaluationFlags::hessians) != 0u) + Assert(this->hessians_quad_submitted == true, + internal::ExcAccessToUninitializedField()); + } Assert(this->matrix_free != nullptr || this->mapped_geometry->is_initialized(), ExcNotInitialized()); @@ -7158,9 +7207,10 @@ FEEvaluationdof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -7364,13 +7414,14 @@ FEFaceEvaluationmapping_data->quadrature_point_offsets[this->cell]; } -# ifdef DEBUG - this->is_reinitialized = true; - this->dof_values_initialized = false; - this->values_quad_initialized = false; - this->gradients_quad_initialized = false; - this->hessians_quad_initialized = false; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + this->dof_values_initialized = false; + this->values_quad_initialized = false; + this->gradients_quad_initialized = false; + this->hessians_quad_initialized = false; + } } @@ -7548,13 +7599,14 @@ FEFaceEvaluationis_reinitialized = true; - this->dof_values_initialized = false; - this->values_quad_initialized = false; - this->gradients_quad_initialized = false; - this->hessians_quad_initialized = false; -# endif + if constexpr (running_in_debug_mode()) + { + this->is_reinitialized = true; + this->dof_values_initialized = false; + this->values_quad_initialized = false; + this->gradients_quad_initialized = false; + this->hessians_quad_initialized = false; + } } @@ -7574,9 +7626,10 @@ FEFaceEvaluation:: evaluate(const EvaluationFlags::EvaluationFlags evaluation_flag) { -# ifdef DEBUG - Assert(this->dof_values_initialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized, ExcNotInitialized()); + } evaluate(this->values_dofs, evaluation_flag); } @@ -7628,14 +7681,15 @@ FEFaceEvaluation::evaluate( n_components, evaluation_flag_actual, values_array, *this); -# ifdef DEBUG - this->values_quad_initialized = - evaluation_flag_actual & EvaluationFlags::values; - this->gradients_quad_initialized = - evaluation_flag_actual & EvaluationFlags::gradients; - this->hessians_quad_initialized = - evaluation_flag_actual & EvaluationFlags::hessians; -# endif + if constexpr (running_in_debug_mode()) + { + this->values_quad_initialized = + evaluation_flag_actual & EvaluationFlags::values; + this->gradients_quad_initialized = + evaluation_flag_actual & EvaluationFlags::gradients; + this->hessians_quad_initialized = + evaluation_flag_actual & EvaluationFlags::hessians; + } } @@ -7655,9 +7709,10 @@ FEFaceEvaluation:: project_to_face(const EvaluationFlags::EvaluationFlags evaluation_flag) { -# ifdef DEBUG - Assert(this->dof_values_initialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(this->dof_values_initialized, ExcNotInitialized()); + } project_to_face(this->values_dofs, evaluation_flag); } @@ -7762,14 +7817,15 @@ FEFaceEvaluation:: evaluate_in_face(n_components, evaluation_flag_actual, *this); -# ifdef DEBUG - this->values_quad_initialized = - evaluation_flag_actual & EvaluationFlags::values; - this->gradients_quad_initialized = - evaluation_flag_actual & EvaluationFlags::gradients; - this->hessians_quad_initialized = - evaluation_flag_actual & EvaluationFlags::hessians; -# endif + if constexpr (running_in_debug_mode()) + { + this->values_quad_initialized = + evaluation_flag_actual & EvaluationFlags::values; + this->gradients_quad_initialized = + evaluation_flag_actual & EvaluationFlags::gradients; + this->hessians_quad_initialized = + evaluation_flag_actual & EvaluationFlags::hessians; + } } @@ -7792,9 +7848,10 @@ FEFaceEvaluationvalues_dofs, sum_into_values); -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -7970,9 +8027,10 @@ FEFaceEvaluationvalues_dofs, sum_into_values); -# ifdef DEBUG - this->dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + this->dof_values_initialized = true; + } } @@ -8109,12 +8167,14 @@ FEFaceEvaluationevaluate(evaluation_flag); } -# ifdef DEBUG - this->values_quad_initialized = evaluation_flag & EvaluationFlags::values; - this->gradients_quad_initialized = - evaluation_flag & EvaluationFlags::gradients; - this->hessians_quad_initialized = evaluation_flag & EvaluationFlags::hessians; -# endif + if constexpr (running_in_debug_mode()) + { + this->values_quad_initialized = evaluation_flag & EvaluationFlags::values; + this->gradients_quad_initialized = + evaluation_flag & EvaluationFlags::gradients; + this->hessians_quad_initialized = + evaluation_flag & EvaluationFlags::hessians; + } } diff --git a/include/deal.II/matrix_free/fe_evaluation_data.h b/include/deal.II/matrix_free/fe_evaluation_data.h index 7a54ba8c56..32061d07e0 100644 --- a/include/deal.II/matrix_free/fe_evaluation_data.h +++ b/include/deal.II/matrix_free/fe_evaluation_data.h @@ -497,10 +497,11 @@ public: const std::array & get_cell_ids() const { -// implemented inline to avoid compilation problems on Windows -#ifdef DEBUG - Assert(is_reinitialized, ExcNotInitialized()); -#endif + // implemented inline to avoid compilation problems on Windows + if constexpr (running_in_debug_mode()) + { + Assert(is_reinitialized, ExcNotInitialized()); + } return cell_ids; } @@ -511,10 +512,11 @@ public: const std::array & get_face_ids() const { -// implemented inline to avoid compilation problems on Windows -#ifdef DEBUG - Assert(is_reinitialized && is_face, ExcNotInitialized()); -#endif + // implemented inline to avoid compilation problems on Windows + if constexpr (running_in_debug_mode()) + { + Assert(is_reinitialized && is_face, ExcNotInitialized()); + } return face_ids; } @@ -525,10 +527,11 @@ public: unsigned int get_cell_or_face_batch_id() const { -// implemented inline to avoid compilation problems on Windows -#ifdef DEBUG - Assert(is_reinitialized, ExcNotInitialized()); -#endif + // implemented inline to avoid compilation problems on Windows + if constexpr (running_in_debug_mode()) + { + Assert(is_reinitialized, ExcNotInitialized()); + } return cell; } @@ -540,10 +543,11 @@ public: const std::array & get_cell_or_face_ids() const { -// implemented inline to avoid compilation problems on Windows -#ifdef DEBUG - Assert(is_reinitialized, ExcNotInitialized()); -#endif + // implemented inline to avoid compilation problems on Windows + if constexpr (running_in_debug_mode()) + { + Assert(is_reinitialized, ExcNotInitialized()); + } if (!is_face || dof_access_index == internal::MatrixFreeFunctions::DoFInfo::dof_access_cell) @@ -1158,15 +1162,16 @@ FEEvaluationData::operator=(const FEEvaluationData &other) quadrature_points = nullptr; quadrature_weights = other.quadrature_weights; -# ifdef DEBUG - is_reinitialized = false; - dof_values_initialized = false; - values_quad_initialized = false; - gradients_quad_initialized = false; - hessians_quad_initialized = false; - values_quad_submitted = false; - gradients_quad_submitted = false; -# endif + if constexpr (running_in_debug_mode()) + { + is_reinitialized = false; + dof_values_initialized = false; + values_quad_initialized = false; + gradients_quad_initialized = false; + hessians_quad_initialized = false; + values_quad_submitted = false; + gradients_quad_submitted = false; + } cell = numbers::invalid_unsigned_int; interior_face = other.is_interior_face(); @@ -1211,13 +1216,16 @@ FEEvaluationData::set_data_pointers( // include 12 extra fields to insert some padding between values, gradients // and hessians, which helps to reduce the probability of cache conflicts const unsigned int allocated_size = size_scratch_data + size_data_arrays + 12; -# ifdef DEBUG - scratch_data_array->clear(); - scratch_data_array->resize(allocated_size, - Number(numbers::signaling_nan())); -# else - scratch_data_array->resize_fast(allocated_size); -# endif + if constexpr (running_in_debug_mode()) + { + scratch_data_array->clear(); + scratch_data_array->resize( + allocated_size, Number(numbers::signaling_nan())); + } + else + { + scratch_data_array->resize_fast(allocated_size); + } scratch_data.reinit(scratch_data_array->begin() + size_data_arrays + 12, size_scratch_data); @@ -1386,9 +1394,10 @@ template inline Number * FEEvaluationData::begin_dof_values() { -# ifdef DEBUG - dof_values_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + dof_values_initialized = true; + } return values_dofs; } @@ -1398,9 +1407,11 @@ template inline const Number * FEEvaluationData::begin_values() const { -# ifdef DEBUG - Assert(values_quad_initialized || values_quad_submitted, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(values_quad_initialized || values_quad_submitted, + ExcNotInitialized()); + } return values_quad; } @@ -1410,10 +1421,11 @@ template inline Number * FEEvaluationData::begin_values() { -# ifdef DEBUG - values_quad_initialized = true; - values_quad_submitted = true; -# endif + if constexpr (running_in_debug_mode()) + { + values_quad_initialized = true; + values_quad_submitted = true; + } return values_quad; } @@ -1423,10 +1435,11 @@ template inline const Number * FEEvaluationData::begin_gradients() const { -# ifdef DEBUG - Assert(gradients_quad_initialized || gradients_quad_submitted, - ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(gradients_quad_initialized || gradients_quad_submitted, + ExcNotInitialized()); + } return gradients_quad; } @@ -1436,10 +1449,11 @@ template inline Number * FEEvaluationData::begin_gradients() { -# ifdef DEBUG - gradients_quad_submitted = true; - gradients_quad_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + gradients_quad_submitted = true; + gradients_quad_initialized = true; + } return gradients_quad; } @@ -1449,9 +1463,10 @@ template inline const Number * FEEvaluationData::begin_hessians() const { -# ifdef DEBUG - Assert(hessians_quad_initialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(hessians_quad_initialized, ExcNotInitialized()); + } return hessians_quad; } @@ -1461,9 +1476,10 @@ template inline Number * FEEvaluationData::begin_hessians() { -# ifdef DEBUG - hessians_quad_initialized = true; -# endif + if constexpr (running_in_debug_mode()) + { + hessians_quad_initialized = true; + } return hessians_quad; } @@ -1490,9 +1506,10 @@ template inline internal::MatrixFreeFunctions::GeometryType FEEvaluationData::get_cell_type() const { -# ifdef DEBUG - Assert(is_reinitialized, ExcNotInitialized()); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(is_reinitialized, ExcNotInitialized()); + } return cell_type; } diff --git a/include/deal.II/matrix_free/fe_point_evaluation.h b/include/deal.II/matrix_free/fe_point_evaluation.h index f2adf1800e..085293f646 100644 --- a/include/deal.II/matrix_free/fe_point_evaluation.h +++ b/include/deal.II/matrix_free/fe_point_evaluation.h @@ -2082,30 +2082,34 @@ FEPointEvaluationBase::do_reinit() mapping_info->compute_data_index_offset(geometry_index); const unsigned int compressed_data_offset = mapping_info->compute_compressed_data_index_offset(geometry_index); -#ifdef DEBUG - const UpdateFlags update_flags_mapping = - mapping_info->get_update_flags_mapping(); - if (update_flags_mapping & UpdateFlags::update_quadrature_points) - real_point_ptr = mapping_info->get_real_point(data_offset); - if (update_flags_mapping & UpdateFlags::update_jacobians) - jacobian_ptr = - mapping_info->get_jacobian(compressed_data_offset, is_interior); - if (update_flags_mapping & UpdateFlags::update_inverse_jacobians) - inverse_jacobian_ptr = - mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior); - if (update_flags_mapping & UpdateFlags::update_normal_vectors) - normal_ptr = mapping_info->get_normal_vector(data_offset); - if (update_flags_mapping & UpdateFlags::update_JxW_values) - JxW_ptr = mapping_info->get_JxW(data_offset); -#else - real_point_ptr = mapping_info->get_real_point(data_offset); - jacobian_ptr = - mapping_info->get_jacobian(compressed_data_offset, is_interior); - inverse_jacobian_ptr = - mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior); - normal_ptr = mapping_info->get_normal_vector(data_offset); - JxW_ptr = mapping_info->get_JxW(data_offset); -#endif + if constexpr (running_in_debug_mode()) + { + const UpdateFlags update_flags_mapping = + mapping_info->get_update_flags_mapping(); + if (update_flags_mapping & UpdateFlags::update_quadrature_points) + real_point_ptr = mapping_info->get_real_point(data_offset); + if (update_flags_mapping & UpdateFlags::update_jacobians) + jacobian_ptr = + mapping_info->get_jacobian(compressed_data_offset, is_interior); + if (update_flags_mapping & UpdateFlags::update_inverse_jacobians) + inverse_jacobian_ptr = + mapping_info->get_inverse_jacobian(compressed_data_offset, + is_interior); + if (update_flags_mapping & UpdateFlags::update_normal_vectors) + normal_ptr = mapping_info->get_normal_vector(data_offset); + if (update_flags_mapping & UpdateFlags::update_JxW_values) + JxW_ptr = mapping_info->get_JxW(data_offset); + } + else + { + real_point_ptr = mapping_info->get_real_point(data_offset); + jacobian_ptr = + mapping_info->get_jacobian(compressed_data_offset, is_interior); + inverse_jacobian_ptr = + mapping_info->get_inverse_jacobian(compressed_data_offset, is_interior); + normal_ptr = mapping_info->get_normal_vector(data_offset); + JxW_ptr = mapping_info->get_JxW(data_offset); + } if (!is_linear && fast_path) { diff --git a/include/deal.II/matrix_free/mapping_info.templates.h b/include/deal.II/matrix_free/mapping_info.templates.h index 6c508062a5..be4e8127d7 100644 --- a/include/deal.II/matrix_free/mapping_info.templates.h +++ b/include/deal.II/matrix_free/mapping_info.templates.h @@ -1253,26 +1253,29 @@ namespace internal const VectorizedDouble jac_det = determinant(jac); -#ifdef DEBUG - for (unsigned int v = 0; v < n_lanes_d; ++v) + if constexpr (running_in_debug_mode()) { - const typename Triangulation::cell_iterator - cell_iterator( - &tria, - cell_array[cell * n_lanes + vv + v].first, - cell_array[cell * n_lanes + vv + v].second); - - Assert(jac_det[v] > - 1e-12 * Utilities::fixed_power( - cell_iterator->diameter() / - std::sqrt(double(dim))), - (typename Mapping::ExcDistortedMappedCell( - cell_iterator->center(), jac_det[v], q))); + for (unsigned int v = 0; v < n_lanes_d; ++v) + { + const typename Triangulation::cell_iterator + cell_iterator( + &tria, + cell_array[cell * n_lanes + vv + v].first, + cell_array[cell * n_lanes + vv + v].second); + + Assert( + jac_det[v] > 1e-12 * Utilities::fixed_power( + cell_iterator->diameter() / + std::sqrt(double(dim))), + (typename Mapping::ExcDistortedMappedCell( + cell_iterator->center(), jac_det[v], q))); + } + } + else + { + (void)tria; + (void)cell_array; } -#else - (void)tria; - (void)cell_array; -#endif const Tensor<2, dim, VectorizedDouble> inv_jac = transpose(invert(jac)); @@ -2352,10 +2355,11 @@ namespace internal 1. : my_data.descriptor[0].quadrature.weight(q)); -#ifdef DEBUG - for (unsigned int v = 0; v < n_lanes_d; ++v) - Assert(JxW[v] > 0.0, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int v = 0; v < n_lanes_d; ++v) + Assert(JxW[v] > 0.0, ExcInternalError()); + } store_vectorized_array(JxW, vv, diff --git a/include/deal.II/matrix_free/matrix_free.templates.h b/include/deal.II/matrix_free/matrix_free.templates.h index f55e4e8bf0..c124c58491 100644 --- a/include/deal.II/matrix_free/matrix_free.templates.h +++ b/include/deal.II/matrix_free/matrix_free.templates.h @@ -117,15 +117,16 @@ MatrixFree::create_cell_subrange_hp_by_index( { // the range over which we are searching must be ordered, otherwise we // got a range that spans over too many cells -#ifdef DEBUG - for (unsigned int i = range.first + 1; i < range.second; ++i) - Assert( - fe_indices[i] >= fe_indices[i - 1], - ExcMessage( - "Cell range must be over sorted range of FE indices in hp-case!")); - AssertIndexRange(range.first, fe_indices.size() + 1); - AssertIndexRange(range.second, fe_indices.size() + 1); -#endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = range.first + 1; i < range.second; ++i) + Assert( + fe_indices[i] >= fe_indices[i - 1], + ExcMessage( + "Cell range must be over sorted range of FE indices in hp-case!")); + AssertIndexRange(range.first, fe_indices.size() + 1); + AssertIndexRange(range.second, fe_indices.size() + 1); + } std::pair return_range; return_range.first = std::lower_bound(fe_indices.begin() + range.first, fe_indices.begin() + range.second, @@ -468,15 +469,16 @@ MatrixFree::internal_reinit( task_info.n_procs = Utilities::MPI::n_mpi_processes(task_info.communicator); -#ifdef DEBUG - for (const auto &constraint : constraints) - Assert( - constraint->is_closed(task_info.communicator), - ExcMessage( - "You have provided a non-empty AffineConstraints object that has not " - "been closed. Please call AffineConstraints::close() before " - "calling MatrixFree::reinit()!")); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &constraint : constraints) + Assert( + constraint->is_closed(task_info.communicator), + ExcMessage( + "You have provided a non-empty AffineConstraints object that has not " + "been closed. Please call AffineConstraints::close() before " + "calling MatrixFree::reinit()!")); + } initialize_dof_handlers(dof_handler, additional_data); for (unsigned int no = 0; no < dof_handler.size(); ++no) @@ -1799,40 +1801,44 @@ namespace internal irregular_cells.back() = task_info.n_ghost_cells % n_lanes; } -#ifdef DEBUG - { - unsigned int n_cells = 0; - for (unsigned int i = 0; i < task_info.cell_partition_data.back(); - ++i) - n_cells += irregular_cells[i] > 0 ? irregular_cells[i] : n_lanes; - AssertDimension(n_cells, task_info.n_active_cells); - n_cells = 0; - for (unsigned int i = task_info.cell_partition_data.back(); - i < n_ghost_slots + task_info.cell_partition_data.back(); - ++i) - n_cells += irregular_cells[i] > 0 ? irregular_cells[i] : n_lanes; - AssertDimension(n_cells, task_info.n_ghost_cells); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + unsigned int n_cells = 0; + for (unsigned int i = 0; i < task_info.cell_partition_data.back(); + ++i) + n_cells += + irregular_cells[i] > 0 ? irregular_cells[i] : n_lanes; + AssertDimension(n_cells, task_info.n_active_cells); + n_cells = 0; + for (unsigned int i = task_info.cell_partition_data.back(); + i < n_ghost_slots + task_info.cell_partition_data.back(); + ++i) + n_cells += + irregular_cells[i] > 0 ? irregular_cells[i] : n_lanes; + AssertDimension(n_cells, task_info.n_ghost_cells); + } + } task_info.cell_partition_data.push_back( task_info.cell_partition_data.back() + n_ghost_slots); } - // Finally perform the renumbering. We also want to group several cells - // together to a batch of cells for SIMD (vectorized) execution (where the - // arithmetic operations of several cells will then be done - // simultaneously). -#ifdef DEBUG - { - AssertDimension(renumbering.size(), - task_info.n_active_cells + task_info.n_ghost_cells); - std::vector sorted_renumbering(renumbering); - std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); - for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) - Assert(sorted_renumbering[i] == i, ExcInternalError()); - } -#endif + // Finally perform the renumbering. We also want to group several cells + // together to a batch of cells for SIMD (vectorized) execution (where the + // arithmetic operations of several cells will then be done + // simultaneously). + if constexpr (running_in_debug_mode()) + { + { + AssertDimension(renumbering.size(), + task_info.n_active_cells + task_info.n_ghost_cells); + std::vector sorted_renumbering(renumbering); + std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); + for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) + Assert(sorted_renumbering[i] == i, ExcInternalError()); + } + } { std::vector> cell_level_index_old; cell_level_index.swap(cell_level_index_old); diff --git a/include/deal.II/matrix_free/operators.h b/include/deal.II/matrix_free/operators.h index 7e2a209646..72f8836638 100644 --- a/include/deal.II/matrix_free/operators.h +++ b/include/deal.II/matrix_free/operators.h @@ -1973,13 +1973,14 @@ namespace MatrixFreeOperators for (unsigned int i = 0; i < inverse_diagonal_vector.locally_owned_size(); ++i) { -#ifdef DEBUG - // only define the type alias in debug mode to avoid a warning - using Number = - typename Base::value_type; - Assert(diagonal_vector.local_element(i) > Number(0), - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // only define the type alias in debug mode to avoid a warning + using Number = + typename Base::value_type; + Assert(diagonal_vector.local_element(i) > Number(0), + ExcInternalError()); + } inverse_diagonal_vector.local_element(i) = 1. / inverse_diagonal_vector.local_element(i); } diff --git a/include/deal.II/matrix_free/vector_access_internal.h b/include/deal.II/matrix_free/vector_access_internal.h index b156b25a2b..f32dc00521 100644 --- a/include/deal.II/matrix_free/vector_access_internal.h +++ b/include/deal.II/matrix_free/vector_access_internal.h @@ -24,9 +24,7 @@ #include #include -#ifdef DEBUG -# include -#endif +#include DEAL_II_NAMESPACE_OPEN @@ -207,64 +205,68 @@ namespace internal (void)matrix_free; (void)dof_info; -#ifdef DEBUG - if (vec.partitioners_are_compatible(*dof_info.vector_partitioner) == false) + if constexpr (running_in_debug_mode()) { - unsigned int dof_index = numbers::invalid_unsigned_int; - - for (unsigned int i = 0; i < matrix_free.n_components(); ++i) - if (&matrix_free.get_dof_info(i) == &dof_info) - { - dof_index = i; - break; - } - - Assert(dof_index != numbers::invalid_unsigned_int, ExcInternalError()); - - std::vector dof_indices_with_compatible_partitioners; - - for (unsigned int i = 0; i < matrix_free.n_components(); ++i) - if (vec.partitioners_are_compatible( - *matrix_free.get_dof_info(i).vector_partitioner)) - dof_indices_with_compatible_partitioners.push_back( - std::to_string(i)); - - if (dof_indices_with_compatible_partitioners.empty()) + if (vec.partitioners_are_compatible(*dof_info.vector_partitioner) == + false) { - Assert(false, - ExcMessage("The parallel layout of the given vector is " - "compatible neither with the Partitioner of the " - "current FEEvaluation with dof_handler_index=" + - std::to_string(dof_index) + - " nor with any Partitioner in MatrixFree. A " - "potential reason is that you did not use " - "MatrixFree::initialize_dof_vector() to get a " - "compatible vector.")); - } - else - { - Assert( - false, - ExcMessage( - "The parallel layout of the given vector is " - "not compatible with the Partitioner of the " - "current FEEvaluation with dof_handler_index=" + - std::to_string(dof_index) + - ". However, the underlying " - "MatrixFree contains Partitioner objects that are compatible. " - "They have the following dof_handler_index values: " + - boost::algorithm::join(dof_indices_with_compatible_partitioners, - ", ") + - ". Did you want to pass any of these values to the " - "constructor of the current FEEvaluation object or " - "did you not use MatrixFree::initialize_dof_vector() " - "with dof_handler_index=" + - std::to_string(dof_index) + - " to get a " - "compatible vector?")); + unsigned int dof_index = numbers::invalid_unsigned_int; + + for (unsigned int i = 0; i < matrix_free.n_components(); ++i) + if (&matrix_free.get_dof_info(i) == &dof_info) + { + dof_index = i; + break; + } + + Assert(dof_index != numbers::invalid_unsigned_int, + ExcInternalError()); + + std::vector dof_indices_with_compatible_partitioners; + + for (unsigned int i = 0; i < matrix_free.n_components(); ++i) + if (vec.partitioners_are_compatible( + *matrix_free.get_dof_info(i).vector_partitioner)) + dof_indices_with_compatible_partitioners.push_back( + std::to_string(i)); + + if (dof_indices_with_compatible_partitioners.empty()) + { + Assert(false, + ExcMessage( + "The parallel layout of the given vector is " + "compatible neither with the Partitioner of the " + "current FEEvaluation with dof_handler_index=" + + std::to_string(dof_index) + + " nor with any Partitioner in MatrixFree. A " + "potential reason is that you did not use " + "MatrixFree::initialize_dof_vector() to get a " + "compatible vector.")); + } + else + { + Assert( + false, + ExcMessage( + "The parallel layout of the given vector is " + "not compatible with the Partitioner of the " + "current FEEvaluation with dof_handler_index=" + + std::to_string(dof_index) + + ". However, the underlying " + "MatrixFree contains Partitioner objects that are compatible. " + "They have the following dof_handler_index values: " + + boost::algorithm::join( + dof_indices_with_compatible_partitioners, ", ") + + ". Did you want to pass any of these values to the " + "constructor of the current FEEvaluation object or " + "did you not use MatrixFree::initialize_dof_vector() " + "with dof_handler_index=" + + std::to_string(dof_index) + + " to get a " + "compatible vector?")); + } } } -#endif } @@ -306,17 +308,23 @@ namespace internal VectorizedArrayType *dof_values, std::bool_constant) const { -#ifdef DEBUG - // in debug mode, run non-vectorized version because this path - // has additional checks (e.g., regarding ghosting) - process_dofs_vectorized( - dofs_per_cell, dof_index, vec, dof_values, std::bool_constant()); -#else - const Number *vec_ptr = vec.begin() + dof_index; - for (unsigned int i = 0; i < dofs_per_cell; - ++i, vec_ptr += VectorizedArrayType::size()) - dof_values[i].load(vec_ptr); -#endif + if constexpr (running_in_debug_mode()) + { + // in debug mode, run non-vectorized version because this path + // has additional checks (e.g., regarding ghosting) + process_dofs_vectorized(dofs_per_cell, + dof_index, + vec, + dof_values, + std::bool_constant()); + } + else + { + const Number *vec_ptr = vec.begin() + dof_index; + for (unsigned int i = 0; i < dofs_per_cell; + ++i, vec_ptr += VectorizedArrayType::size()) + dof_values[i].load(vec_ptr); + } } @@ -441,19 +449,22 @@ namespace internal (void)constant_offset; (void)vec; -#ifdef DEBUG - // in debug mode, run non-vectorized version because this path - // has additional checks (e.g., regarding ghosting) - Assert(vec_ptr == vec.begin() + constant_offset, ExcInternalError()); - process_dof_gather(indices, - vec, - constant_offset, - vec_ptr, - res, - std::bool_constant()); -#else - res.gather(vec_ptr, indices); -#endif + if constexpr (running_in_debug_mode()) + { + // in debug mode, run non-vectorized version because this path + // has additional checks (e.g., regarding ghosting) + Assert(vec_ptr == vec.begin() + constant_offset, ExcInternalError()); + process_dof_gather(indices, + vec, + constant_offset, + vec_ptr, + res, + std::bool_constant()); + } + else + { + res.gather(vec_ptr, indices); + } } diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h index 8c7c1c6e58..786148df41 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h @@ -2345,19 +2345,20 @@ namespace internal fe.n_dofs_per_vertex() > 0; }); -#ifdef DEBUG - const bool fine_element_is_discontinuous = - std::all_of(dof_handler_fine.get_fe_collection().begin(), - dof_handler_fine.get_fe_collection().end(), - [](const auto &fe) { - return fe.n_dofs_per_cell() == 0 || - fe.n_dofs_per_vertex() == 0; - }); + if constexpr (running_in_debug_mode()) + { + const bool fine_element_is_discontinuous = + std::all_of(dof_handler_fine.get_fe_collection().begin(), + dof_handler_fine.get_fe_collection().end(), + [](const auto &fe) { + return fe.n_dofs_per_cell() == 0 || + fe.n_dofs_per_vertex() == 0; + }); - Assert(transfer.fine_element_is_continuous != - fine_element_is_discontinuous, - ExcNotImplemented()); -#endif + Assert(transfer.fine_element_is_continuous != + fine_element_is_discontinuous, + ExcNotImplemented()); + } const bool is_feq = std::all_of(dof_handler_fine.get_fe_collection().begin(), dof_handler_fine.get_fe_collection().end(), diff --git a/include/deal.II/numerics/cell_data_transfer.templates.h b/include/deal.II/numerics/cell_data_transfer.templates.h index 2ac1eba6a0..fa16d56fbe 100644 --- a/include/deal.II/numerics/cell_data_transfer.templates.h +++ b/include/deal.II/numerics/cell_data_transfer.templates.h @@ -127,11 +127,14 @@ CellDataTransfer:: } } -#ifdef DEBUG - n_active_cells_pre = triangulation->n_active_cells(); -#else - (void)n_active_cells_pre; -#endif + if constexpr (running_in_debug_mode()) + { + n_active_cells_pre = triangulation->n_active_cells(); + } + else + { + (void)n_active_cells_pre; + } } @@ -141,14 +144,17 @@ void CellDataTransfer::unpack(const VectorType &in, VectorType &out) { -#ifdef DEBUG - Assert(in.size() == n_active_cells_pre, - ExcDimensionMismatch(in.size(), n_active_cells_pre)); - Assert(out.size() == triangulation->n_active_cells(), - ExcDimensionMismatch(out.size(), triangulation->n_active_cells())); -#else - (void)n_active_cells_pre; -#endif + if constexpr (running_in_debug_mode()) + { + Assert(in.size() == n_active_cells_pre, + ExcDimensionMismatch(in.size(), n_active_cells_pre)); + Assert(out.size() == triangulation->n_active_cells(), + ExcDimensionMismatch(out.size(), triangulation->n_active_cells())); + } + else + { + (void)n_active_cells_pre; + } // Transfer data of persisting cells. for (const auto &persisting : persisting_cells_active_index) diff --git a/include/deal.II/numerics/matrix_creator.templates.h b/include/deal.II/numerics/matrix_creator.templates.h index 5a67ba86a8..4fbb7b289f 100644 --- a/include/deal.II/numerics/matrix_creator.templates.h +++ b/include/deal.II/numerics/matrix_creator.templates.h @@ -1725,31 +1725,35 @@ namespace MatrixCreator copy_data.cell->face(face)->boundary_id()) != boundary_functions.end()) { -#ifdef DEBUG - // in debug mode: compute an element in the matrix which is - // guaranteed to belong to a boundary dof. We do this to check - // that the entries in the cell matrix are guaranteed to be zero - // if the respective dof is not on the boundary. Since because of - // round-off, the actual value of the matrix entry may be - // only close to zero, we assert that it is small relative to an - // element which is guaranteed to be nonzero. (absolute smallness - // does not suffice since the size of the domain scales in here) - // - // for this purpose we seek the diagonal of the matrix, where - // there must be an element belonging to the boundary. we take the - // maximum diagonal entry. - types::global_dof_index max_element = 0; - for (const auto index : dof_to_boundary_mapping) - if ((index != numbers::invalid_dof_index) && - (index > max_element)) - max_element = index; - Assert(max_element == matrix.n() - 1, ExcInternalError()); - - double max_diag_entry = 0; - for (unsigned int i = 0; i < copy_data.dofs_per_cell; ++i) - if (std::abs(copy_data.cell_matrix[pos](i, i)) > max_diag_entry) - max_diag_entry = std::abs(copy_data.cell_matrix[pos](i, i)); -#endif + if constexpr (running_in_debug_mode()) + { + // in debug mode: compute an element in the matrix which is + // guaranteed to belong to a boundary dof. We do this to check + // that the entries in the cell matrix are guaranteed to be + // zero if the respective dof is not on the boundary. Since + // because of round-off, the actual value of the matrix entry + // may be only close to zero, we assert that it is small + // relative to an element which is guaranteed to be nonzero. + // (absolute smallness does not suffice since the size of the + // domain scales in here) + // + // for this purpose we seek the diagonal of the matrix, where + // there must be an element belonging to the boundary. we take + // the maximum diagonal entry. + types::global_dof_index max_element = 0; + for (const auto index : dof_to_boundary_mapping) + if ((index != numbers::invalid_dof_index) && + (index > max_element)) + max_element = index; + Assert(max_element == matrix.n() - 1, ExcInternalError()); + + double max_diag_entry = 0; + for (unsigned int i = 0; i < copy_data.dofs_per_cell; ++i) + if (std::abs(copy_data.cell_matrix[pos](i, i)) > + max_diag_entry) + max_diag_entry = + std::abs(copy_data.cell_matrix[pos](i, i)); + } for (unsigned int i = 0; i < copy_data.dofs_per_cell; ++i) { diff --git a/include/deal.II/numerics/vector_tools_boundary.templates.h b/include/deal.II/numerics/vector_tools_boundary.templates.h index 78cbdcf978..51d73f1869 100644 --- a/include/deal.II/numerics/vector_tools_boundary.templates.h +++ b/include/deal.II/numerics/vector_tools_boundary.templates.h @@ -775,30 +775,31 @@ namespace VectorTools // but it needs to be implemented if (dim >= 3) { -#ifdef DEBUG - // Assert that there are no hanging nodes at the boundary - int level = -1; - for (const auto &cell : dof.active_cell_iterators()) - for (auto f : cell->face_indices()) - { - if (cell->at_boundary(f)) + if constexpr (running_in_debug_mode()) + { + // Assert that there are no hanging nodes at the boundary + int level = -1; + for (const auto &cell : dof.active_cell_iterators()) + for (auto f : cell->face_indices()) { - if (level == -1) - level = cell->level(); - else + if (cell->at_boundary(f)) { - Assert( - level == cell->level(), - ExcMessage( - "The mesh you use in projecting boundary values " - "has hanging nodes at the boundary. This would require " - "dealing with hanging node constraints when solving " - "the linear system on the boundary, but this is not " - "currently implemented.")); + if (level == -1) + level = cell->level(); + else + { + Assert( + level == cell->level(), + ExcMessage( + "The mesh you use in projecting boundary values " + "has hanging nodes at the boundary. This would require " + "dealing with hanging node constraints when solving " + "the linear system on the boundary, but this is not " + "currently implemented.")); + } } } - } -#endif + } } sparsity.compress(); diff --git a/include/deal.II/numerics/vector_tools_integrate_difference.templates.h b/include/deal.II/numerics/vector_tools_integrate_difference.templates.h index aa7ab85083..53543aad41 100644 --- a/include/deal.II/numerics/vector_tools_integrate_difference.templates.h +++ b/include/deal.II/numerics/vector_tools_integrate_difference.templates.h @@ -653,21 +653,22 @@ namespace VectorTools { Assert(cellwise_error.size() == tria.n_active_cells(), ExcMessage("input vector cell_error has invalid size!")); -#ifdef DEBUG - { - // check that off-processor entries are zero. Otherwise we will compute - // wrong results below! - typename InVector::size_type i = 0; - typename Triangulation::active_cell_iterator it = - tria.begin_active(); - for (; i < cellwise_error.size(); ++i, ++it) - if (!it->is_locally_owned()) - Assert( - std::fabs(cellwise_error[i]) < 1e-20, - ExcMessage( - "cellwise_error of cells that are not locally owned need to be zero!")); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + // check that off-processor entries are zero. Otherwise we will + // compute wrong results below! + typename InVector::size_type i = 0; + typename Triangulation::active_cell_iterator it = + tria.begin_active(); + for (; i < cellwise_error.size(); ++i, ++it) + if (!it->is_locally_owned()) + Assert( + std::fabs(cellwise_error[i]) < 1e-20, + ExcMessage( + "cellwise_error of cells that are not locally owned need to be zero!")); + } + } const MPI_Comm comm = tria.get_mpi_communicator(); diff --git a/include/deal.II/numerics/vector_tools_interpolate.templates.h b/include/deal.II/numerics/vector_tools_interpolate.templates.h index 30a47571bb..c7bffc2ac6 100644 --- a/include/deal.II/numerics/vector_tools_interpolate.templates.h +++ b/include/deal.II/numerics/vector_tools_interpolate.templates.h @@ -444,22 +444,23 @@ namespace VectorTools if (selected) { -#ifdef DEBUG - // make sure that all selected base elements are indeed - // interpolatory - - if (const auto fe_system = - dynamic_cast *>(&fe[fe_index])) + if constexpr (running_in_debug_mode()) { - const auto index = - fe_system->system_to_base_index(i).first.first; - Assert(fe_system->base_element(index) - .has_generalized_support_points(), - ExcMessage("The component mask supplied to " - "VectorTools::interpolate selects a " - "non-interpolatory element.")); + // make sure that all selected base elements are indeed + // interpolatory + + if (const auto fe_system = + dynamic_cast *>(&fe[fe_index])) + { + const auto index = + fe_system->system_to_base_index(i).first.first; + Assert(fe_system->base_element(index) + .has_generalized_support_points(), + ExcMessage("The component mask supplied to " + "VectorTools::interpolate selects a " + "non-interpolatory element.")); + } } -#endif // Add local values to the global vectors if (needs_expensive_algorithm[fe_index]) diff --git a/include/deal.II/numerics/vector_tools_project.templates.h b/include/deal.II/numerics/vector_tools_project.templates.h index 5c7c2f4cb0..d457c692b4 100644 --- a/include/deal.II/numerics/vector_tools_project.templates.h +++ b/include/deal.II/numerics/vector_tools_project.templates.h @@ -311,12 +311,13 @@ namespace VectorTools const DiagonalMatrix &preconditioner = use_lumped ? *mass_matrix.get_matrix_lumped_diagonal_inverse() : *mass_matrix.get_matrix_diagonal_inverse(); -#ifdef DEBUG - // Make sure we picked a valid preconditioner - const auto &diagonal = preconditioner.get_vector(); - for (const Number &v : diagonal) - Assert(v > 0.0, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // Make sure we picked a valid preconditioner + const auto &diagonal = preconditioner.get_vector(); + for (const Number &v : diagonal) + Assert(v > 0.0, ExcInternalError()); + } cg.solve(mass_matrix, work_result, rhs, preconditioner); work_result += inhomogeneities; diff --git a/source/base/data_out_base.cc b/source/base/data_out_base.cc index a69a601b36..bb00ca0f46 100644 --- a/source/base/data_out_base.cc +++ b/source/base/data_out_base.cc @@ -8057,11 +8057,12 @@ DataOutInterface::create_xdmf_entry( Assert(patches.size() > 0, DataOutBase::ExcNoPatches()); // We currently don't support writing mixed meshes: -# ifdef DEBUG - for (const auto &patch : patches) - Assert(patch.reference_cell == patches[0].reference_cell, - ExcNotImplemented()); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &patch : patches) + Assert(patch.reference_cell == patches[0].reference_cell, + ExcNotImplemented()); + } XDMFEntry entry(h5_mesh_filename, h5_solution_filename, @@ -9060,52 +9061,54 @@ template void DataOutInterface::validate_dataset_names() const { -#ifdef DEBUG - { - // Check that names for datasets are only used once. This is somewhat - // complicated, because vector ranges might have a name or not. - std::set all_names; - - const std::vector< - std::tuple> - ranges = this->get_nonscalar_data_ranges(); - const std::vector data_names = this->get_dataset_names(); - const unsigned int n_data_sets = data_names.size(); - std::vector data_set_written(n_data_sets, false); - - for (const auto &range : ranges) + if constexpr (running_in_debug_mode()) + { { - const std::string &name = std::get<2>(range); - if (!name.empty()) + // Check that names for datasets are only used once. This is somewhat + // complicated, because vector ranges might have a name or not. + std::set all_names; + + const std::vector< + std::tuple> + ranges = this->get_nonscalar_data_ranges(); + const std::vector data_names = this->get_dataset_names(); + const unsigned int n_data_sets = data_names.size(); + std::vector data_set_written(n_data_sets, false); + + for (const auto &range : ranges) { - Assert(all_names.find(name) == all_names.end(), - ExcMessage( - "Error: names of fields in DataOut need to be unique, " - "but '" + - name + "' is used more than once.")); - all_names.insert(name); - for (unsigned int i = std::get<0>(range); i <= std::get<1>(range); - ++i) - data_set_written[i] = true; + const std::string &name = std::get<2>(range); + if (!name.empty()) + { + Assert(all_names.find(name) == all_names.end(), + ExcMessage( + "Error: names of fields in DataOut need to be unique, " + "but '" + + name + "' is used more than once.")); + all_names.insert(name); + for (unsigned int i = std::get<0>(range); + i <= std::get<1>(range); + ++i) + data_set_written[i] = true; + } } - } - for (unsigned int data_set = 0; data_set < n_data_sets; ++data_set) - if (data_set_written[data_set] == false) - { - const std::string &name = data_names[data_set]; - Assert(all_names.find(name) == all_names.end(), - ExcMessage( - "Error: names of fields in DataOut need to be unique, " - "but '" + - name + "' is used more than once.")); - all_names.insert(name); - } - } -#endif + for (unsigned int data_set = 0; data_set < n_data_sets; ++data_set) + if (data_set_written[data_set] == false) + { + const std::string &name = data_names[data_set]; + Assert(all_names.find(name) == all_names.end(), + ExcMessage( + "Error: names of fields in DataOut need to be unique, " + "but '" + + name + "' is used more than once.")); + all_names.insert(name); + } + } + } } diff --git a/source/base/enable_observer_pointer.cc b/source/base/enable_observer_pointer.cc index d0abe6e6dc..d29d95ec3f 100644 --- a/source/base/enable_observer_pointer.cc +++ b/source/base/enable_observer_pointer.cc @@ -58,60 +58,60 @@ EnableObserverPointer::check_no_subscribers() const noexcept // derived class. Note that the name may be mangled, so it need not be the // clear-text class name. However, you can obtain the latter by running the // c++filt program over the output. -#ifdef DEBUG - - // If there are still active pointers, show a message and kill the program. - // However, under some circumstances, this is not so desirable. For example, - // in code like this: - // - // Triangulation tria; - // DoFHandler *dh = new DoFHandler(tria); - // ...some function that throws an exception - // - // the exception will lead to the destruction of the triangulation, but since - // the dof_handler is on the heap it will not be destroyed. This will trigger - // an assertion in the triangulation. If we kill the program at this point, we - // will never be able to learn what caused the problem. In this situation, - // just display a message and continue the program. - if (counter != 0) + if constexpr (running_in_debug_mode()) { - if (std::uncaught_exceptions() == 0) + // If there are still active pointers, show a message and kill the + // program. However, under some circumstances, this is not so desirable. + // For example, in code like this: + // + // Triangulation tria; + // DoFHandler *dh = new DoFHandler(tria); + // ...some function that throws an exception + // + // the exception will lead to the destruction of the triangulation, but + // since the dof_handler is on the heap it will not be destroyed. This + // will trigger an assertion in the triangulation. If we kill the program + // at this point, we will never be able to learn what caused the problem. + // In this situation, just display a message and continue the program. + if (counter != 0) { - std::string infostring; - for (const auto &map_entry : counter_map) + if (std::uncaught_exceptions() == 0) { - if (map_entry.second > 0) - infostring += - "\n from Subscriber " + std::string(map_entry.first); + std::string infostring; + for (const auto &map_entry : counter_map) + { + if (map_entry.second > 0) + infostring += + "\n from Subscriber " + std::string(map_entry.first); + } + + if (infostring.empty()) + infostring = ""; + + AssertNothrow(counter == 0, + ExcInUse(counter.load(), + object_info->name(), + infostring)); + } + else + { + std::cerr + << "---------------------------------------------------------" + << std::endl + << "An object pointed to by a ObserverPointer is being destroyed." + << std::endl + << "Under normal circumstances, this would abort the program." + << std::endl + << "However, another exception is being processed at the" + << std::endl + << "moment, so the program will continue to run to allow" + << std::endl + << "this exception to be processed." << std::endl + << "---------------------------------------------------------" + << std::endl; } - - if (infostring.empty()) - infostring = ""; - - AssertNothrow(counter == 0, - ExcInUse(counter.load(), - object_info->name(), - infostring)); - } - else - { - std::cerr - << "---------------------------------------------------------" - << std::endl - << "An object pointed to by a ObserverPointer is being destroyed." - << std::endl - << "Under normal circumstances, this would abort the program." - << std::endl - << "However, another exception is being processed at the" - << std::endl - << "moment, so the program will continue to run to allow" - << std::endl - << "this exception to be processed." << std::endl - << "---------------------------------------------------------" - << std::endl; } } -#endif } diff --git a/source/base/index_set.cc b/source/base/index_set.cc index a82db34640..ee1dbaec15 100644 --- a/source/base/index_set.cc +++ b/source/base/index_set.cc @@ -202,22 +202,24 @@ IndexSet::do_compress() const Assert(next_index == n_elements(), ExcInternalError()); } -#ifdef DEBUG - // A consistency check: We should only ever have added indices - // that are within the range of the index set. Instead of doing - // this in every one of the many functions that add indices, - // do this in the current, central location - for (const auto &range : ranges) - Assert((range.begin < index_space_size) && (range.end <= index_space_size), - ExcMessage("In the process of creating the current IndexSet " - "object, you added indices beyond the size of the index " - "space. Specifically, you added elements that form the " - "range [" + - std::to_string(range.begin) + "," + - std::to_string(range.end) + - "), but the size of the index space is only " + - std::to_string(index_space_size) + ".")); -#endif + if constexpr (running_in_debug_mode()) + { + // A consistency check: We should only ever have added indices + // that are within the range of the index set. Instead of doing + // this in every one of the many functions that add indices, + // do this in the current, central location + for (const auto &range : ranges) + Assert((range.begin < index_space_size) && + (range.end <= index_space_size), + ExcMessage( + "In the process of creating the current IndexSet " + "object, you added indices beyond the size of the index " + "space. Specifically, you added elements that form the " + "range [" + + std::to_string(range.begin) + "," + std::to_string(range.end) + + "), but the size of the index space is only " + + std::to_string(index_space_size) + ".")); + } } @@ -457,14 +459,15 @@ IndexSet::split_by_block( start += n_block_indices; } -#ifdef DEBUG - types::global_dof_index sum = 0; - for (const auto &partition : partitioned) + if constexpr (running_in_debug_mode()) { - sum += partition.size(); + types::global_dof_index sum = 0; + for (const auto &partition : partitioned) + { + sum += partition.size(); + } + AssertDimension(sum, this->size()); } - AssertDimension(sum, this->size()); -#endif return partitioned; } @@ -972,29 +975,30 @@ IndexSet::make_tpetra_map_rcp(const MPI_Comm communicator, compress(); (void)communicator; -# ifdef DEBUG - if (!overlapping) + if constexpr (running_in_debug_mode()) { - const size_type n_global_elements = - Utilities::MPI::sum(n_elements(), communicator); - Assert(n_global_elements == size(), - ExcMessage("You are trying to create an Tpetra::Map object " - "that partitions elements of an index set " - "between processors. However, the union of the " - "index sets on different processors does not " - "contain all indices exactly once: the sum of " - "the number of entries the various processors " - "want to store locally is " + - std::to_string(n_global_elements) + - " whereas the total size of the object to be " - "allocated is " + - std::to_string(size()) + - ". In other words, there are " - "either indices that are not spoken for " - "by any processor, or there are indices that are " - "claimed by multiple processors.")); + if (!overlapping) + { + const size_type n_global_elements = + Utilities::MPI::sum(n_elements(), communicator); + Assert(n_global_elements == size(), + ExcMessage("You are trying to create an Tpetra::Map object " + "that partitions elements of an index set " + "between processors. However, the union of the " + "index sets on different processors does not " + "contain all indices exactly once: the sum of " + "the number of entries the various processors " + "want to store locally is " + + std::to_string(n_global_elements) + + " whereas the total size of the object to be " + "allocated is " + + std::to_string(size()) + + ". In other words, there are " + "either indices that are not spoken for " + "by any processor, or there are indices that are " + "claimed by multiple processors.")); + } } -# endif // Find out if the IndexSet is ascending and 1:1. This corresponds to a // linear Tpetra::Map. Overlapping IndexSets are never 1:1. @@ -1046,29 +1050,30 @@ IndexSet::make_trilinos_map(const MPI_Comm communicator, compress(); (void)communicator; -# ifdef DEBUG - if (!overlapping) + if constexpr (running_in_debug_mode()) { - const size_type n_global_elements = - Utilities::MPI::sum(n_elements(), communicator); - Assert(n_global_elements == size(), - ExcMessage("You are trying to create an Epetra_Map object " - "that partitions elements of an index set " - "between processors. However, the union of the " - "index sets on different processors does not " - "contain all indices exactly once: the sum of " - "the number of entries the various processors " - "want to store locally is " + - std::to_string(n_global_elements) + - " whereas the total size of the object to be " - "allocated is " + - std::to_string(size()) + - ". In other words, there are " - "either indices that are not spoken for " - "by any processor, or there are indices that are " - "claimed by multiple processors.")); + if (!overlapping) + { + const size_type n_global_elements = + Utilities::MPI::sum(n_elements(), communicator); + Assert(n_global_elements == size(), + ExcMessage("You are trying to create an Epetra_Map object " + "that partitions elements of an index set " + "between processors. However, the union of the " + "index sets on different processors does not " + "contain all indices exactly once: the sum of " + "the number of entries the various processors " + "want to store locally is " + + std::to_string(n_global_elements) + + " whereas the total size of the object to be " + "allocated is " + + std::to_string(size()) + + ". In other words, there are " + "either indices that are not spoken for " + "by any processor, or there are indices that are " + "claimed by multiple processors.")); + } } -# endif // Find out if the IndexSet is ascending and 1:1. This corresponds to a // linear EpetraMap. Overlapping IndexSets are never 1:1. diff --git a/source/base/mpi.cc b/source/base/mpi.cc index 894c8456e6..1e59d6a607 100644 --- a/source/base/mpi.cc +++ b/source/base/mpi.cc @@ -218,13 +218,14 @@ namespace Utilities ierr = MPI_Type_commit(&result); AssertThrowMPI(ierr); -# ifdef DEBUG - MPI_Count size64; - ierr = MPI_Type_size_x(result, &size64); - AssertThrowMPI(ierr); + if constexpr (running_in_debug_mode()) + { + MPI_Count size64; + ierr = MPI_Type_size_x(result, &size64); + AssertThrowMPI(ierr); - Assert(size64 == static_cast(n_bytes), ExcInternalError()); -# endif + Assert(size64 == static_cast(n_bytes), ExcInternalError()); + } // Now put the new data type into a std::unique_ptr with a custom // deleter. We call the std::unique_ptr constructor that as first @@ -260,10 +261,11 @@ namespace Utilities const unsigned int myid = Utilities::MPI::this_mpi_process(mpi_comm); const unsigned int n_procs = Utilities::MPI::n_mpi_processes(mpi_comm); -# ifdef DEBUG - for (const unsigned int destination : destinations) - AssertIndexRange(destination, n_procs); -# endif + if constexpr (running_in_debug_mode()) + { + for (const unsigned int destination : destinations) + AssertIndexRange(destination, n_procs); + } // Have a little function that checks if destinations provided // to the current process are unique. The way it does this is @@ -395,15 +397,17 @@ namespace Utilities const unsigned int n_procs = Utilities::MPI::n_mpi_processes(mpi_comm); -# ifdef DEBUG - for (const unsigned int destination : destinations) + if constexpr (running_in_debug_mode()) { - AssertIndexRange(destination, n_procs); - Assert(destination != Utilities::MPI::this_mpi_process(mpi_comm), - ExcMessage( - "There is no point in communicating with ourselves.")); + for (const unsigned int destination : destinations) + { + AssertIndexRange(destination, n_procs); + Assert( + destination != Utilities::MPI::this_mpi_process(mpi_comm), + ExcMessage( + "There is no point in communicating with ourselves.")); + } } -# endif // Calculate the number of messages to send to each process std::vector dest_vector(n_procs); @@ -1137,12 +1141,17 @@ namespace Utilities // this function in release mode to avoid touching data // unnecessarily (and overwrite the smaller pieces), as the // locally owned part comes first -#ifdef DEBUG - data.resize(size, invalid_index_value); - std::fill(data.begin() + start, data.begin() + end, value); -#else - data.resize(size, value); -#endif + if constexpr (running_in_debug_mode()) + { + data.resize(size, invalid_index_value); + std::fill(data.begin() + start, + data.begin() + end, + value); + } + else + { + data.resize(size, value); + } } else { @@ -1249,14 +1258,15 @@ namespace Utilities Assert(next_index > index_range.first, ExcInternalError()); -#ifdef DEBUG - // make sure that the owner is the same on the current - // interval - for (types::global_dof_index i = index_range.first + 1; - i < next_index; - ++i) - AssertDimension(owner, dof_to_dict_rank(i)); -#endif + if constexpr (running_in_debug_mode()) + { + // make sure that the owner is the same on the current + // interval + for (types::global_dof_index i = index_range.first + 1; + i < next_index; + ++i) + AssertDimension(owner, dof_to_dict_rank(i)); + } // add the interval, either to the local range or into a // buffer to be sent to another processor @@ -1348,20 +1358,22 @@ namespace Utilities // process message: loop over all intervals for (auto interval : buffer) { -# ifdef DEBUG - for (types::global_dof_index i = interval.first; - i < interval.second; - i++) - Assert(actually_owning_ranks.entry_has_been_set( - i - local_range.first) == false, - ExcInternalError()); - Assert(interval.first >= local_range.first && - interval.first < local_range.second, - ExcInternalError()); - Assert(interval.second > local_range.first && - interval.second <= local_range.second, - ExcInternalError()); -# endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + for (types::global_dof_index i = interval.first; + i < interval.second; + i++) + Assert(actually_owning_ranks.entry_has_been_set( + i - local_range.first) == false, + ExcInternalError()); + Assert(interval.first >= local_range.first && + interval.first < local_range.second, + ExcInternalError()); + Assert(interval.second > local_range.first && + interval.second <= local_range.second, + ExcInternalError()); + } actually_owning_ranks.fill(interval.first - local_range.first, @@ -1405,25 +1417,27 @@ namespace Utilities // process message: loop over all intervals for (auto interval : request) { -# ifdef DEBUG - for (types::global_dof_index i = interval.first; - i < interval.second; - i++) - Assert( - actually_owning_ranks.entry_has_been_set( - i - local_range.first) == false, - ExcMessage( - "Multiple processes seem to own the same global index. " - "A possible reason is that the sets of locally owned " - "indices are not distinct.")); - Assert(interval.first < interval.second, - ExcInternalError()); - Assert( - local_range.first <= interval.first && - interval.second <= local_range.second, - ExcMessage( - "The specified interval is not handled by the current process.")); -# endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + for (types::global_dof_index i = interval.first; + i < interval.second; + i++) + Assert( + actually_owning_ranks.entry_has_been_set( + i - local_range.first) == false, + ExcMessage( + "Multiple processes seem to own the same global index. " + "A possible reason is that the sets of locally owned " + "indices are not distinct.")); + Assert(interval.first < interval.second, + ExcInternalError()); + Assert( + local_range.first <= interval.first && + interval.second <= local_range.second, + ExcMessage( + "The specified interval is not handled by the current process.")); + } actually_owning_ranks.fill(interval.first - local_range.first, interval.second - @@ -1758,17 +1772,18 @@ namespace Utilities } -# ifdef DEBUG - for (const auto &it : requested_indices) + if constexpr (running_in_debug_mode()) { - IndexSet copy_set = it.second; - copy_set.subtract_set(owned_indices); - Assert(copy_set.n_elements() == 0, - ExcInternalError( - "The indices requested from the current " - "MPI rank should be locally owned here!")); + for (const auto &it : requested_indices) + { + IndexSet copy_set = it.second; + copy_set.subtract_set(owned_indices); + Assert(copy_set.n_elements() == 0, + ExcInternalError( + "The indices requested from the current " + "MPI rank should be locally owned here!")); + } } -# endif #endif // DEAL_II_WITH_MPI diff --git a/source/base/partitioner.cc b/source/base/partitioner.cc index 1dd1fcb597..d7135e62d4 100644 --- a/source/base/partitioner.cc +++ b/source/base/partitioner.cc @@ -321,55 +321,58 @@ namespace Utilities local_range_data.first); } -# ifdef DEBUG - - // simple check: the number of processors to which we want to send - // ghosts and the processors to which ghosts reference should be the - // same - AssertDimension( - Utilities::MPI::sum(import_targets_data.size(), communicator), - Utilities::MPI::sum(ghost_targets_data.size(), communicator)); - - // simple check: the number of indices to exchange should match from the - // ghost indices side and the import indices side - AssertDimension(Utilities::MPI::sum(n_import_indices_data, communicator), - Utilities::MPI::sum(n_ghost_indices_data, communicator)); - - // expensive check that the communication channel is sane -> do a ghost - // exchange step and see whether the ghost indices sent to us by other - // processes (ghost_indices) are the same as we hold locally - // (ghost_indices_ref). - const std::vector ghost_indices_ref = - ghost_indices_data.get_index_vector(); - AssertDimension(ghost_indices_ref.size(), n_ghost_indices()); - std::vector indices_to_send(n_import_indices()); - std::vector ghost_indices(n_ghost_indices()); - - const std::vector my_indices = - locally_owned_range_data.get_index_vector(); - std::vector requests; - n_ghost_indices_in_larger_set = n_ghost_indices_data; - export_to_ghosted_array_start(127, - ArrayView( - my_indices.data(), my_indices.size()), - make_array_view(indices_to_send), - make_array_view(ghost_indices), - requests); - export_to_ghosted_array_finish(make_array_view(ghost_indices), requests); - int flag = 0; - const int ierr = MPI_Testall(requests.size(), - requests.data(), - &flag, - MPI_STATUSES_IGNORE); - AssertThrowMPI(ierr); - Assert(flag == 1, - ExcMessage( - "MPI found unfinished requests. Check communication setup")); - - for (unsigned int i = 0; i < ghost_indices.size(); ++i) - AssertDimension(ghost_indices[i], ghost_indices_ref[i]); + if constexpr (running_in_debug_mode()) + { + // simple check: the number of processors to which we want to send + // ghosts and the processors to which ghosts reference should be the + // same + AssertDimension( + Utilities::MPI::sum(import_targets_data.size(), communicator), + Utilities::MPI::sum(ghost_targets_data.size(), communicator)); + + // simple check: the number of indices to exchange should match from + // the ghost indices side and the import indices side + AssertDimension( + Utilities::MPI::sum(n_import_indices_data, communicator), + Utilities::MPI::sum(n_ghost_indices_data, communicator)); + + // expensive check that the communication channel is sane -> do a + // ghost exchange step and see whether the ghost indices sent to us by + // other processes (ghost_indices) are the same as we hold locally + // (ghost_indices_ref). + const std::vector ghost_indices_ref = + ghost_indices_data.get_index_vector(); + AssertDimension(ghost_indices_ref.size(), n_ghost_indices()); + std::vector indices_to_send( + n_import_indices()); + std::vector ghost_indices(n_ghost_indices()); + + const std::vector my_indices = + locally_owned_range_data.get_index_vector(); + std::vector requests; + n_ghost_indices_in_larger_set = n_ghost_indices_data; + export_to_ghosted_array_start( + 127, + ArrayView(my_indices.data(), + my_indices.size()), + make_array_view(indices_to_send), + make_array_view(ghost_indices), + requests); + export_to_ghosted_array_finish(make_array_view(ghost_indices), + requests); + int flag = 0; + const int ierr = MPI_Testall(requests.size(), + requests.data(), + &flag, + MPI_STATUSES_IGNORE); + AssertThrowMPI(ierr); + Assert(flag == 1, + ExcMessage( + "MPI found unfinished requests. Check communication setup")); -# endif + for (unsigned int i = 0; i < ghost_indices.size(); ++i) + AssertDimension(ghost_indices[i], ghost_indices_ref[i]); + } # endif // #ifdef DEAL_II_WITH_MPI diff --git a/source/base/process_grid.cc b/source/base/process_grid.cc index 050c5ade7e..09979c8633 100644 --- a/source/base/process_grid.cc +++ b/source/base/process_grid.cc @@ -195,12 +195,13 @@ namespace Utilities AssertThrowMPI(ierr); // Double check that the process with rank 0 in subgroup is active: -# ifdef DEBUG - if (mpi_communicator_inactive_with_root != MPI_COMM_NULL && - Utilities::MPI::this_mpi_process( - mpi_communicator_inactive_with_root) == 0) - Assert(mpi_process_is_active, ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + if (mpi_communicator_inactive_with_root != MPI_COMM_NULL && + Utilities::MPI::this_mpi_process( + mpi_communicator_inactive_with_root) == 0) + Assert(mpi_process_is_active, ExcInternalError()); + } } diff --git a/source/base/quadrature.cc b/source/base/quadrature.cc index 461fcedc76..6dccc8e3e2 100644 --- a/source/base/quadrature.cc +++ b/source/base/quadrature.cc @@ -186,17 +186,18 @@ Quadrature::Quadrature(const SubQuadrature &q1, const Quadrature<1> &q2) ++present_index; } -#ifdef DEBUG - if (size() > 0) + if constexpr (running_in_debug_mode()) { - double sum = 0; - for (unsigned int i = 0; i < size(); ++i) - sum += weights[i]; - // we cannot guarantee the sum of weights to be exactly one, but it should - // be near that. - Assert((sum > 0.999999) && (sum < 1.000001), ExcInternalError()); + if (size() > 0) + { + double sum = 0; + for (unsigned int i = 0; i < size(); ++i) + sum += weights[i]; + // we cannot guarantee the sum of weights to be exactly one, but it + // should be near that. + Assert((sum > 0.999999) && (sum < 1.000001), ExcInternalError()); + } } -#endif if (is_tensor_product_flag) { @@ -227,17 +228,18 @@ Quadrature<1>::Quadrature(const SubQuadrature &, const Quadrature<1> &q2) ++present_index; } -# ifdef DEBUG - if (size() > 0) + if constexpr (running_in_debug_mode()) { - double sum = 0; - for (unsigned int i = 0; i < size(); ++i) - sum += weights[i]; - // we cannot guarantee the sum of weights to be exactly one, but it should - // be near that. - Assert((sum > 0.999999) && (sum < 1.000001), ExcInternalError()); + if (size() > 0) + { + double sum = 0; + for (unsigned int i = 0; i < size(); ++i) + sum += weights[i]; + // we cannot guarantee the sum of weights to be exactly one, but it + // should be near that. + Assert((sum > 0.999999) && (sum < 1.000001), ExcInternalError()); + } } -# endif } @@ -623,12 +625,13 @@ QIterated<1>::QIterated(const Quadrature<1> &base_quadrature, else if (std::abs(i[0] - 1.0) < 1e-12) i[0] = 1.0; -#ifdef DEBUG - double sum_of_weights = 0; - for (unsigned int i = 0; i < this->size(); ++i) - sum_of_weights += this->weight(i); - Assert(std::fabs(sum_of_weights - 1) < 1e-13, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + double sum_of_weights = 0; + for (unsigned int i = 0; i < this->size(); ++i) + sum_of_weights += this->weight(i); + Assert(std::fabs(sum_of_weights - 1) < 1e-13, ExcInternalError()); + } } diff --git a/source/base/table_handler.cc b/source/base/table_handler.cc index 9392ee363e..c395c5cff2 100644 --- a/source/base/table_handler.cc +++ b/source/base/table_handler.cc @@ -753,13 +753,16 @@ TableHandler::n_rows() const std::map::const_iterator col_iter = columns.begin(); unsigned int n = col_iter->second.entries.size(); -#ifdef DEBUG - std::string first_name = col_iter->first; - for (++col_iter; col_iter != columns.end(); ++col_iter) - Assert(col_iter->second.entries.size() == n, - ExcWrongNumberOfDataEntries( - col_iter->first, col_iter->second.entries.size(), first_name, n)); -#endif + if constexpr (running_in_debug_mode()) + { + std::string first_name = col_iter->first; + for (++col_iter; col_iter != columns.end(); ++col_iter) + Assert(col_iter->second.entries.size() == n, + ExcWrongNumberOfDataEntries(col_iter->first, + col_iter->second.entries.size(), + first_name, + n)); + } return n; } diff --git a/source/base/tensor_product_polynomials.cc b/source/base/tensor_product_polynomials.cc index a83d08f3b8..0c265759bd 100644 --- a/source/base/tensor_product_polynomials.cc +++ b/source/base/tensor_product_polynomials.cc @@ -710,12 +710,13 @@ AnisotropicPolynomials::compute_index( } else { -#ifdef DEBUG - unsigned int n_poly = 1; - for (unsigned int d = 0; d < dim; ++d) - n_poly *= polynomials[d].size(); - Assert(i < n_poly, ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + unsigned int n_poly = 1; + for (unsigned int d = 0; d < dim; ++d) + n_poly *= polynomials[d].size(); + Assert(i < n_poly, ExcInternalError()); + } if (dim == 0) { diff --git a/source/differentiation/sd/symengine_optimizer.cc b/source/differentiation/sd/symengine_optimizer.cc index 8d1e67f8cb..1f94de6285 100644 --- a/source/differentiation/sd/symengine_optimizer.cc +++ b/source/differentiation/sd/symengine_optimizer.cc @@ -169,16 +169,17 @@ namespace Differentiation ExcMessage( "Cannot register symbols once the optimizer is finalized.")); -# ifdef DEBUG - // Ensure that all of the keys in the map are actually symbolic - // in nature - for (const auto &entry : substitution_map) + if constexpr (running_in_debug_mode()) { - const SD::Expression &symbol = entry.first; - Assert(SymEngine::is_a(*(symbol.get_RCP())), - ExcMessage("Key entry in map is not a symbol.")); + // Ensure that all of the keys in the map are actually symbolic + // in nature + for (const auto &entry : substitution_map) + { + const SD::Expression &symbol = entry.first; + Assert(SymEngine::is_a(*(symbol.get_RCP())), + ExcMessage("Key entry in map is not a symbol.")); + } } -# endif // Merge the two maps, in the process ensuring that there is no // duplication of symbols independent_variables_symbols.insert(substitution_map.begin(), @@ -403,21 +404,24 @@ namespace Differentiation // Check that the registered symbol map and the input map are compatible // with one another -# ifdef DEBUG - const SD::types::symbol_vector symbol_sub_vec = - Utilities::extract_symbols(substitution_map); - const SD::types::symbol_vector symbol_vec = - Utilities::extract_symbols(independent_variables_symbols); - Assert(symbol_sub_vec.size() == symbol_vec.size(), - ExcDimensionMismatch(symbol_sub_vec.size(), symbol_vec.size())); - for (unsigned int i = 0; i < symbol_sub_vec.size(); ++i) + if constexpr (running_in_debug_mode()) { - Assert(numbers::values_are_equal(symbol_sub_vec[i], symbol_vec[i]), - ExcMessage( - "The input substitution map is either incomplete, or does " - "not match that used in the register_symbols() call.")); + const SD::types::symbol_vector symbol_sub_vec = + Utilities::extract_symbols(substitution_map); + const SD::types::symbol_vector symbol_vec = + Utilities::extract_symbols(independent_variables_symbols); + Assert(symbol_sub_vec.size() == symbol_vec.size(), + ExcDimensionMismatch(symbol_sub_vec.size(), + symbol_vec.size())); + for (unsigned int i = 0; i < symbol_sub_vec.size(); ++i) + { + Assert( + numbers::values_are_equal(symbol_sub_vec[i], symbol_vec[i]), + ExcMessage( + "The input substitution map is either incomplete, or does " + "not match that used in the register_symbols() call.")); + } } -# endif // Extract the values from the substitution map, and use the other // function @@ -733,12 +737,13 @@ namespace Differentiation dependent_variables_output.reserve(n_dependent_variables() + 1); const bool entry_registered = (map_dep_expr_vec_entry.find(func) != map_dep_expr_vec_entry.end()); -# ifdef DEBUG - if (entry_registered == true && - is_valid_nonunique_dependent_variable(func) == false) - Assert(entry_registered, - ExcMessage("Function has already been registered.")); -# endif + if constexpr (running_in_debug_mode()) + { + if (entry_registered == true && + is_valid_nonunique_dependent_variable(func) == false) + Assert(entry_registered, + ExcMessage("Function has already been registered.")); + } if (entry_registered == false) { dependent_variables_functions.push_back(func); @@ -766,12 +771,13 @@ namespace Differentiation { const bool entry_registered = (map_dep_expr_vec_entry.find(func) != map_dep_expr_vec_entry.end()); -# ifdef DEBUG - if (entry_registered == true && - is_valid_nonunique_dependent_variable(func) == false) - Assert(entry_registered, - ExcMessage("Function has already been registered.")); -# endif + if constexpr (running_in_debug_mode()) + { + if (entry_registered == true && + is_valid_nonunique_dependent_variable(func) == false) + Assert(entry_registered, + ExcMessage("Function has already been registered.")); + } if (entry_registered == false) { dependent_variables_functions.push_back(func); diff --git a/source/distributed/cell_weights.cc b/source/distributed/cell_weights.cc index 280922bf7b..fe7e0a2352 100644 --- a/source/distributed/cell_weights.cc +++ b/source/distributed/cell_weights.cc @@ -191,12 +191,13 @@ namespace parallel break; case CellStatus::children_will_be_coarsened: -#ifdef DEBUG - for (const auto &child : cell->child_iterators()) - Assert(child->is_active() && child->coarsen_flag_set(), - typename dealii::Triangulation< - dim>::ExcInconsistentCoarseningFlags()); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &child : cell->child_iterators()) + Assert(child->is_active() && child->coarsen_flag_set(), + typename dealii::Triangulation< + dim>::ExcInconsistentCoarseningFlags()); + } fe_index = dealii::internal::hp::DoFHandlerImplementation:: dominated_future_fe_on_children(cell); diff --git a/source/distributed/shared_tria.cc b/source/distributed/shared_tria.cc index e4ee70b431..3718320e24 100644 --- a/source/distributed/shared_tria.cc +++ b/source/distributed/shared_tria.cc @@ -86,19 +86,20 @@ namespace parallel DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim)) void Triangulation::partition() { -# ifdef DEBUG - // Check that all meshes are the same (or at least have the same - // total number of active cells): - const unsigned int max_active_cells = - Utilities::MPI::max(this->n_active_cells(), - this->get_mpi_communicator()); - Assert( - max_active_cells == this->n_active_cells(), - ExcMessage( - "A parallel::shared::Triangulation needs to be refined in the same " - "way on all processors, but the participating processors don't " - "agree on the number of active cells.")); -# endif + if constexpr (running_in_debug_mode()) + { + // Check that all meshes are the same (or at least have the same + // total number of active cells): + const unsigned int max_active_cells = + Utilities::MPI::max(this->n_active_cells(), + this->get_mpi_communicator()); + Assert( + max_active_cells == this->n_active_cells(), + ExcMessage( + "A parallel::shared::Triangulation needs to be refined in the same " + "way on all processors, but the participating processors don't " + "agree on the number of active cells.")); + } auto partition_settings = (partition_zoltan | partition_metis | partition_zorder | partition_custom_signal) & @@ -284,37 +285,38 @@ namespace parallel true_subdomain_ids_of_cells[index] = cell->subdomain_id(); } -# ifdef DEBUG - { - // Assert that each cell is owned by a processor - const unsigned int n_my_cells = std::count_if( - this->begin_active(), - typename Triangulation::active_cell_iterator( - this->end()), - [](const auto &i) { return (i.is_locally_owned()); }); - - const unsigned int total_cells = - Utilities::MPI::sum(n_my_cells, this->get_mpi_communicator()); - Assert(total_cells == this->n_active_cells(), - ExcMessage("Not all cells are assigned to a processor.")); - } - - // If running with multigrid, assert that each level - // cell is owned by a processor - if (settings & construct_multigrid_hierarchy) + if constexpr (running_in_debug_mode()) { - const unsigned int n_my_cells = - std::count_if(this->begin(), this->end(), [](const auto &i) { - return (i.is_locally_owned_on_level()); - }); + { + // Assert that each cell is owned by a processor + const unsigned int n_my_cells = std::count_if( + this->begin_active(), + typename Triangulation::active_cell_iterator( + this->end()), + [](const auto &i) { return (i.is_locally_owned()); }); + + const unsigned int total_cells = + Utilities::MPI::sum(n_my_cells, this->get_mpi_communicator()); + Assert(total_cells == this->n_active_cells(), + ExcMessage("Not all cells are assigned to a processor.")); + } + + // If running with multigrid, assert that each level + // cell is owned by a processor + if (settings & construct_multigrid_hierarchy) + { + const unsigned int n_my_cells = + std::count_if(this->begin(), this->end(), [](const auto &i) { + return (i.is_locally_owned_on_level()); + }); - const unsigned int total_cells = - Utilities::MPI::sum(n_my_cells, this->get_mpi_communicator()); - Assert(total_cells == this->n_cells(), - ExcMessage("Not all cells are assigned to a processor.")); + const unsigned int total_cells = + Utilities::MPI::sum(n_my_cells, this->get_mpi_communicator()); + Assert(total_cells == this->n_cells(), + ExcMessage("Not all cells are assigned to a processor.")); + } } -# endif } diff --git a/source/distributed/tria.cc b/source/distributed/tria.cc index 7444bdcfaa..3712897afd 100644 --- a/source/distributed/tria.cc +++ b/source/distributed/tria.cc @@ -2630,18 +2630,21 @@ namespace parallel } } -# ifdef DEBUG - // There must not be any chains! - for (unsigned int i = 0; i < topological_vertex_numbering.size(); ++i) + if constexpr (running_in_debug_mode()) { - const unsigned int j = topological_vertex_numbering[i]; - Assert(j == i || topological_vertex_numbering[j] == j, - ExcMessage("Got inconclusive constraints with chain: " + - std::to_string(i) + " vs " + std::to_string(j) + - " which should be equal to " + - std::to_string(topological_vertex_numbering[j]))); + // There must not be any chains! + for (unsigned int i = 0; i < topological_vertex_numbering.size(); + ++i) + { + const unsigned int j = topological_vertex_numbering[i]; + Assert(j == i || topological_vertex_numbering[j] == j, + ExcMessage( + "Got inconclusive constraints with chain: " + + std::to_string(i) + " vs " + std::to_string(j) + + " which should be equal to " + + std::to_string(topological_vertex_numbering[j]))); + } } -# endif // this code is replicated from grid/tria.cc but using an indirection @@ -3012,20 +3015,21 @@ namespace parallel } while (mesh_changed); -# ifdef DEBUG - // check if correct number of ghosts is created - unsigned int num_ghosts = 0; - - for (const auto &cell : this->active_cell_iterators()) + if constexpr (running_in_debug_mode()) { - if (cell->subdomain_id() != this->my_subdomain && - cell->subdomain_id() != numbers::artificial_subdomain_id) - ++num_ghosts; - } + // check if correct number of ghosts is created + unsigned int num_ghosts = 0; - Assert(num_ghosts == parallel_ghost->ghosts.elem_count, - ExcInternalError()); -# endif + for (const auto &cell : this->active_cell_iterators()) + { + if (cell->subdomain_id() != this->my_subdomain && + cell->subdomain_id() != numbers::artificial_subdomain_id) + ++num_ghosts; + } + + Assert(num_ghosts == parallel_ghost->ghosts.elem_count, + ExcInternalError()); + } @@ -3121,42 +3125,46 @@ namespace parallel -# ifdef DEBUG - // check that our local copy has exactly as many cells as the p4est - // original (at least if we are on only one processor); for parallel - // computations, we want to check that we have at least as many as p4est - // stores locally (in the future we should check that we have exactly as - // many non-artificial cells as parallel_forest->local_num_quadrants) - { - const unsigned int total_local_cells = this->n_active_cells(); + if constexpr (running_in_debug_mode()) + { + // check that our local copy has exactly as many cells as the p4est + // original (at least if we are on only one processor); for parallel + // computations, we want to check that we have at least as many as + // p4est stores locally (in the future we should check that we have + // exactly as many non-artificial cells as + // parallel_forest->local_num_quadrants) + { + const unsigned int total_local_cells = this->n_active_cells(); - if (Utilities::MPI::n_mpi_processes(this->mpi_communicator) == 1) - { - Assert(static_cast( - parallel_forest->local_num_quadrants) == total_local_cells, - ExcInternalError()); - } - else - { + if (Utilities::MPI::n_mpi_processes(this->mpi_communicator) == 1) + { + Assert(static_cast( + parallel_forest->local_num_quadrants) == + total_local_cells, + ExcInternalError()); + } + else + { + Assert(static_cast( + parallel_forest->local_num_quadrants) <= + total_local_cells, + ExcInternalError()); + } + + // count the number of owned, active cells and compare with p4est. + unsigned int n_owned = 0; + for (const auto &cell : this->active_cell_iterators()) + { + if (cell->subdomain_id() == this->my_subdomain) + ++n_owned; + } + Assert(static_cast( - parallel_forest->local_num_quadrants) <= total_local_cells, + parallel_forest->local_num_quadrants) == n_owned, ExcInternalError()); } - - // count the number of owned, active cells and compare with p4est. - unsigned int n_owned = 0; - for (const auto &cell : this->active_cell_iterators()) - { - if (cell->subdomain_id() == this->my_subdomain) - ++n_owned; - } - - Assert(static_cast( - parallel_forest->local_num_quadrants) == n_owned, - ExcInternalError()); - } -# endif + } this->smooth_grid = save_smooth; @@ -3283,14 +3291,15 @@ namespace parallel void Triangulation::execute_coarsening_and_refinement() { // do not allow anisotropic refinement -# ifdef DEBUG - for (const auto &cell : this->active_cell_iterators()) - if (cell->is_locally_owned() && cell->refine_flag_set()) - Assert(cell->refine_flag_set() == - RefinementPossibilities::isotropic_refinement, - ExcMessage( - "This class does not support anisotropic refinement")); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &cell : this->active_cell_iterators()) + if (cell->is_locally_owned() && cell->refine_flag_set()) + Assert(cell->refine_flag_set() == + RefinementPossibilities::isotropic_refinement, + ExcMessage( + "This class does not support anisotropic refinement")); + } // safety check: p4est has an upper limit on the level of a cell @@ -3480,59 +3489,63 @@ namespace parallel this->data_serializer.unpack_cell_status(this->local_cell_relations); } -# ifdef DEBUG - // Check that we know the level subdomain ids of all our neighbors. This - // also involves coarser cells that share a vertex if they are active. - // - // Example (M= my, O=other): - // *------* - // | | - // | O | - // | | - // *---*---*------* - // | M | M | - // *---*---* - // | | M | - // *---*---* - // ^- the parent can be owned by somebody else, so O is not a neighbor - // one level coarser - if (settings & construct_multigrid_hierarchy) + if constexpr (running_in_debug_mode()) { - for (unsigned int lvl = 0; lvl < this->n_global_levels(); ++lvl) + // Check that we know the level subdomain ids of all our neighbors. + // This also involves coarser cells that share a vertex if they are + // active. + // + // Example (M= my, O=other): + // *------* + // | | + // | O | + // | | + // *---*---*------* + // | M | M | + // *---*---* + // | | M | + // *---*---* + // ^- the parent can be owned by somebody else, so O is not a + // neighbor + // one level coarser + if (settings & construct_multigrid_hierarchy) { - std::vector active_verts = - this->mark_locally_active_vertices_on_level(lvl); - - const unsigned int maybe_coarser_lvl = - (lvl > 0) ? (lvl - 1) : lvl; - typename Triangulation::cell_iterator - cell = this->begin(maybe_coarser_lvl), - endc = this->end(lvl); - for (; cell != endc; ++cell) - if (cell->level() == static_cast(lvl) || cell->is_active()) - { - const bool is_level_artificial = - (cell->level_subdomain_id() == - numbers::artificial_subdomain_id); - bool need_to_know = false; - for (const unsigned int vertex : - GeometryInfo::vertex_indices()) - if (active_verts[cell->vertex_index(vertex)]) - { - need_to_know = true; - break; - } + for (unsigned int lvl = 0; lvl < this->n_global_levels(); ++lvl) + { + std::vector active_verts = + this->mark_locally_active_vertices_on_level(lvl); + + const unsigned int maybe_coarser_lvl = + (lvl > 0) ? (lvl - 1) : lvl; + typename Triangulation::cell_iterator + cell = this->begin(maybe_coarser_lvl), + endc = this->end(lvl); + for (; cell != endc; ++cell) + if (cell->level() == static_cast(lvl) || + cell->is_active()) + { + const bool is_level_artificial = + (cell->level_subdomain_id() == + numbers::artificial_subdomain_id); + bool need_to_know = false; + for (const unsigned int vertex : + GeometryInfo::vertex_indices()) + if (active_verts[cell->vertex_index(vertex)]) + { + need_to_know = true; + break; + } - Assert( - !need_to_know || !is_level_artificial, - ExcMessage( - "Internal error: the owner of cell" + - cell->id().to_string() + - " is unknown even though it is needed for geometric multigrid.")); - } + Assert( + !need_to_know || !is_level_artificial, + ExcMessage( + "Internal error: the owner of cell" + + cell->id().to_string() + + " is unknown even though it is needed for geometric multigrid.")); + } + } } } -# endif this->update_periodic_face_map(); this->update_number_cache(); @@ -3547,14 +3560,15 @@ namespace parallel DEAL_II_CXX20_REQUIRES((concepts::is_valid_dim_spacedim)) void Triangulation::repartition() { -# ifdef DEBUG - for (const auto &cell : this->active_cell_iterators()) - if (cell->is_locally_owned()) - Assert( - !cell->refine_flag_set() && !cell->coarsen_flag_set(), - ExcMessage( - "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition().")); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &cell : this->active_cell_iterators()) + if (cell->is_locally_owned()) + Assert( + !cell->refine_flag_set() && !cell->coarsen_flag_set(), + ExcMessage( + "Error: There shouldn't be any cells flagged for coarsening/refinement when calling repartition().")); + } // signal that repartitioning is going to happen this->signals.pre_distributed_repartition(); diff --git a/source/distributed/tria_base.cc b/source/distributed/tria_base.cc index 262d588239..a4eeda0b30 100644 --- a/source/distributed/tria_base.cc +++ b/source/distributed/tria_base.cc @@ -233,60 +233,61 @@ namespace parallel this->number_cache.level_ghost_owners.insert( cell->level_subdomain_id()); -# ifdef DEBUG - // Check that level_ghost_owners is symmetric by sending a message - // to everyone - { - int ierr = MPI_Barrier(this->mpi_communicator); - AssertThrowMPI(ierr); - - const int mpi_tag = Utilities::MPI::internal::Tags:: - triangulation_base_fill_level_ghost_owners; - - // important: preallocate to avoid (re)allocation: - std::vector requests( - this->number_cache.level_ghost_owners.size()); - unsigned int dummy = 0; - unsigned int req_counter = 0; - - for (const auto &it : this->number_cache.level_ghost_owners) - { - ierr = MPI_Isend(&dummy, - 1, - MPI_UNSIGNED, - it, - mpi_tag, - this->mpi_communicator, - &requests[req_counter]); - AssertThrowMPI(ierr); - ++req_counter; - } - - for (const auto &it : this->number_cache.level_ghost_owners) + if constexpr (running_in_debug_mode()) + { + // Check that level_ghost_owners is symmetric by sending a message + // to everyone { - unsigned int dummy; - ierr = MPI_Recv(&dummy, - 1, - MPI_UNSIGNED, - it, - mpi_tag, - this->mpi_communicator, - MPI_STATUS_IGNORE); + int ierr = MPI_Barrier(this->mpi_communicator); AssertThrowMPI(ierr); - } - if (requests.size() > 0) - { - ierr = MPI_Waitall(requests.size(), - requests.data(), - MPI_STATUSES_IGNORE); + const int mpi_tag = Utilities::MPI::internal::Tags:: + triangulation_base_fill_level_ghost_owners; + + // important: preallocate to avoid (re)allocation: + std::vector requests( + this->number_cache.level_ghost_owners.size()); + unsigned int dummy = 0; + unsigned int req_counter = 0; + + for (const auto &it : this->number_cache.level_ghost_owners) + { + ierr = MPI_Isend(&dummy, + 1, + MPI_UNSIGNED, + it, + mpi_tag, + this->mpi_communicator, + &requests[req_counter]); + AssertThrowMPI(ierr); + ++req_counter; + } + + for (const auto &it : this->number_cache.level_ghost_owners) + { + unsigned int dummy; + ierr = MPI_Recv(&dummy, + 1, + MPI_UNSIGNED, + it, + mpi_tag, + this->mpi_communicator, + MPI_STATUS_IGNORE); + AssertThrowMPI(ierr); + } + + if (requests.size() > 0) + { + ierr = MPI_Waitall(requests.size(), + requests.data(), + MPI_STATUSES_IGNORE); + AssertThrowMPI(ierr); + } + + ierr = MPI_Barrier(this->mpi_communicator); AssertThrowMPI(ierr); } - - ierr = MPI_Barrier(this->mpi_communicator); - AssertThrowMPI(ierr); - } -# endif + } Assert(this->number_cache.level_ghost_owners.size() < Utilities::MPI::n_mpi_processes(this->mpi_communicator), @@ -583,17 +584,18 @@ namespace parallel const std::vector &vertex_locally_moved) { AssertDimension(vertex_locally_moved.size(), this->n_vertices()); -#ifdef DEBUG - { - const std::vector locally_owned_vertices = - dealii::GridTools::get_locally_owned_vertices(*this); - for (unsigned int i = 0; i < locally_owned_vertices.size(); ++i) - Assert((vertex_locally_moved[i] == false) || - (locally_owned_vertices[i] == true), - ExcMessage("The vertex_locally_moved argument must not " - "contain vertices that are not locally owned")); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + const std::vector locally_owned_vertices = + dealii::GridTools::get_locally_owned_vertices(*this); + for (unsigned int i = 0; i < locally_owned_vertices.size(); ++i) + Assert((vertex_locally_moved[i] == false) || + (locally_owned_vertices[i] == true), + ExcMessage("The vertex_locally_moved argument must not " + "contain vertices that are not locally owned")); + } + } Point invalid_point; for (unsigned int d = 0; d < spacedim; ++d) diff --git a/source/dofs/dof_accessor_set.cc b/source/dofs/dof_accessor_set.cc index f06edd4e72..21398d15c4 100644 --- a/source/dofs/dof_accessor_set.cc +++ b/source/dofs/dof_accessor_set.cc @@ -70,21 +70,6 @@ namespace internal return a; } - /** - * Check if a vector is a deal.II vector. - */ - template - constexpr bool is_dealii_vector = - std::is_same_v> || - std::is_same_v> || - std::is_same_v> || - std::is_same_v>; /** * Helper functions that call set_ghost_state() if the vector supports this @@ -117,6 +102,24 @@ namespace internal } #endif + namespace + { + // Test whether a vector is a deal.II vector + template + constexpr bool is_dealii_vector = + std::is_same_v> || + std::is_same_v> || + std::is_same_v> || + std::is_same_v>; + } // namespace + + /** * Helper function that sets the values on a cell, but also checks if the * new values are similar to the old values. @@ -134,32 +137,33 @@ namespace internal { (void)perform_check; -#ifdef DEBUG - if (perform_check && is_dealii_vector) + if constexpr (running_in_debug_mode()) { - const bool old_ghost_state = values.has_ghost_elements(); - set_ghost_state(values, true); - - Vector local_values_old(cell.get_fe().n_dofs_per_cell()); - cell.get_dof_values(values, local_values_old); - - for (unsigned int i = 0; i < cell.get_fe().n_dofs_per_cell(); ++i) + if (perform_check && is_dealii_vector) { - // a check consistent with the one in - // Utilities::MPI::Partitioner::import_from_ghosted_array_finish() - Assert(local_values_old[i] == number() || - get_abs(local_values_old[i] - local_values[i]) <= - get_abs(local_values_old[i] + local_values[i]) * - 100000. * - std::numeric_limits::real_type>::epsilon(), - ExcNonMatchingElementsSetDofValuesByInterpolation( - local_values[i], local_values_old[i])); + const bool old_ghost_state = values.has_ghost_elements(); + set_ghost_state(values, true); + + Vector local_values_old(cell.get_fe().n_dofs_per_cell()); + cell.get_dof_values(values, local_values_old); + + for (unsigned int i = 0; i < cell.get_fe().n_dofs_per_cell(); ++i) + { + // a check consistent with the one in + // Utilities::MPI::Partitioner::import_from_ghosted_array_finish() + Assert( + local_values_old[i] == number() || + get_abs(local_values_old[i] - local_values[i]) <= + get_abs(local_values_old[i] + local_values[i]) * 100000. * + std::numeric_limits::real_type>::epsilon(), + ExcNonMatchingElementsSetDofValuesByInterpolation( + local_values[i], local_values_old[i])); + } + + set_ghost_state(values, old_ghost_state); } - - set_ghost_state(values, old_ghost_state); } -#endif cell.set_dof_values(local_values, values); } diff --git a/source/dofs/dof_handler.cc b/source/dofs/dof_handler.cc index 6a666f5e5b..10a5adcea3 100644 --- a/source/dofs/dof_handler.cc +++ b/source/dofs/dof_handler.cc @@ -708,24 +708,25 @@ namespace internal vertex_fe_association[cell->active_fe_index()] [cell->vertex_index(v)] = true; - // in debug mode, make sure that each vertex is associated - // with at least one FE (note that except for unused - // vertices, all vertices are actually active). this is of - // course only true for vertices that are part of either - // ghost or locally owned cells -#ifdef DEBUG - for (unsigned int v = 0; v < dof_handler.tria->n_vertices(); ++v) - if (locally_used_vertices[v] == true) - if (dof_handler.tria->vertex_used(v) == true) - { - unsigned int fe = 0; - for (; fe < dof_handler.fe_collection.size(); ++fe) - if (vertex_fe_association[fe][v] == true) - break; - Assert(fe != dof_handler.fe_collection.size(), - ExcInternalError()); - } -#endif + // in debug mode, make sure that each vertex is associated + // with at least one FE (note that except for unused + // vertices, all vertices are actually active). this is of + // course only true for vertices that are part of either + // ghost or locally owned cells + if constexpr (running_in_debug_mode()) + { + for (unsigned int v = 0; v < dof_handler.tria->n_vertices(); ++v) + if (locally_used_vertices[v] == true) + if (dof_handler.tria->vertex_used(v) == true) + { + unsigned int fe = 0; + for (; fe < dof_handler.fe_collection.size(); ++fe) + if (vertex_fe_association[fe][v] == true) + break; + Assert(fe != dof_handler.fe_collection.size(), + ExcInternalError()); + } + } const unsigned int d = 0; const unsigned int l = 0; @@ -1499,13 +1500,15 @@ namespace internal // based on the 'least dominant finite element' of its // children. Consider the childrens' hypothetical future // index when they have been flagged for p-refinement. -#ifdef DEBUG - for (const auto &child : parent->child_iterators()) - Assert(child->is_active() && - child->coarsen_flag_set(), - typename dealii::Triangulation< - dim>::ExcInconsistentCoarseningFlags()); -#endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + for (const auto &child : parent->child_iterators()) + Assert(child->is_active() && + child->coarsen_flag_set(), + typename dealii::Triangulation< + dim>::ExcInconsistentCoarseningFlags()); + } const types::fe_index fe_index = dealii::internal::hp:: DoFHandlerImplementation::Implementation:: @@ -2159,24 +2162,25 @@ void DoFHandler::distribute_dofs( ExcMessage("The given hp::FECollection contains more finite elements " "than the DoFHandler can cover with active FE indices.")); -# ifdef DEBUG - // make sure that the provided FE collection is large enough to - // cover all FE indices presently in use on the mesh - if ((hp_cell_active_fe_indices.size() > 0) && - (hp_cell_future_fe_indices.size() > 0)) + if constexpr (running_in_debug_mode()) { - Assert(hp_capability_enabled, ExcInternalError()); - - for (const auto &cell : - this->active_cell_iterators() | IteratorFilters::LocallyOwnedCell()) + // make sure that the provided FE collection is large enough to + // cover all FE indices presently in use on the mesh + if ((hp_cell_active_fe_indices.size() > 0) && + (hp_cell_future_fe_indices.size() > 0)) { - Assert(cell->active_fe_index() < ff.size(), - ExcInvalidFEIndex(cell->active_fe_index(), ff.size())); - Assert(cell->future_fe_index() < ff.size(), - ExcInvalidFEIndex(cell->future_fe_index(), ff.size())); + Assert(hp_capability_enabled, ExcInternalError()); + + for (const auto &cell : this->active_cell_iterators() | + IteratorFilters::LocallyOwnedCell()) + { + Assert(cell->active_fe_index() < ff.size(), + ExcInvalidFEIndex(cell->active_fe_index(), ff.size())); + Assert(cell->future_fe_index() < ff.size(), + ExcInvalidFEIndex(cell->future_fe_index(), ff.size())); + } } } -# endif // // register the new finite element collection @@ -2401,26 +2405,29 @@ void DoFHandler::renumber_dofs( AssertDimension(new_numbers.size(), this->n_locally_owned_dofs()); -# ifdef DEBUG - // assert that the new indices are consecutively numbered if we are - // working on a single processor. this doesn't need to - // hold in the case of a parallel mesh since we map the interval - // [0...n_dofs()) into itself but only globally, not on each processor - if (this->n_locally_owned_dofs() == this->n_dofs()) + if constexpr (running_in_debug_mode()) { - std::vector tmp(new_numbers); - std::sort(tmp.begin(), tmp.end()); - std::vector::const_iterator p = tmp.begin(); - types::global_dof_index i = 0; - for (; p != tmp.end(); ++p, ++i) - Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + // assert that the new indices are consecutively numbered if we are + // working on a single processor. this doesn't need to + // hold in the case of a parallel mesh since we map the interval + // [0...n_dofs()) into itself but only globally, not on each processor + if (this->n_locally_owned_dofs() == this->n_dofs()) + { + std::vector tmp(new_numbers); + std::sort(tmp.begin(), tmp.end()); + std::vector::const_iterator p = + tmp.begin(); + types::global_dof_index i = 0; + for (; p != tmp.end(); ++p, ++i) + Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + } + else + for (const auto new_number : new_numbers) + Assert( + new_number < this->n_dofs(), + ExcMessage( + "New DoF index is not less than the total number of dofs.")); } - else - for (const auto new_number : new_numbers) - Assert(new_number < this->n_dofs(), - ExcMessage( - "New DoF index is not less than the total number of dofs.")); -# endif // uncompress the internal storage scheme of dofs on cells so that // we can access dofs in turns. uncompress in parallel, starting @@ -2455,44 +2462,47 @@ void DoFHandler::renumber_dofs( ExcMessage( "You need to distribute DoFs before you can renumber them.")); -# ifdef DEBUG - if (dynamic_cast *>( - &*this->tria) != nullptr) - { - Assert(new_numbers.size() == this->n_dofs() || - new_numbers.size() == this->n_locally_owned_dofs(), - ExcMessage("Incorrect size of the input array.")); - } - else if (dynamic_cast< - const parallel::DistributedTriangulationBase *>( - &*this->tria) != nullptr) - { - AssertDimension(new_numbers.size(), this->n_locally_owned_dofs()); - } - else + if constexpr (running_in_debug_mode()) { - AssertDimension(new_numbers.size(), this->n_dofs()); - } + if (dynamic_cast + *>(&*this->tria) != nullptr) + { + Assert(new_numbers.size() == this->n_dofs() || + new_numbers.size() == this->n_locally_owned_dofs(), + ExcMessage("Incorrect size of the input array.")); + } + else if (dynamic_cast< + const parallel::DistributedTriangulationBase + *>(&*this->tria) != nullptr) + { + AssertDimension(new_numbers.size(), this->n_locally_owned_dofs()); + } + else + { + AssertDimension(new_numbers.size(), this->n_dofs()); + } - // assert that the new indices are consecutively numbered if we are - // working on a single processor. this doesn't need to - // hold in the case of a parallel mesh since we map the interval - // [0...n_dofs()) into itself but only globally, not on each processor - if (this->n_locally_owned_dofs() == this->n_dofs()) - { - std::vector tmp(new_numbers); - std::sort(tmp.begin(), tmp.end()); - std::vector::const_iterator p = tmp.begin(); - types::global_dof_index i = 0; - for (; p != tmp.end(); ++p, ++i) - Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + // assert that the new indices are consecutively numbered if we are + // working on a single processor. this doesn't need to + // hold in the case of a parallel mesh since we map the interval + // [0...n_dofs()) into itself but only globally, not on each processor + if (this->n_locally_owned_dofs() == this->n_dofs()) + { + std::vector tmp(new_numbers); + std::sort(tmp.begin(), tmp.end()); + std::vector::const_iterator p = + tmp.begin(); + types::global_dof_index i = 0; + for (; p != tmp.end(); ++p, ++i) + Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + } + else + for (const auto new_number : new_numbers) + Assert( + new_number < this->n_dofs(), + ExcMessage( + "New DoF index is not less than the total number of dofs.")); } - else - for (const auto new_number : new_numbers) - Assert(new_number < this->n_dofs(), - ExcMessage( - "New DoF index is not less than the total number of dofs.")); -# endif this->number_cache = this->policy->renumber_dofs(new_numbers); } @@ -2516,26 +2526,27 @@ void DoFHandler::renumber_dofs( AssertDimension(new_numbers.size(), this->locally_owned_mg_dofs(level).n_elements()); -# ifdef DEBUG - // assert that the new indices are consecutively numbered if we are working - // on a single processor. this doesn't need to hold in the case of a - // parallel mesh since we map the interval [0...n_dofs(level)) into itself - // but only globally, not on each processor - if (this->n_locally_owned_dofs() == this->n_dofs()) + if constexpr (running_in_debug_mode()) { - std::vector tmp(new_numbers); - std::sort(tmp.begin(), tmp.end()); - std::vector::const_iterator p = tmp.begin(); - types::global_dof_index i = 0; - for (; p != tmp.end(); ++p, ++i) - Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + // assert that the new indices are consecutively numbered if we are + // working on a single processor. this doesn't need to hold in the case of + // a parallel mesh since we map the interval [0...n_dofs(level)) into + // itself but only globally, not on each processor + if (this->n_locally_owned_dofs() == this->n_dofs()) + { + std::vector tmp(new_numbers); + std::sort(tmp.begin(), tmp.end()); + std::vector::const_iterator p = tmp.begin(); + types::global_dof_index i = 0; + for (; p != tmp.end(); ++p, ++i) + Assert(*p == i, ExcNewNumbersNotConsecutive(i)); + } + else + for (const auto new_number : new_numbers) + Assert(new_number < this->n_dofs(level), + ExcMessage( + "New DoF index is not less than the total number of dofs.")); } - else - for (const auto new_number : new_numbers) - Assert(new_number < this->n_dofs(level), - ExcMessage( - "New DoF index is not less than the total number of dofs.")); -# endif this->mg_number_cache[level] = this->policy->renumber_mg_dofs(level, new_numbers); diff --git a/source/dofs/dof_handler_policy.cc b/source/dofs/dof_handler_policy.cc index 886f96ef49..3cbe0f4fd8 100644 --- a/source/dofs/dof_handler_policy.cc +++ b/source/dofs/dof_handler_policy.cc @@ -127,25 +127,26 @@ namespace internal DEAL_II_NOT_IMPLEMENTED(); } -#ifdef DEBUG - // Each entry of 'complete_identities' contains a set of - // pairs (fe_index,dof_index). Because we put in exactly - // two fe indices, we know that each entry of the outer - // vector needs to contain a set of exactly two such - // pairs. Check this. While there, also check that - // the two entries actually reference fe_index_1 and - // fe_index_2: - for (const auto &complete_identity : complete_identities) + if constexpr (running_in_debug_mode()) { - Assert(complete_identity.size() == 2, ExcInternalError()); - Assert(complete_identity.find(fe_index_1) != - complete_identity.end(), - ExcInternalError()); - Assert(complete_identity.find(fe_index_2) != - complete_identity.end(), - ExcInternalError()); + // Each entry of 'complete_identities' contains a set of + // pairs (fe_index,dof_index). Because we put in exactly + // two fe indices, we know that each entry of the outer + // vector needs to contain a set of exactly two such + // pairs. Check this. While there, also check that + // the two entries actually reference fe_index_1 and + // fe_index_2: + for (const auto &complete_identity : complete_identities) + { + Assert(complete_identity.size() == 2, ExcInternalError()); + Assert(complete_identity.find(fe_index_1) != + complete_identity.end(), + ExcInternalError()); + Assert(complete_identity.find(fe_index_2) != + complete_identity.end(), + ExcInternalError()); + } } -#endif // Next reduce these sets of two pairs by removing the // fe_index parts: We know which indices we have. But we @@ -165,21 +166,24 @@ namespace internal reduced_identities.emplace_back(dof_index_1, dof_index_2); } -#ifdef DEBUG - // double check whether the newly created entries make - // any sense at all - for (const auto &identity : reduced_identities) + if constexpr (running_in_debug_mode()) { - Assert(identity.first < - fes[fe_index_1] - .template n_dofs_per_object(face_no), - ExcInternalError()); - Assert(identity.second < - fes[fe_index_2] - .template n_dofs_per_object(face_no), - ExcInternalError()); + // double check whether the newly created entries make + // any sense at all + for (const auto &identity : reduced_identities) + { + Assert( + identity.first < + fes[fe_index_1].template n_dofs_per_object( + face_no), + ExcInternalError()); + Assert( + identity.second < + fes[fe_index_2].template n_dofs_per_object( + face_no), + ExcInternalError()); + } } -#endif identities = std::make_unique(std::move(reduced_identities)); @@ -3759,51 +3763,53 @@ namespace internal // at this point, we must have taken care of the data transfer // on all cells we had previously marked. verify this -# ifdef DEBUG - for (const auto &cell : dof_handler->active_cell_iterators()) - Assert(cell_marked[cell->active_cell_index()] == false, - ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &cell : dof_handler->active_cell_iterators()) + Assert(cell_marked[cell->active_cell_index()] == false, + ExcInternalError()); + } } -# ifdef DEBUG - // check that we are really done - { - std::vector local_dof_indices; + if constexpr (running_in_debug_mode()) + { + // check that we are really done + { + std::vector local_dof_indices; - for (const auto &cell : dof_handler->active_cell_iterators()) - if (!cell->is_artificial()) - { - local_dof_indices.resize(cell->get_fe().n_dofs_per_cell()); - cell->get_dof_indices(local_dof_indices); - if (local_dof_indices.end() != - std::find(local_dof_indices.begin(), - local_dof_indices.end(), - numbers::invalid_dof_index)) + for (const auto &cell : dof_handler->active_cell_iterators()) + if (!cell->is_artificial()) { - if (cell->is_ghost()) + local_dof_indices.resize(cell->get_fe().n_dofs_per_cell()); + cell->get_dof_indices(local_dof_indices); + if (local_dof_indices.end() != + std::find(local_dof_indices.begin(), + local_dof_indices.end(), + numbers::invalid_dof_index)) { - Assert(false, - ExcMessage( - "A ghost cell ended up with incomplete " - "DoF index information. This should not " - "have happened!")); - } - else - { - Assert( - false, - ExcMessage( - "A locally owned cell ended up with incomplete " - "DoF index information. This should not " - "have happened!")); + if (cell->is_ghost()) + { + Assert(false, + ExcMessage( + "A ghost cell ended up with incomplete " + "DoF index information. This should not " + "have happened!")); + } + else + { + Assert( + false, + ExcMessage( + "A locally owned cell ended up with incomplete " + "DoF index information. This should not " + "have happened!")); + } } } - } - } -# endif // DEBUG + } + } // DEBUG return number_cache; -#endif // DEAL_II_WITH_MPI +#endif // DEAL_II_WITH_MPI } @@ -3947,36 +3953,39 @@ namespace internal // in Phase 1. communicate_mg_ghost_cells(*dof_handler, cell_marked); -# ifdef DEBUG - // make sure we have finished all cells: - for (const auto &cell : dof_handler->cell_iterators()) - Assert(cell_marked[cell->level()][cell->index()] == false, - ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + // make sure we have finished all cells: + for (const auto &cell : dof_handler->cell_iterators()) + Assert(cell_marked[cell->level()][cell->index()] == false, + ExcInternalError()); + } } -# ifdef DEBUG - // check that we are really done - { - std::vector local_dof_indices; - for (const auto &cell : dof_handler->cell_iterators()) - if (cell->level_subdomain_id() != - dealii::numbers::artificial_subdomain_id) - { - local_dof_indices.resize(cell->get_fe().n_dofs_per_cell()); - cell->get_mg_dof_indices(local_dof_indices); - if (local_dof_indices.end() != - std::find(local_dof_indices.begin(), - local_dof_indices.end(), - numbers::invalid_dof_index)) + if constexpr (running_in_debug_mode()) + { + // check that we are really done + { + std::vector local_dof_indices; + for (const auto &cell : dof_handler->cell_iterators()) + if (cell->level_subdomain_id() != + dealii::numbers::artificial_subdomain_id) { - Assert(false, ExcMessage("not all DoFs got distributed!")); + local_dof_indices.resize(cell->get_fe().n_dofs_per_cell()); + cell->get_mg_dof_indices(local_dof_indices); + if (local_dof_indices.end() != + std::find(local_dof_indices.begin(), + local_dof_indices.end(), + numbers::invalid_dof_index)) + { + Assert(false, + ExcMessage("not all DoFs got distributed!")); + } } - } - } -# endif // DEBUG + } + } // DEBUG return number_caches; diff --git a/source/dofs/dof_renumbering.cc b/source/dofs/dof_renumbering.cc index 7f6e492bf1..f39914cfce 100644 --- a/source/dofs/dof_renumbering.cc +++ b/source/dofs/dof_renumbering.cc @@ -2295,14 +2295,15 @@ namespace DoFRenumbering std::vector(), false); -#ifdef DEBUG - { - const std::vector dofs_per_component = - DoFTools::count_dofs_per_fe_component(dof_handler, true); - for (const auto &dpc : dofs_per_component) - Assert(dofs_per_component[0] == dpc, ExcNotImplemented()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + const std::vector dofs_per_component = + DoFTools::count_dofs_per_fe_component(dof_handler, true); + for (const auto &dpc : dofs_per_component) + Assert(dofs_per_component[0] == dpc, ExcNotImplemented()); + } + } const unsigned int n_components = dof_handler.get_fe_collection().n_components(); Assert(dof_handler.n_dofs() % n_components == 0, ExcInternalError()); @@ -2338,15 +2339,16 @@ namespace DoFRenumbering component_dofs.end()); } component_renumbered_dofs.compress(); -#ifdef DEBUG - { - IndexSet component_renumbered_dofs2(dof_handler.n_dofs()); - component_renumbered_dofs2.add_indices(component_renumbering.begin(), - component_renumbering.end()); - Assert(component_renumbered_dofs2 == component_renumbered_dofs, - ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + IndexSet component_renumbered_dofs2(dof_handler.n_dofs()); + component_renumbered_dofs2.add_indices(component_renumbering.begin(), + component_renumbering.end()); + Assert(component_renumbered_dofs2 == component_renumbered_dofs, + ExcInternalError()); + } + } for (const FiniteElement &fe : dof_handler.get_fe_collection()) { diff --git a/source/dofs/dof_tools_constraints.cc b/source/dofs/dof_tools_constraints.cc index a5abaf041b..95aeac9b7b 100644 --- a/source/dofs/dof_tools_constraints.cc +++ b/source/dofs/dof_tools_constraints.cc @@ -1086,20 +1086,23 @@ namespace DoFTools cell->active_fe_index()) == true, ExcInternalError()); -#ifdef DEBUG - for (unsigned int c = 0; c < cell->face(f)->n_children(); ++c) + if constexpr (running_in_debug_mode()) { - if (cell->neighbor_child_on_subface(f, c)->is_artificial()) - continue; + for (unsigned int c = 0; c < cell->face(f)->n_children(); ++c) + { + if (cell->neighbor_child_on_subface(f, c) + ->is_artificial()) + continue; - Assert(cell->face(f)->child(c)->n_active_fe_indices() == 1, - ExcInternalError()); + Assert(cell->face(f)->child(c)->n_active_fe_indices() == + 1, + ExcInternalError()); - Assert(cell->face(f)->child(c)->fe_index_is_active( - cell->active_fe_index()) == true, - ExcNotImplemented()); - } -#endif // DEBUG + Assert(cell->face(f)->child(c)->fe_index_is_active( + cell->active_fe_index()) == true, + ExcNotImplemented()); + } + } // DEBUG // Ok, start up the work: const FiniteElement &fe = cell->get_fe(); @@ -1220,48 +1223,54 @@ namespace DoFTools cell->active_fe_index()) == true, ExcInternalError()); -#ifdef DEBUG - - for (unsigned int c = 0; c < cell->face(face)->n_children(); ++c) + if constexpr (running_in_debug_mode()) { - if (cell->neighbor_child_on_subface(face, c)->is_artificial()) - continue; + for (unsigned int c = 0; c < cell->face(face)->n_children(); + ++c) + { + if (cell->neighbor_child_on_subface(face, c) + ->is_artificial()) + continue; - AssertDimension( - cell->face(face)->child(c)->n_active_fe_indices(), 1); + AssertDimension( + cell->face(face)->child(c)->n_active_fe_indices(), 1); - Assert(cell->face(face)->child(c)->fe_index_is_active( - cell->active_fe_index()) == true, - ExcNotImplemented()); + Assert(cell->face(face)->child(c)->fe_index_is_active( + cell->active_fe_index()) == true, + ExcNotImplemented()); + + for (unsigned int e = 0; + e < GeometryInfo::vertices_per_face; + ++e) + { + Assert(cell->face(face) + ->child(c) + ->line(e) + ->n_active_fe_indices() == 1, + ExcNotImplemented()); + + Assert(cell->face(face) + ->child(c) + ->line(e) + ->fe_index_is_active( + cell->active_fe_index()) == true, + ExcNotImplemented()); + } + } for (unsigned int e = 0; e < GeometryInfo::vertices_per_face; ++e) { - Assert(cell->face(face) - ->child(c) - ->line(e) - ->n_active_fe_indices() == 1, + Assert(cell->face(face)->line(e)->n_active_fe_indices() == + 1, ExcNotImplemented()); - Assert( - cell->face(face)->child(c)->line(e)->fe_index_is_active( - cell->active_fe_index()) == true, - ExcNotImplemented()); + Assert(cell->face(face)->line(e)->fe_index_is_active( + cell->active_fe_index()) == true, + ExcNotImplemented()); } - } - - for (unsigned int e = 0; e < GeometryInfo::vertices_per_face; - ++e) - { - Assert(cell->face(face)->line(e)->n_active_fe_indices() == 1, - ExcNotImplemented()); - - Assert(cell->face(face)->line(e)->fe_index_is_active( - cell->active_fe_index()) == true, - ExcNotImplemented()); - } -#endif // DEBUG + } // DEBUG // Ok, start up the work const FiniteElement &fe = cell->get_fe(); @@ -3612,83 +3621,91 @@ namespace DoFTools static const int dim = FaceIterator::AccessorType::dimension; static const int spacedim = FaceIterator::AccessorType::space_dimension; -#ifdef DEBUG - const auto [orientation, rotation, flip] = - ::dealii::internal::split_face_orientation(combined_orientation); - - Assert((dim != 1) || - (orientation == true && flip == false && rotation == false), - ExcMessage("The supplied orientation (orientation, rotation, flip) " - "is invalid for 1d")); - - Assert((dim != 2) || (flip == false && rotation == false), - ExcMessage("The supplied orientation (orientation, rotation, flip) " - "is invalid for 2d")); - - Assert(face_1 != face_2, - ExcMessage("face_1 and face_2 are equal! Cannot constrain DoFs " - "on the very same face")); - - Assert(face_1->at_boundary() && face_2->at_boundary(), - ExcMessage("Faces for periodicity constraints must be on the " - "boundary")); + if constexpr (running_in_debug_mode()) + { + const auto [orientation, rotation, flip] = + ::dealii::internal::split_face_orientation(combined_orientation); - Assert(matrix.m() == matrix.n(), - ExcMessage("The supplied (rotation or interpolation) matrix must " - "be a square matrix")); + Assert((dim != 1) || + (orientation == true && flip == false && rotation == false), + ExcMessage( + "The supplied orientation (orientation, rotation, flip) " + "is invalid for 1d")); - Assert(first_vector_components.empty() || matrix.m() == spacedim, - ExcMessage("first_vector_components is nonempty, so matrix must " - "be a rotation matrix exactly of size spacedim")); + Assert((dim != 2) || (flip == false && rotation == false), + ExcMessage( + "The supplied orientation (orientation, rotation, flip) " + "is invalid for 2d")); - if (!face_1->has_children()) - { - // TODO: the implementation makes the assumption that all faces have the - // same number of dofs - AssertDimension( - face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(), 1); - const unsigned int face_no = 0; + Assert(face_1 != face_2, + ExcMessage("face_1 and face_2 are equal! Cannot constrain DoFs " + "on the very same face")); - Assert(face_1->n_active_fe_indices() == 1, ExcInternalError()); - const unsigned int n_dofs_per_face = - face_1->get_fe(face_1->nth_active_fe_index(0)) - .n_dofs_per_face(face_no); + Assert(face_1->at_boundary() && face_2->at_boundary(), + ExcMessage("Faces for periodicity constraints must be on the " + "boundary")); - Assert(matrix.m() == 0 || - (first_vector_components.empty() && - matrix.m() == n_dofs_per_face) || - (!first_vector_components.empty() && matrix.m() == spacedim), + Assert(matrix.m() == matrix.n(), ExcMessage( - "The matrix must have either size 0 or spacedim " - "(if first_vector_components is nonempty) " - "or the size must be equal to the # of DoFs on the face " - "(if first_vector_components is empty).")); - } + "The supplied (rotation or interpolation) matrix must " + "be a square matrix")); - if (!face_2->has_children()) - { - // TODO: the implementation makes the assumption that all faces have the - // same number of dofs - AssertDimension( - face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(), 1); - const unsigned int face_no = 0; + Assert(first_vector_components.empty() || matrix.m() == spacedim, + ExcMessage("first_vector_components is nonempty, so matrix must " + "be a rotation matrix exactly of size spacedim")); - Assert(face_2->n_active_fe_indices() == 1, ExcInternalError()); - const unsigned int n_dofs_per_face = - face_2->get_fe(face_2->nth_active_fe_index(0)) - .n_dofs_per_face(face_no); + if (!face_1->has_children()) + { + // TODO: the implementation makes the assumption that all faces have + // the same number of dofs + AssertDimension( + face_1->get_fe(face_1->nth_active_fe_index(0)).n_unique_faces(), + 1); + const unsigned int face_no = 0; + + Assert(face_1->n_active_fe_indices() == 1, ExcInternalError()); + const unsigned int n_dofs_per_face = + face_1->get_fe(face_1->nth_active_fe_index(0)) + .n_dofs_per_face(face_no); + + Assert(matrix.m() == 0 || + (first_vector_components.empty() && + matrix.m() == n_dofs_per_face) || + (!first_vector_components.empty() && + matrix.m() == spacedim), + ExcMessage( + "The matrix must have either size 0 or spacedim " + "(if first_vector_components is nonempty) " + "or the size must be equal to the # of DoFs on the face " + "(if first_vector_components is empty).")); + } - Assert(matrix.m() == 0 || - (first_vector_components.empty() && - matrix.m() == n_dofs_per_face) || - (!first_vector_components.empty() && matrix.m() == spacedim), - ExcMessage( - "The matrix must have either size 0 or spacedim " - "(if first_vector_components is nonempty) " - "or the size must be equal to the # of DoFs on the face " - "(if first_vector_components is empty).")); + if (!face_2->has_children()) + { + // TODO: the implementation makes the assumption that all faces have + // the same number of dofs + AssertDimension( + face_2->get_fe(face_2->nth_active_fe_index(0)).n_unique_faces(), + 1); + const unsigned int face_no = 0; + + Assert(face_2->n_active_fe_indices() == 1, ExcInternalError()); + const unsigned int n_dofs_per_face = + face_2->get_fe(face_2->nth_active_fe_index(0)) + .n_dofs_per_face(face_no); + + Assert(matrix.m() == 0 || + (first_vector_components.empty() && + matrix.m() == n_dofs_per_face) || + (!first_vector_components.empty() && + matrix.m() == spacedim), + ExcMessage( + "The matrix must have either size 0 or spacedim " + "(if first_vector_components is nonempty) " + "or the size must be equal to the # of DoFs on the face " + "(if first_vector_components is empty).")); + } } -#endif if (face_1->has_children() && face_2->has_children()) { @@ -4277,13 +4294,14 @@ namespace DoFTools fine_fe.component_to_base_index(fine_component).first), ExcFiniteElementsDontMatch()); -#ifdef DEBUG - // if in debug mode, check whether the coarse grid is indeed coarser - // everywhere than the fine grid - for (const auto &cell : coarse_grid.active_cell_iterators()) - Assert(cell->level() <= coarse_to_fine_grid_map[cell]->level(), - ExcGridNotCoarser()); -#endif + if constexpr (running_in_debug_mode()) + { + // if in debug mode, check whether the coarse grid is indeed coarser + // everywhere than the fine grid + for (const auto &cell : coarse_grid.active_cell_iterators()) + Assert(cell->level() <= coarse_to_fine_grid_map[cell]->level(), + ExcGridNotCoarser()); + } /* * From here on: the term `parameter' refers to the selected component @@ -4412,18 +4430,20 @@ namespace DoFTools // respective dofs of the other components have sum of weights zero, of // course. we do not explicitly ask which component a dof belongs to, // but this at least tests some errors -#ifdef DEBUG - for (unsigned int col = 0; col < n_parameters_on_fine_grid; ++col) + if constexpr (running_in_debug_mode()) { - double sum = 0; - for (types::global_dof_index row = 0; row < n_coarse_dofs; ++row) - if (weights[row].find(col) != weights[row].end()) - sum += weights[row][col]; - Assert((std::fabs(sum - 1) < 1.e-12) || - ((coarse_fe.n_components() > 1) && (sum == 0)), - ExcInternalError()); + for (unsigned int col = 0; col < n_parameters_on_fine_grid; ++col) + { + double sum = 0; + for (types::global_dof_index row = 0; row < n_coarse_dofs; + ++row) + if (weights[row].find(col) != weights[row].end()) + sum += weights[row][col]; + Assert((std::fabs(sum - 1) < 1.e-12) || + ((coarse_fe.n_components() > 1) && (sum == 0)), + ExcInternalError()); + } } -#endif return n_parameters_on_fine_grid; diff --git a/source/dofs/dof_tools_sparsity.cc b/source/dofs/dof_tools_sparsity.cc index acbd336cad..06fd0e55bd 100644 --- a/source/dofs/dof_tools_sparsity.cc +++ b/source/dofs/dof_tools_sparsity.cc @@ -388,16 +388,18 @@ namespace DoFTools AssertDimension(dof_to_boundary_mapping.size(), n_dofs); AssertDimension(sparsity.n_rows(), dof.n_boundary_dofs()); AssertDimension(sparsity.n_cols(), dof.n_boundary_dofs()); -#ifdef DEBUG - if (sparsity.n_rows() != 0) + if constexpr (running_in_debug_mode()) { - types::global_dof_index max_element = 0; - for (const types::global_dof_index index : dof_to_boundary_mapping) - if ((index != numbers::invalid_dof_index) && (index > max_element)) - max_element = index; - AssertDimension(max_element, sparsity.n_rows() - 1); + if (sparsity.n_rows() != 0) + { + types::global_dof_index max_element = 0; + for (const types::global_dof_index index : dof_to_boundary_mapping) + if ((index != numbers::invalid_dof_index) && + (index > max_element)) + max_element = index; + AssertDimension(max_element, sparsity.n_rows() - 1); + } } -#endif std::vector dofs_on_this_face; dofs_on_this_face.reserve(dof.get_fe_collection().max_dofs_per_face()); @@ -502,16 +504,18 @@ namespace DoFTools dof.n_boundary_dofs(boundary_ids))); (void)fe_is_hermite; -#ifdef DEBUG - if (sparsity.n_rows() != 0) + if constexpr (running_in_debug_mode()) { - types::global_dof_index max_element = 0; - for (const types::global_dof_index index : dof_to_boundary_mapping) - if ((index != numbers::invalid_dof_index) && (index > max_element)) - max_element = index; - AssertDimension(max_element, sparsity.n_rows() - 1); + if (sparsity.n_rows() != 0) + { + types::global_dof_index max_element = 0; + for (const types::global_dof_index index : dof_to_boundary_mapping) + if ((index != numbers::invalid_dof_index) && + (index > max_element)) + max_element = index; + AssertDimension(max_element, sparsity.n_rows() - 1); + } } -#endif std::vector dofs_on_this_face; dofs_on_this_face.reserve(dof.get_fe_collection().max_dofs_per_face()); diff --git a/source/fe/fe.cc b/source/fe/fe.cc index 318e1e9a4a..d9f2ba8737 100644 --- a/source/fe/fe.cc +++ b/source/fe/fe.cc @@ -1208,15 +1208,16 @@ FiniteElement::get_sub_fe(const ComponentMask &mask) const const unsigned int first_selected = mask.first_selected_component(n_total_components); -# ifdef DEBUG - // check that it is contiguous: - for (unsigned int c = 0; c < n_total_components; ++c) - Assert((c < first_selected && (!mask[c])) || - (c >= first_selected && c < first_selected + n_selected && - mask[c]) || - (c >= first_selected + n_selected && !mask[c]), - ExcMessage("Error: the given ComponentMask is not contiguous!")); -# endif + if constexpr (running_in_debug_mode()) + { + // check that it is contiguous: + for (unsigned int c = 0; c < n_total_components; ++c) + Assert((c < first_selected && (!mask[c])) || + (c >= first_selected && c < first_selected + n_selected && + mask[c]) || + (c >= first_selected + n_selected && !mask[c]), + ExcMessage("Error: the given ComponentMask is not contiguous!")); + } return get_sub_fe(first_selected, n_selected); } diff --git a/source/fe/fe_bernstein.cc b/source/fe/fe_bernstein.cc index 02764a88d9..03bf4154cf 100644 --- a/source/fe/fe_bernstein.cc +++ b/source/fe/fe_bernstein.cc @@ -186,19 +186,20 @@ FE_Bernstein::get_subface_interpolation_matrix( } } -#ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int j = 0; j < source_fe->n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int j = 0; j < source_fe->n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -#endif } else { diff --git a/source/fe/fe_dgq.cc b/source/fe/fe_dgq.cc index bdd4ebcf01..bbcc63543d 100644 --- a/source/fe/fe_dgq.cc +++ b/source/fe/fe_dgq.cc @@ -322,22 +322,24 @@ FE_DGQ::get_interpolation_matrix( if (std::fabs(interpolation_matrix(i, j)) < 1e-15) interpolation_matrix(i, j) = 0.; -#ifdef DEBUG - // make sure that the row sum of - // each of the matrices is 1 at - // this point. this must be so - // since the shape functions sum up - // to 1 - for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i) + if constexpr (running_in_debug_mode()) { - double sum = 0.; - for (unsigned int j = 0; j < source_fe->n_dofs_per_cell(); ++j) - sum += interpolation_matrix(i, j); + // make sure that the row sum of + // each of the matrices is 1 at + // this point. this must be so + // since the shape functions sum up + // to 1 + for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i) + { + double sum = 0.; + for (unsigned int j = 0; j < source_fe->n_dofs_per_cell(); ++j) + sum += interpolation_matrix(i, j); - Assert(std::fabs(sum - 1) < 5e-14 * std::max(this->degree, 1U) * dim, - ExcInternalError()); + Assert(std::fabs(sum - 1) < + 5e-14 * std::max(this->degree, 1U) * dim, + ExcInternalError()); + } } -#endif } else if (dynamic_cast *>(&x_source_fe)) { diff --git a/source/fe/fe_face.cc b/source/fe/fe_face.cc index 538b89b158..ce059b651b 100644 --- a/source/fe/fe_face.cc +++ b/source/fe/fe_face.cc @@ -222,19 +222,20 @@ FE_FaceQ::get_subface_interpolation_matrix( } } -#ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int j = 0; j < source_fe->n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int j = 0; j < source_fe->n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -#endif } else if (dynamic_cast *>(&x_source_fe) != nullptr) { diff --git a/source/fe/fe_q_base.cc b/source/fe/fe_q_base.cc index 0084fa5e75..5170001067 100644 --- a/source/fe/fe_q_base.cc +++ b/source/fe/fe_q_base.cc @@ -559,18 +559,19 @@ FE_Q_Base::get_interpolation_matrix( if (std::fabs(interpolation_matrix(i, j)) < eps) interpolation_matrix(i, j) = 0.; -# ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i) + if constexpr (running_in_debug_mode()) { - double sum = 0.; - for (unsigned int j = 0; j < source_fe->n_dofs_per_cell(); ++j) - sum += interpolation_matrix(i, j); + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int i = 0; i < this->n_dofs_per_cell(); ++i) + { + double sum = 0.; + for (unsigned int j = 0; j < source_fe->n_dofs_per_cell(); ++j) + sum += interpolation_matrix(i, j); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -# endif } else if (dynamic_cast *>(&x_source_fe)) { @@ -695,19 +696,20 @@ FE_Q_Base::get_subface_interpolation_matrix( } } -# ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -# endif } else if (dynamic_cast *>(&source_fe) != nullptr) { @@ -1269,23 +1271,14 @@ FE_Q_Base::get_prolongation_matrix( // evaluations of the Lagrange polynomials are zero or one. const double eps = 1e-15 * q_degree * dim; -# ifdef DEBUG - // in DEBUG mode, check that the evaluation of support points in the - // current numbering gives the identity operation - for (unsigned int i = 0; i < q_dofs_per_cell; ++i) + if constexpr (running_in_debug_mode()) { - Assert(std::fabs(1. - this->poly_space->compute_value( - i, this->unit_support_points[i])) < eps, - ExcInternalError("The Lagrange polynomial does not evaluate " - "to one or zero in a nodal point. " - "This typically indicates that the " - "polynomial interpolation is " - "ill-conditioned such that round-off " - "prevents the sum to be one.")); - for (unsigned int j = 0; j < q_dofs_per_cell; ++j) - if (j != i) - Assert(std::fabs(this->poly_space->compute_value( - i, this->unit_support_points[j])) < eps, + // in DEBUG mode, check that the evaluation of support points in the + // current numbering gives the identity operation + for (unsigned int i = 0; i < q_dofs_per_cell; ++i) + { + Assert(std::fabs(1. - this->poly_space->compute_value( + i, this->unit_support_points[i])) < eps, ExcInternalError( "The Lagrange polynomial does not evaluate " "to one or zero in a nodal point. " @@ -1293,8 +1286,19 @@ FE_Q_Base::get_prolongation_matrix( "polynomial interpolation is " "ill-conditioned such that round-off " "prevents the sum to be one.")); + for (unsigned int j = 0; j < q_dofs_per_cell; ++j) + if (j != i) + Assert(std::fabs(this->poly_space->compute_value( + i, this->unit_support_points[j])) < eps, + ExcInternalError( + "The Lagrange polynomial does not evaluate " + "to one or zero in a nodal point. " + "This typically indicates that the " + "polynomial interpolation is " + "ill-conditioned such that round-off " + "prevents the sum to be one.")); + } } -# endif // to efficiently evaluate the polynomial at the subcell, make use of // the tensor product structure of this element and only evaluate 1d @@ -1403,24 +1407,26 @@ FE_Q_Base::get_prolongation_matrix( if (q_dofs_per_cell < this->n_dofs_per_cell()) prolongate(q_dofs_per_cell, q_dofs_per_cell) = 1.; - // and make sure that the row sum is 1. this must be so since for this - // element, the shape functions add up to one -# ifdef DEBUG - for (unsigned int row = 0; row < this->n_dofs_per_cell(); ++row) + // and make sure that the row sum is 1. this must be so since for this + // element, the shape functions add up to one + if constexpr (running_in_debug_mode()) { - double sum = 0; - for (unsigned int col = 0; col < this->n_dofs_per_cell(); ++col) - sum += prolongate(row, col); - Assert(std::fabs(sum - 1.) < - std::max(eps, 5e-16 * std::sqrt(this->n_dofs_per_cell())), - ExcInternalError("The entries in a row of the local " - "prolongation matrix do not add to one. " - "This typically indicates that the " - "polynomial interpolation is " - "ill-conditioned such that round-off " - "prevents the sum to be one.")); + for (unsigned int row = 0; row < this->n_dofs_per_cell(); ++row) + { + double sum = 0; + for (unsigned int col = 0; col < this->n_dofs_per_cell(); ++col) + sum += prolongate(row, col); + Assert(std::fabs(sum - 1.) < + std::max(eps, + 5e-16 * std::sqrt(this->n_dofs_per_cell())), + ExcInternalError("The entries in a row of the local " + "prolongation matrix do not add to one. " + "This typically indicates that the " + "polynomial interpolation is " + "ill-conditioned such that round-off " + "prevents the sum to be one.")); + } } -# endif // move result into place const_cast &>( diff --git a/source/fe/fe_raviart_thomas_nodal.cc b/source/fe/fe_raviart_thomas_nodal.cc index 4e9dbfb28d..e3e5948ea1 100644 --- a/source/fe/fe_raviart_thomas_nodal.cc +++ b/source/fe/fe_raviart_thomas_nodal.cc @@ -558,20 +558,21 @@ FE_RaviartThomasNodal::get_face_interpolation_matrix( } } -#ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1), - ExcInternalError()); + Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1), + ExcInternalError()); + } } -#endif } @@ -652,20 +653,21 @@ FE_RaviartThomasNodal::get_subface_interpolation_matrix( } } -#ifdef DEBUG - // make sure that the row sum of each of the matrices is 1 at this - // point. this must be so since the shape functions sum up to 1 - for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + // make sure that the row sum of each of the matrices is 1 at this + // point. this must be so since the shape functions sum up to 1 + for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1), - ExcInternalError()); + Assert(std::fabs(sum - 1) < 2e-13 * this->degree * (dim - 1), + ExcInternalError()); + } } -#endif } diff --git a/source/fe/fe_simplex_p.cc b/source/fe/fe_simplex_p.cc index 8c5daebd42..e958760b5c 100644 --- a/source/fe/fe_simplex_p.cc +++ b/source/fe/fe_simplex_p.cc @@ -519,24 +519,25 @@ FE_SimplexPoly::get_restriction_matrix( restriction_mat[i][j] = this->shape_value(j, transformed_point[0]); } -#ifdef DEBUG - for (unsigned int i = 0; i < this->n_dofs_per_cell(); i++) + if constexpr (running_in_debug_mode()) { - double sum = 0.; - - for (unsigned int j = 0; j < this->n_dofs_per_cell(); j++) - sum += restriction_mat[i][j]; - - Assert(std::fabs(sum - 1) < eps || std::fabs(sum) < eps, - ExcInternalError( - "The entries in a row of the local " - "restriction matrix do not add to zero or one. " - "This typically indicates that the " - "polynomial interpolation is " - "ill-conditioned such that round-off " - "prevents the sum to be one.")); + for (unsigned int i = 0; i < this->n_dofs_per_cell(); i++) + { + double sum = 0.; + + for (unsigned int j = 0; j < this->n_dofs_per_cell(); j++) + sum += restriction_mat[i][j]; + + Assert(std::fabs(sum - 1) < eps || std::fabs(sum) < eps, + ExcInternalError( + "The entries in a row of the local " + "restriction matrix do not add to zero or one. " + "This typically indicates that the " + "polynomial interpolation is " + "ill-conditioned such that round-off " + "prevents the sum to be one.")); + } } -#endif // Remove small entries from the matrix for (unsigned int i = 0; i < restriction_mat.m(); ++i) @@ -605,17 +606,18 @@ FE_SimplexPoly::get_face_interpolation_matrix( interpolation_matrix(i, j) = matrix_entry; } -#ifdef DEBUG - for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -#endif } else if (dynamic_cast *>(&source_fe) != nullptr) { @@ -679,17 +681,18 @@ FE_SimplexPoly::get_subface_interpolation_matrix( interpolation_matrix(i, j) = matrix_entry; } -#ifdef DEBUG - for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + if constexpr (running_in_debug_mode()) { - double sum = 0.; + for (unsigned int j = 0; j < source_fe.n_dofs_per_face(face_no); ++j) + { + double sum = 0.; - for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) - sum += interpolation_matrix(j, i); + for (unsigned int i = 0; i < this->n_dofs_per_face(face_no); ++i) + sum += interpolation_matrix(j, i); - Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + Assert(std::fabs(sum - 1) < eps, ExcInternalError()); + } } -#endif } else if (dynamic_cast *>(&source_fe) != nullptr) { diff --git a/source/fe/fe_simplex_p_bubbles.cc b/source/fe/fe_simplex_p_bubbles.cc index 8ba986b41c..fa10c23f21 100644 --- a/source/fe/fe_simplex_p_bubbles.cc +++ b/source/fe/fe_simplex_p_bubbles.cc @@ -217,18 +217,19 @@ namespace FE_P_BubblesImplementation for (auto &p : bubble_functions) lump_polys.push_back(std::move(p)); - // Sanity check: -#ifdef DEBUG - BarycentricPolynomial unity; - for (const auto &p : lump_polys) - unity = unity + p; - - Point test; - for (unsigned int d = 0; d < dim; ++d) - test[d] = 2.0; - Assert(std::abs(unity.value(test) - 1.0) < 1e-10, - ExcInternalError()); -#endif + // Sanity check: + if constexpr (running_in_debug_mode()) + { + BarycentricPolynomial unity; + for (const auto &p : lump_polys) + unity = unity + p; + + Point test; + for (unsigned int d = 0; d < dim; ++d) + test[d] = 2.0; + Assert(std::abs(unity.value(test) - 1.0) < 1e-10, + ExcInternalError()); + } return BarycentricPolynomials(lump_polys); } diff --git a/source/fe/fe_system.cc b/source/fe/fe_system.cc index 67aeb6365a..0b2be1f0c4 100644 --- a/source/fe/fe_system.cc +++ b/source/fe/fe_system.cc @@ -1936,23 +1936,24 @@ FESystem::initialize( } } -# ifdef DEBUG - // check generalized_support_points_index_table for consistency - for (unsigned int i = 0; i < base_elements.size(); ++i) + if constexpr (running_in_debug_mode()) { - if (!base_element(i).has_generalized_support_points()) - continue; - - const auto &points = - base_elements[i].first->get_generalized_support_points(); - for (unsigned int j = 0; j < points.size(); ++j) + // check generalized_support_points_index_table for consistency + for (unsigned int i = 0; i < base_elements.size(); ++i) { - const auto n = generalized_support_points_index_table[i][j]; - Assert(this->generalized_support_points[n] == points[j], - ExcInternalError()); + if (!base_element(i).has_generalized_support_points()) + continue; + + const auto &points = + base_elements[i].first->get_generalized_support_points(); + for (unsigned int j = 0; j < points.size(); ++j) + { + const auto n = generalized_support_points_index_table[i][j]; + Assert(this->generalized_support_points[n] == points[j], + ExcInternalError()); + } } - } -# endif /* DEBUG */ + } /* DEBUG */ }); // initialize quad dof index permutation in 3d and higher diff --git a/source/fe/mapping_q.cc b/source/fe/mapping_q.cc index 6b00d4aa19..5b4d7faa13 100644 --- a/source/fe/mapping_q.cc +++ b/source/fe/mapping_q.cc @@ -1634,28 +1634,30 @@ MappingQ<3, 3>::add_quad_support_points( { const Triangulation<3>::face_iterator face = cell->face(face_no); -#ifdef DEBUG - const bool face_orientation = cell->face_orientation(face_no), - face_flip = cell->face_flip(face_no), - face_rotation = cell->face_rotation(face_no); - const unsigned int vertices_per_face = GeometryInfo<3>::vertices_per_face, - lines_per_face = GeometryInfo<3>::lines_per_face; - - // some sanity checks up front - for (unsigned int i = 0; i < vertices_per_face; ++i) - Assert(face->vertex_index(i) == - cell->vertex_index(GeometryInfo<3>::face_to_cell_vertices( - face_no, i, face_orientation, face_flip, face_rotation)), - ExcInternalError()); - - // indices of the lines that bound a face are given by GeometryInfo<3>:: - // face_to_cell_lines - for (unsigned int i = 0; i < lines_per_face; ++i) - Assert(face->line(i) == - cell->line(GeometryInfo<3>::face_to_cell_lines( - face_no, i, face_orientation, face_flip, face_rotation)), - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + const bool face_orientation = cell->face_orientation(face_no), + face_flip = cell->face_flip(face_no), + face_rotation = cell->face_rotation(face_no); + const unsigned int vertices_per_face = + GeometryInfo<3>::vertices_per_face, + lines_per_face = GeometryInfo<3>::lines_per_face; + + // some sanity checks up front + for (unsigned int i = 0; i < vertices_per_face; ++i) + Assert(face->vertex_index(i) == + cell->vertex_index(GeometryInfo<3>::face_to_cell_vertices( + face_no, i, face_orientation, face_flip, face_rotation)), + ExcInternalError()); + + // indices of the lines that bound a face are given by + // GeometryInfo<3>:: face_to_cell_lines + for (unsigned int i = 0; i < lines_per_face; ++i) + Assert(face->line(i) == + cell->line(GeometryInfo<3>::face_to_cell_lines( + face_no, i, face_orientation, face_flip, face_rotation)), + ExcInternalError()); + } // extract the points surrounding a quad from the points // already computed. First get the 4 vertices and then the points on // the four lines diff --git a/source/grid/grid_generator.cc b/source/grid/grid_generator.cc index 5f8bc68054..b2954e83da 100644 --- a/source/grid/grid_generator.cc +++ b/source/grid/grid_generator.cc @@ -1623,14 +1623,16 @@ namespace GridGenerator Assert(dim > 1, ExcNotImplemented()); Assert(dim < 4, ExcNotImplemented()); -# ifdef DEBUG - Tensor<2, dim> vector_matrix; - for (unsigned int d = 0; d < dim; ++d) - for (unsigned int c = 1; c <= dim; ++c) - vector_matrix[c - 1][d] = vertices[c][d] - vertices[0][d]; - Assert(determinant(vector_matrix) > 0., - ExcMessage("Vertices of simplex must form a right handed system")); -# endif + if constexpr (running_in_debug_mode()) + { + Tensor<2, dim> vector_matrix; + for (unsigned int d = 0; d < dim; ++d) + for (unsigned int c = 1; c <= dim; ++c) + vector_matrix[c - 1][d] = vertices[c][d] - vertices[0][d]; + Assert(determinant(vector_matrix) > 0., + ExcMessage( + "Vertices of simplex must form a right handed system")); + } // Set up the vertices by first copying into points. std::vector> points = vertices; @@ -2678,17 +2680,18 @@ namespace GridGenerator std::reverse(step_sizes[i].begin(), step_sizes[i].end()); } -# ifdef DEBUG - double x = 0; - for (unsigned int j = 0; j < step_sizes.at(i).size(); ++j) - x += step_sizes[i][j]; - Assert(std::fabs(x - (p2[i] - p1[i])) <= 1e-12 * std::fabs(x), - ExcMessage( - "The sequence of step sizes in coordinate direction " + - Utilities::int_to_string(i) + - " must be equal to the distance of the two given " - "points in this coordinate direction.")); -# endif + if constexpr (running_in_debug_mode()) + { + double x = 0; + for (unsigned int j = 0; j < step_sizes.at(i).size(); ++j) + x += step_sizes[i][j]; + Assert(std::fabs(x - (p2[i] - p1[i])) <= 1e-12 * std::fabs(x), + ExcMessage( + "The sequence of step sizes in coordinate direction " + + Utilities::int_to_string(i) + + " must be equal to the distance of the two given " + "points in this coordinate direction.")); + } } @@ -6850,12 +6853,14 @@ namespace GridGenerator Triangulation &result) { AssertDimension(dim, extents.size()); -# ifdef DEBUG - for (const auto &extent : extents) - Assert(0 < extent, - ExcMessage("The Triangulation must be copied at least one time in " - "each coordinate dimension.")); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &extent : extents) + Assert(0 < extent, + ExcMessage( + "The Triangulation must be copied at least one time in " + "each coordinate dimension.")); + } const BoundingBox bbox(input.get_vertices()); const auto &min = bbox.get_boundary_points().first; const auto &max = bbox.get_boundary_points().second; @@ -7135,40 +7140,43 @@ namespace GridGenerator // mode) if (0 < manifold_priorities.size()) { -# ifdef DEBUG - // check that the provided manifold_priorities is valid - std::vector sorted_manifold_priorities = - manifold_priorities; - std::sort(sorted_manifold_priorities.begin(), - sorted_manifold_priorities.end()); - Assert(std::unique(sorted_manifold_priorities.begin(), - sorted_manifold_priorities.end()) == - sorted_manifold_priorities.end(), - ExcMessage( - "The given vector of manifold ids may not contain any " - "duplicated entries.")); - std::vector sorted_manifold_ids = - input.get_manifold_ids(); - std::sort(sorted_manifold_ids.begin(), sorted_manifold_ids.end()); - if (sorted_manifold_priorities != sorted_manifold_ids) + if constexpr (running_in_debug_mode()) { - std::ostringstream message; - message << "The given triangulation has manifold ids {"; - for (const types::manifold_id manifold_id : sorted_manifold_ids) - if (manifold_id != sorted_manifold_ids.back()) - message << manifold_id << ", "; - message << sorted_manifold_ids.back() << "}, but \n" - << " the given vector of manifold ids is {"; - for (const types::manifold_id manifold_id : manifold_priorities) - if (manifold_id != manifold_priorities.back()) - message << manifold_id << ", "; - message - << manifold_priorities.back() << "}.\n" - << " These vectors should contain the same elements.\n"; - const std::string m = message.str(); - Assert(false, ExcMessage(m)); + // check that the provided manifold_priorities is valid + std::vector sorted_manifold_priorities = + manifold_priorities; + std::sort(sorted_manifold_priorities.begin(), + sorted_manifold_priorities.end()); + Assert(std::unique(sorted_manifold_priorities.begin(), + sorted_manifold_priorities.end()) == + sorted_manifold_priorities.end(), + ExcMessage( + "The given vector of manifold ids may not contain any " + "duplicated entries.")); + std::vector sorted_manifold_ids = + input.get_manifold_ids(); + std::sort(sorted_manifold_ids.begin(), sorted_manifold_ids.end()); + if (sorted_manifold_priorities != sorted_manifold_ids) + { + std::ostringstream message; + message << "The given triangulation has manifold ids {"; + for (const types::manifold_id manifold_id : + sorted_manifold_ids) + if (manifold_id != sorted_manifold_ids.back()) + message << manifold_id << ", "; + message << sorted_manifold_ids.back() << "}, but \n" + << " the given vector of manifold ids is {"; + for (const types::manifold_id manifold_id : + manifold_priorities) + if (manifold_id != manifold_priorities.back()) + message << manifold_id << ", "; + message + << manifold_priorities.back() << "}.\n" + << " These vectors should contain the same elements.\n"; + const std::string m = message.str(); + Assert(false, ExcMessage(m)); + } } -# endif return manifold_priorities; } // otherwise use the default ranking: ascending order, but TFI manifolds diff --git a/source/grid/grid_generator_pipe_junction.cc b/source/grid/grid_generator_pipe_junction.cc index bad74ee667..ac220f2959 100644 --- a/source/grid/grid_generator_pipe_junction.cc +++ b/source/grid/grid_generator_pipe_junction.cc @@ -290,15 +290,17 @@ namespace GridGenerator constexpr unsigned int n_pipes = 3; constexpr double tolerance = 1.e-12; -# ifdef DEBUG - // Verify user input. - Assert(bifurcation.second > 0, - ExcMessage("Invalid input: negative radius.")); - Assert(openings.size() == n_pipes, - ExcMessage("Invalid input: only 3 openings allowed.")); - for (const auto &opening : openings) - Assert(opening.second > 0, ExcMessage("Invalid input: negative radius.")); -# endif + if constexpr (running_in_debug_mode()) + { + // Verify user input. + Assert(bifurcation.second > 0, + ExcMessage("Invalid input: negative radius.")); + Assert(openings.size() == n_pipes, + ExcMessage("Invalid input: only 3 openings allowed.")); + for (const auto &opening : openings) + Assert(opening.second > 0, + ExcMessage("Invalid input: negative radius.")); + } // Each pipe segment will be identified by the index of its opening in the // parameter array. To determine the next and previous entry in the array diff --git a/source/grid/grid_in.cc b/source/grid/grid_in.cc index b44074905b..9a10891f71 100644 --- a/source/grid/grid_in.cc +++ b/source/grid/grid_in.cc @@ -2848,17 +2848,19 @@ GridIn::read_msh(const std::string &fname) AssertDimension(node_tags[i], i + 1); for (unsigned int d = 0; d < spacedim; ++d) vertices[i][d] = coord[i * 3 + d]; -# ifdef DEBUG - // Make sure the embedded dimension is right - for (unsigned int d = spacedim; d < 3; ++d) - Assert(std::abs(coord[i * 3 + d]) < 1e-10, - ExcMessage("The grid you are reading contains nodes that are " - "nonzero in the coordinate with index " + - std::to_string(d) + - ", but you are trying to save " - "it on a grid embedded in a " + - std::to_string(spacedim) + " dimensional space.")); -# endif + if constexpr (running_in_debug_mode()) + { + // Make sure the embedded dimension is right + for (unsigned int d = spacedim; d < 3; ++d) + Assert(std::abs(coord[i * 3 + d]) < 1e-10, + ExcMessage( + "The grid you are reading contains nodes that are " + "nonzero in the coordinate with index " + + std::to_string(d) + + ", but you are trying to save " + "it on a grid embedded in a " + + std::to_string(spacedim) + " dimensional space.")); + } } } diff --git a/source/grid/grid_tools.cc b/source/grid/grid_tools.cc index eb525ccb0d..5594f47c44 100644 --- a/source/grid/grid_tools.cc +++ b/source/grid/grid_tools.cc @@ -959,13 +959,14 @@ namespace GridTools vertex_to_point = p - mesh.get_vertices()[closest_vertex_index]; } -#ifdef DEBUG - { - // Double-check if found index is at marked cell - Assert(any_cell_marked(vertex_to_cells[closest_vertex_index]), - dealii::ExcMessage("Found non-marked vertex")); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + // Double-check if found index is at marked cell + Assert(any_cell_marked(vertex_to_cells[closest_vertex_index]), + dealii::ExcMessage("Found non-marked vertex")); + } + } const double vertex_point_norm = vertex_to_point.norm(); if (vertex_point_norm > 0) @@ -3474,23 +3475,24 @@ namespace GridTools AssertDimension(cells_out.size(), maps_out.size()); AssertDimension(cells_out.size(), qpoints_out.size()); -#ifdef DEBUG - unsigned int c = cells_out.size(); - unsigned int qps = 0; - // The number of points in all - // the cells must be the same as - // the number of points we - // started off from, - // plus the points which were ignored - for (unsigned int n = 0; n < c; ++n) + if constexpr (running_in_debug_mode()) { - AssertDimension(qpoints_out[n].size(), maps_out[n].size()); - qps += qpoints_out[n].size(); - } + unsigned int c = cells_out.size(); + unsigned int qps = 0; + // The number of points in all + // the cells must be the same as + // the number of points we + // started off from, + // plus the points which were ignored + for (unsigned int n = 0; n < c; ++n) + { + AssertDimension(qpoints_out[n].size(), maps_out[n].size()); + qps += qpoints_out[n].size(); + } - Assert(qps + missing_points_out.size() == np, - ExcDimensionMismatch(qps + missing_points_out.size(), np)); -#endif + Assert(qps + missing_points_out.size() == np, + ExcDimensionMismatch(qps + missing_points_out.size(), np)); + } return std::make_tuple(std::move(cells_out), std::move(qpoints_out), diff --git a/source/grid/grid_tools_dof_handlers.cc b/source/grid/grid_tools_dof_handlers.cc index a32a74f8c2..009e8d3274 100644 --- a/source/grid/grid_tools_dof_handlers.cc +++ b/source/grid/grid_tools_dof_handlers.cc @@ -2132,26 +2132,27 @@ namespace GridTools (void)space_dim; AssertIndexRange(direction, space_dim); -#ifdef DEBUG - { - constexpr int dim = CellIterator::AccessorType::dimension; - constexpr int spacedim = CellIterator::AccessorType::space_dimension; - // For parallel::fullydistributed::Triangulation there might be unmatched - // faces on periodic boundaries on the coarse grid. As a result - // this assert is not fulfilled (which is not a bug!). See also the - // discussion in the method collect_periodic_faces. - if (!(((pairs1.size() > 0) && - (dynamic_cast *>( - &pairs1.begin()->first->get_triangulation()) != nullptr)) || - ((pairs2.size() > 0) && - (dynamic_cast< - const parallel::fullydistributed::Triangulation - *>(&pairs2.begin()->first->get_triangulation()) != nullptr)))) - Assert(pairs1.size() == pairs2.size(), - ExcMessage("Unmatched faces on periodic boundaries")); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + constexpr int dim = CellIterator::AccessorType::dimension; + constexpr int spacedim = CellIterator::AccessorType::space_dimension; + // For parallel::fullydistributed::Triangulation there might be + // unmatched faces on periodic boundaries on the coarse grid. As a + // result this assert is not fulfilled (which is not a bug!). See also + // the discussion in the method collect_periodic_faces. + if (!(((pairs1.size() > 0) && + (dynamic_cast *>( + &pairs1.begin()->first->get_triangulation()) != nullptr)) || + ((pairs2.size() > 0) && + (dynamic_cast *>( + &pairs2.begin()->first->get_triangulation()) != nullptr)))) + Assert(pairs1.size() == pairs2.size(), + ExcMessage("Unmatched faces on periodic boundaries")); + } + } unsigned int n_matches = 0; @@ -2269,27 +2270,26 @@ namespace GridTools "Are you sure that you've selected the correct boundary " "id's and that the coarsest level mesh is colorized?")); -#ifdef DEBUG - const unsigned int size_old = matched_pairs.size(); -#endif + [[maybe_unused]] const unsigned int size_old = matched_pairs.size(); // and call match_periodic_face_pairs that does the actual matching: match_periodic_face_pairs( pairs1, pairs2, direction, matched_pairs, offset, matrix); -#ifdef DEBUG - // check for standard orientation - const unsigned int size_new = matched_pairs.size(); - for (unsigned int i = size_old; i < size_new; ++i) + if constexpr (running_in_debug_mode()) { - Assert(matched_pairs[i].orientation == - numbers::default_geometric_orientation, - ExcMessage( - "Found a face match with non standard orientation. " - "This function is only suitable for meshes with cells " - "in default orientation")); + // check for standard orientation + const unsigned int size_new = matched_pairs.size(); + for (unsigned int i = size_old; i < size_new; ++i) + { + Assert(matched_pairs[i].orientation == + numbers::default_geometric_orientation, + ExcMessage( + "Found a face match with non standard orientation. " + "This function is only suitable for meshes with cells " + "in default orientation")); + } } -#endif } diff --git a/source/grid/grid_tools_geometry.cc b/source/grid/grid_tools_geometry.cc index b2c61369e5..6e8a045052 100644 --- a/source/grid/grid_tools_geometry.cc +++ b/source/grid/grid_tools_geometry.cc @@ -48,12 +48,14 @@ namespace GridTools // tria.n_levels()==1, since this is something that can happen on one // processor without being true on all. however, we can ask for the // global number of active cells and use that -#ifdef DEBUG - if (const auto *p_tria = dynamic_cast< - const parallel::DistributedTriangulationBase *>(&tria)) - Assert(p_tria->n_global_active_cells() == tria.n_cells(0), - ExcNotImplemented()); -#endif + if constexpr (running_in_debug_mode()) + { + if (const auto *p_tria = dynamic_cast< + const parallel::DistributedTriangulationBase *>( + &tria)) + Assert(p_tria->n_global_active_cells() == tria.n_cells(0), + ExcNotImplemented()); + } // the algorithm used simply traverses all cells and picks out the // boundary vertices. it may or may not be faster to simply get all diff --git a/source/grid/grid_tools_topology.cc b/source/grid/grid_tools_topology.cc index 46d8e0a242..90a52814d0 100644 --- a/source/grid/grid_tools_topology.cc +++ b/source/grid/grid_tools_topology.cc @@ -66,22 +66,23 @@ namespace GridTools std::begin(b.vertices), std::end(b.vertices))) return true; - // it should never be necessary to check the material or manifold - // ids as a 'tiebreaker' (since they must be equal if the vertex - // indices are equal). Assert it anyway: -#ifdef DEBUG - if (std::equal(std::begin(a.vertices), - std::end(a.vertices), - std::begin(b.vertices))) + // it should never be necessary to check the material or manifold + // ids as a 'tiebreaker' (since they must be equal if the vertex + // indices are equal). Assert it anyway: + if constexpr (running_in_debug_mode()) { - Assert(a.material_id == b.material_id && - a.manifold_id == b.manifold_id, - ExcMessage( - "Two CellData objects with equal vertices must " - "have the same material/boundary ids and manifold " - "ids.")); + if (std::equal(std::begin(a.vertices), + std::end(a.vertices), + std::begin(b.vertices))) + { + Assert(a.material_id == b.material_id && + a.manifold_id == b.manifold_id, + ExcMessage( + "Two CellData objects with equal vertices must " + "have the same material/boundary ids and manifold " + "ids.")); + } } -#endif return false; } }; diff --git a/source/grid/manifold_lib.cc b/source/grid/manifold_lib.cc index e4c4b9bbf0..e33d2d6931 100644 --- a/source/grid/manifold_lib.cc +++ b/source/grid/manifold_lib.cc @@ -1471,17 +1471,19 @@ FunctionManifold::push_forward( for (unsigned int i = 0; i < spacedim; ++i) result[i] = pf[i]; -#ifdef DEBUG - Vector pb(chartdim); - pull_back_function->vector_value(result, pb); - for (unsigned int i = 0; i < chartdim; ++i) - Assert( - (chart_point.norm() > tolerance && - (std::abs(pb[i] - chart_point[i]) < tolerance * chart_point.norm())) || - (std::abs(pb[i] - chart_point[i]) < tolerance), - ExcMessage( - "The push forward is not the inverse of the pull back! Bailing out.")); -#endif + if constexpr (running_in_debug_mode()) + { + Vector pb(chartdim); + pull_back_function->vector_value(result, pb); + for (unsigned int i = 0; i < chartdim; ++i) + Assert( + (chart_point.norm() > tolerance && + (std::abs(pb[i] - chart_point[i]) < + tolerance * chart_point.norm())) || + (std::abs(pb[i] - chart_point[i]) < tolerance), + ExcMessage( + "The push forward is not the inverse of the pull back! Bailing out.")); + } return result; } diff --git a/source/grid/tria.cc b/source/grid/tria.cc index cb23ea896f..c100085ca3 100644 --- a/source/grid/tria.cc +++ b/source/grid/tria.cc @@ -1663,21 +1663,22 @@ namespace const auto inverse_orientation = face_1->reference_cell().get_inverse_combined_orientation(orientation); -#ifdef DEBUG - const auto [face_orientation, face_rotation, face_flip] = - internal::split_face_orientation(orientation); - - Assert((dim != 1) || (face_orientation == true && face_flip == false && - face_rotation == false), - ExcMessage("The supplied orientation " - "(face_orientation, face_flip, face_rotation) " - "is invalid for 1d")); - - Assert((dim != 2) || (face_flip == false && face_rotation == false), - ExcMessage("The supplied orientation " - "(face_orientation, face_flip, face_rotation) " - "is invalid for 2d")); -#endif + if constexpr (running_in_debug_mode()) + { + const auto [face_orientation, face_rotation, face_flip] = + internal::split_face_orientation(orientation); + + Assert((dim != 1) || (face_orientation == true && face_flip == false && + face_rotation == false), + ExcMessage("The supplied orientation " + "(face_orientation, face_flip, face_rotation) " + "is invalid for 1d")); + + Assert((dim != 2) || (face_flip == false && face_rotation == false), + ExcMessage("The supplied orientation " + "(face_orientation, face_flip, face_rotation) " + "is invalid for 2d")); + } Assert(face_1 != face_2, ExcMessage("face_1 and face_2 are equal!")); @@ -6131,25 +6132,28 @@ namespace internal triangulation.vertices_used.resize(needed_vertices, false); } - //----------------------------------------- - // Before we start with the actual refinement, we do some - // sanity checks if in debug mode. especially, we try to catch - // the notorious problem with lines being twice refined, - // i.e. there are cells adjacent at one line ("around the - // edge", but not at a face), with two cells differing by more - // than one refinement level - // - // this check is very simple to implement here, since we have - // all lines flagged if they shall be refined -#ifdef DEBUG - for (const auto &cell : triangulation.active_cell_iterators()) - if (!cell->refine_flag_set()) - for (unsigned int line_n = 0; line_n < cell->n_lines(); ++line_n) - if (cell->line(line_n)->has_children()) - for (unsigned int c = 0; c < 2; ++c) - Assert(cell->line(line_n)->child(c)->user_flag_set() == false, - ExcInternalError()); -#endif + //----------------------------------------- + // Before we start with the actual refinement, we do some + // sanity checks if in debug mode. especially, we try to catch + // the notorious problem with lines being twice refined, + // i.e. there are cells adjacent at one line ("around the + // edge", but not at a face), with two cells differing by more + // than one refinement level + // + // this check is very simple to implement here, since we have + // all lines flagged if they shall be refined + if constexpr (running_in_debug_mode()) + { + for (const auto &cell : triangulation.active_cell_iterators()) + if (!cell->refine_flag_set()) + for (unsigned int line_n = 0; line_n < cell->n_lines(); + ++line_n) + if (cell->line(line_n)->has_children()) + for (unsigned int c = 0; c < 2; ++c) + Assert(cell->line(line_n)->child(c)->user_flag_set() == + false, + ExcInternalError()); + } unsigned int current_vertex = 0; @@ -6261,10 +6265,11 @@ namespace internal DEAL_II_NOT_IMPLEMENTED(); } -#ifdef DEBUG - for (const unsigned int line : quad->line_indices()) - AssertIsNotUsed(new_lines[line]); -#endif + if constexpr (running_in_debug_mode()) + { + for (const unsigned int line : quad->line_indices()) + AssertIsNotUsed(new_lines[line]); + } // 2) create new quads (properties are set below). Both triangles // and quads are divided in four. @@ -6282,10 +6287,11 @@ namespace internal } quad->set_refinement_case(RefinementCase<2>::cut_xy); -#ifdef DEBUG - for (const auto &quad : new_quads) - AssertIsNotUsed(quad); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &quad : new_quads) + AssertIsNotUsed(quad); + } // 3) set vertex indices and set new vertex @@ -6428,9 +6434,7 @@ namespace internal new_quad->set_boundary_id_internal(quad->boundary_id()); new_quad->set_manifold_id(quad->manifold_id()); -#ifdef DEBUG - std::set s; -#endif + [[maybe_unused]] std::set s; // ... and fix orientation of lines of face for triangles, // using an expensive algorithm, quadrilaterals are treated @@ -6452,18 +6456,22 @@ namespace internal make_array_view(vertices_0), make_array_view(vertices_1)); -#ifdef DEBUG - for (const auto i : vertices_0) - s.insert(i); - for (const auto i : vertices_1) - s.insert(i); -#endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + for (const auto i : vertices_0) + s.insert(i); + for (const auto i : vertices_1) + s.insert(i); + } new_quad->set_line_orientation(f, orientation); } -#ifdef DEBUG - AssertDimension(s.size(), 3); -#endif + if constexpr (library_build_mode == + LibraryBuildMode::debug) + { + AssertDimension(s.size(), 3); + } } } @@ -7418,27 +7426,29 @@ namespace internal } - //----------------------------------------- - // Before we start with the actual refinement, we do some - // sanity checks if in debug mode. especially, we try to catch - // the notorious problem with lines being twice refined, - // i.e. there are cells adjacent at one line ("around the - // edge", but not at a face), with two cells differing by more - // than one refinement level - // - // this check is very simple to implement here, since we have - // all lines flagged if they shall be refined -#ifdef DEBUG - for (const auto &cell : triangulation.active_cell_iterators()) - if (!cell->refine_flag_set()) - for (unsigned int line = 0; - line < GeometryInfo::lines_per_cell; - ++line) - if (cell->line(line)->has_children()) - for (unsigned int c = 0; c < 2; ++c) - Assert(cell->line(line)->child(c)->user_flag_set() == false, - ExcInternalError()); -#endif + //----------------------------------------- + // Before we start with the actual refinement, we do some + // sanity checks if in debug mode. especially, we try to catch + // the notorious problem with lines being twice refined, + // i.e. there are cells adjacent at one line ("around the + // edge", but not at a face), with two cells differing by more + // than one refinement level + // + // this check is very simple to implement here, since we have + // all lines flagged if they shall be refined + if constexpr (running_in_debug_mode()) + { + for (const auto &cell : triangulation.active_cell_iterators()) + if (!cell->refine_flag_set()) + for (unsigned int line = 0; + line < GeometryInfo::lines_per_cell; + ++line) + if (cell->line(line)->has_children()) + for (unsigned int c = 0; c < 2; ++c) + Assert(cell->line(line)->child(c)->user_flag_set() == + false, + ExcInternalError()); + } //----------------------------------------- // Do refinement on every level @@ -15875,50 +15885,50 @@ void Triangulation::execute_coarsening_and_refinement() if (this->cell_attached_data.n_attached_data_sets == 0) this->update_cell_relations(); -# ifdef DEBUG - - // In debug mode, we want to check for some consistency of the - // result of this function. Because there are multiple exit - // paths, put this check into a ScopeExit object that is - // executed on each of the exit paths. - // - // Specifically, check on exit of this function that if a quad - // cell has been refined, all of its children have neighbors - // in all directions in which the parent cell has neighbors as - // well. The children's neighbors are either the parent - // neighbor or the parent neighbor's children, or simply one of - // the other children of the current cell. This check is - // useful because if one creates a triangulation with an - // inconsistently ordered set of cells (e.g., because one has - // forgotten to call GridTools::consistently_order_cells()), - // then this relatively simple invariant is violated -- so the - // check here can be used to catch that case, at least - // sometimes. - // - // In 1d, this situation cannot happen. In 3d, we have explicit - // orientation flags to ensure that it is not necessary to re-orient - // cells at the beginning. But in both cases, the invariant should - // still hold as long as the cell is a hypercube. - for (const auto &cell : cell_iterators()) + if constexpr (running_in_debug_mode()) { - if (cell->has_children() && cell->reference_cell().is_hyper_cube()) - for (const unsigned int f : cell->face_indices()) - if (cell->at_boundary(f) == false) - { - for (const auto &child : cell->child_iterators()) + // In debug mode, we want to check for some consistency of the + // result of this function. Because there are multiple exit + // paths, put this check into a ScopeExit object that is + // executed on each of the exit paths. + // + // Specifically, check on exit of this function that if a quad + // cell has been refined, all of its children have neighbors + // in all directions in which the parent cell has neighbors as + // well. The children's neighbors are either the parent + // neighbor or the parent neighbor's children, or simply one of + // the other children of the current cell. This check is + // useful because if one creates a triangulation with an + // inconsistently ordered set of cells (e.g., because one has + // forgotten to call GridTools::consistently_order_cells()), + // then this relatively simple invariant is violated -- so the + // check here can be used to catch that case, at least + // sometimes. + // + // In 1d, this situation cannot happen. In 3d, we have explicit + // orientation flags to ensure that it is not necessary to re-orient + // cells at the beginning. But in both cases, the invariant should + // still hold as long as the cell is a hypercube. + for (const auto &cell : cell_iterators()) + { + if (cell->has_children() && cell->reference_cell().is_hyper_cube()) + for (const unsigned int f : cell->face_indices()) + if (cell->at_boundary(f) == false) { - Assert( - child->at_boundary(f) == false, - ExcMessage( - "We ended up with a triangulation whose child cells " - "are not connected to their neighbors as expected. " - "When you created the triangulation, did you forget " - "to call GridTools::consistently_order_cells() " - "before calling Triangulation::create_triangulation()?")); + for (const auto &child : cell->child_iterators()) + { + Assert( + child->at_boundary(f) == false, + ExcMessage( + "We ended up with a triangulation whose child cells " + "are not connected to their neighbors as expected. " + "When you created the triangulation, did you forget " + "to call GridTools::consistently_order_cells() " + "before calling Triangulation::create_triangulation()?")); + } } - } + } } -# endif } @@ -16327,16 +16337,17 @@ void Triangulation::load_attached_data( this->data_serializer.unpack_cell_status(this->local_cell_relations); -# ifdef DEBUG - // the CellStatus of all stored cells should always be - // CellStatus::cell_will_persist. - for (const auto &cell_rel : this->local_cell_relations) + if constexpr (running_in_debug_mode()) { - Assert((cell_rel.second == // cell_status - ::dealii::CellStatus::cell_will_persist), - ExcInternalError()); + // the CellStatus of all stored cells should always be + // CellStatus::cell_will_persist. + for (const auto &cell_rel : this->local_cell_relations) + { + Assert((cell_rel.second == // cell_status + ::dealii::CellStatus::cell_will_persist), + ExcInternalError()); + } } -# endif } } @@ -16389,17 +16400,18 @@ typename Triangulation::DistortedCellList internal::TriangulationImplementation::Implementation::compute_number_cache( *this, levels.size(), number_cache); -# ifdef DEBUG - for (const auto &level : levels) - monitor_memory(level->cells, dim); - - // check whether really all refinement flags are reset (also of - // previously non-active cells which we may not have touched. If the - // refinement flag of a non-active cell is set, something went wrong - // since the cell-accessors should have caught this) - for (const auto &cell : this->cell_iterators()) - Assert(!cell->refine_flag_set(), ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &level : levels) + monitor_memory(level->cells, dim); + + // check whether really all refinement flags are reset (also of + // previously non-active cells which we may not have touched. If the + // refinement flag of a non-active cell is set, something went wrong + // since the cell-accessors should have caught this) + for (const auto &cell : this->cell_iterators()) + Assert(!cell->refine_flag_set(), ExcInternalError()); + } return cells_with_distorted_children; } @@ -16768,31 +16780,34 @@ namespace { Assert(cell->is_active(), ExcInternalError()); -#ifdef DEBUG - // If this is not a parallel::distributed::Triangulation, then we really - // should only get here if the cell is marked for refinement: - if (dynamic_cast - *>(&cell->get_triangulation()) == nullptr) - Assert(cell->refine_flag_set() == false, ExcInternalError()); - else - // But if this is a p::d::Triangulation, then we don't have that - // much control and we can get here because mesh smoothing is - // requested but can not be honored because p4est controls - // what gets refined. In that case, we can at least provide - // a better error message. - Assert(cell->refine_flag_set() == false, - ExcMessage( - "The triangulation is trying to avoid unrefined islands " - "during mesh refinement/coarsening, as you had requested " - " by passing the appropriate 'smoothing flags' to the " - "constructor of the triangulation. However, for objects " - "of type parallel::distributed::Triangulation, control " - "over which cells get refined rests with p4est, not the " - "deal.II triangulation, and consequently it is not " - "always possible to avoid unrefined islands in the mesh. " - "Please remove the constructor argument to the triangulation " - "object that requests mesh smoothing.")); -#endif + if constexpr (running_in_debug_mode()) + { + // If this is not a parallel::distributed::Triangulation, then we really + // should only get here if the cell is marked for refinement: + if (dynamic_cast< + const parallel::distributed::Triangulation *>( + &cell->get_triangulation()) == nullptr) + Assert(cell->refine_flag_set() == false, ExcInternalError()); + else + // But if this is a p::d::Triangulation, then we don't have that + // much control and we can get here because mesh smoothing is + // requested but can not be honored because p4est controls + // what gets refined. In that case, we can at least provide + // a better error message. + Assert( + cell->refine_flag_set() == false, + ExcMessage( + "The triangulation is trying to avoid unrefined islands " + "during mesh refinement/coarsening, as you had requested " + " by passing the appropriate 'smoothing flags' to the " + "constructor of the triangulation. However, for objects " + "of type parallel::distributed::Triangulation, control " + "over which cells get refined rests with p4est, not the " + "deal.II triangulation, and consequently it is not " + "always possible to avoid unrefined islands in the mesh. " + "Please remove the constructor argument to the triangulation " + "object that requests mesh smoothing.")); + } // now we provide two algorithms. the first one is the standard // one, coming from the time, where only isotropic refinement was diff --git a/source/grid/tria_accessor.cc b/source/grid/tria_accessor.cc index e15de30584..6055f6c58b 100644 --- a/source/grid/tria_accessor.cc +++ b/source/grid/tria_accessor.cc @@ -3368,60 +3368,63 @@ CellAccessor::neighbor_child_on_subface( neighbor_child->child(GeometryInfo::child_cell_on_face( neighbor_child->refinement_case(), neighbor_neighbor, 0)); -#ifdef DEBUG - // check, whether the face neighbor_child matches the requested - // subface. - typename Triangulation::face_iterator requested; - switch (this->subface_case(face)) + if constexpr (running_in_debug_mode()) { - case internal::SubfaceCase<3>::case_x: - case internal::SubfaceCase<3>::case_y: - case internal::SubfaceCase<3>::case_xy: - requested = mother_face->child(subface); - break; - case internal::SubfaceCase<3>::case_x1y2y: - case internal::SubfaceCase<3>::case_y1x2x: - requested = - mother_face->child(subface / 2)->child(subface % 2); - break; - - case internal::SubfaceCase<3>::case_x1y: - case internal::SubfaceCase<3>::case_y1x: - switch (subface) - { - case 0: - case 1: - requested = mother_face->child(0)->child(subface); - break; - case 2: - requested = mother_face->child(1); - break; - default: - DEAL_II_ASSERT_UNREACHABLE(); - } - break; - case internal::SubfaceCase<3>::case_x2y: - case internal::SubfaceCase<3>::case_y2x: - switch (subface) - { - case 0: - requested = mother_face->child(0); - break; - case 1: - case 2: - requested = mother_face->child(1)->child(subface - 1); - break; - default: - DEAL_II_ASSERT_UNREACHABLE(); - } - break; - default: - DEAL_II_ASSERT_UNREACHABLE(); - break; + // check, whether the face neighbor_child matches the + // requested subface. + typename Triangulation::face_iterator + requested; + switch (this->subface_case(face)) + { + case internal::SubfaceCase<3>::case_x: + case internal::SubfaceCase<3>::case_y: + case internal::SubfaceCase<3>::case_xy: + requested = mother_face->child(subface); + break; + case internal::SubfaceCase<3>::case_x1y2y: + case internal::SubfaceCase<3>::case_y1x2x: + requested = + mother_face->child(subface / 2)->child(subface % 2); + break; + + case internal::SubfaceCase<3>::case_x1y: + case internal::SubfaceCase<3>::case_y1x: + switch (subface) + { + case 0: + case 1: + requested = mother_face->child(0)->child(subface); + break; + case 2: + requested = mother_face->child(1); + break; + default: + DEAL_II_ASSERT_UNREACHABLE(); + } + break; + case internal::SubfaceCase<3>::case_x2y: + case internal::SubfaceCase<3>::case_y2x: + switch (subface) + { + case 0: + requested = mother_face->child(0); + break; + case 1: + case 2: + requested = + mother_face->child(1)->child(subface - 1); + break; + default: + DEAL_II_ASSERT_UNREACHABLE(); + } + break; + default: + DEAL_II_ASSERT_UNREACHABLE(); + break; + } + Assert(requested == neighbor_child->face(neighbor_neighbor), + ExcInternalError()); } - Assert(requested == neighbor_child->face(neighbor_neighbor), - ExcInternalError()); -#endif return neighbor_child; } diff --git a/source/grid/tria_description.cc b/source/grid/tria_description.cc index 5e59980736..64667df4e0 100644 --- a/source/grid/tria_description.cc +++ b/source/grid/tria_description.cc @@ -734,25 +734,27 @@ namespace TriangulationDescription "in the given communicator.")); } -#ifdef DEBUG - // If we are dealing with a sequential triangulation, then someone - // will have needed to set the subdomain_ids by hand. Make sure that - // all ids we see are less than the number of processes we are - // supposed to split the triangulation into. - if (dynamic_cast *>( - &tria) == nullptr) + if constexpr (running_in_debug_mode()) { - const unsigned int n_mpi_processes = - dealii::Utilities::MPI::n_mpi_processes(comm); - for (const auto &cell : tria.active_cell_iterators()) - Assert(cell->subdomain_id() < n_mpi_processes, - ExcMessage("You can't have a cell with subdomain_id of " + - std::to_string(cell->subdomain_id()) + - " when splitting the triangulation using an MPI " - " communicator with only " + - std::to_string(n_mpi_processes) + " processes.")); + // If we are dealing with a sequential triangulation, then someone + // will have needed to set the subdomain_ids by hand. Make sure that + // all ids we see are less than the number of processes we are + // supposed to split the triangulation into. + if (dynamic_cast *>( + &tria) == nullptr) + { + const unsigned int n_mpi_processes = + dealii::Utilities::MPI::n_mpi_processes(comm); + for (const auto &cell : tria.active_cell_iterators()) + Assert(cell->subdomain_id() < n_mpi_processes, + ExcMessage( + "You can't have a cell with subdomain_id of " + + std::to_string(cell->subdomain_id()) + + " when splitting the triangulation using an MPI " + " communicator with only " + + std::to_string(n_mpi_processes) + " processes.")); + } } -#endif // First, figure out for what rank we are supposed to build the // TriangulationDescription::Description object diff --git a/source/hp/fe_collection.cc b/source/hp/fe_collection.cc index ba40a86976..a7c5876461 100644 --- a/source/hp/fe_collection.cc +++ b/source/hp/fe_collection.cc @@ -118,13 +118,14 @@ namespace hp const std::set &fes, const unsigned int codim) const { -#ifdef DEBUG - // Validate user inputs. - Assert(codim <= dim, ExcImpossibleInDim(dim)); - Assert(this->size() > 0, ExcEmptyObject()); - for (const auto &fe : fes) - AssertIndexRange(fe, this->size()); -#endif + if constexpr (running_in_debug_mode()) + { + // Validate user inputs. + Assert(codim <= dim, ExcImpossibleInDim(dim)); + Assert(this->size() > 0, ExcEmptyObject()); + for (const auto &fe : fes) + AssertIndexRange(fe, this->size()); + } // Check if any element of this FECollection is able to dominate all // elements of @p fes. If one was found, we add it to the set of @@ -158,13 +159,14 @@ namespace hp const std::set &fes, const unsigned int codim) const { -#ifdef DEBUG - // Validate user inputs. - Assert(codim <= dim, ExcImpossibleInDim(dim)); - Assert(this->size() > 0, ExcEmptyObject()); - for (const auto &fe : fes) - AssertIndexRange(fe, this->size()); -#endif + if constexpr (running_in_debug_mode()) + { + // Validate user inputs. + Assert(codim <= dim, ExcImpossibleInDim(dim)); + Assert(this->size() > 0, ExcEmptyObject()); + for (const auto &fe : fes) + AssertIndexRange(fe, this->size()); + } // Check if any element of this FECollection is dominated by all // elements of @p fes. If one was found, we add it to the set of @@ -203,13 +205,14 @@ namespace hp if (fes.size() == 1) return *fes.begin(); -#ifdef DEBUG - // Validate user inputs. - Assert(codim <= dim, ExcImpossibleInDim(dim)); - Assert(this->size() > 0, ExcEmptyObject()); - for (const auto &fe : fes) - AssertIndexRange(fe, this->size()); -#endif + if constexpr (running_in_debug_mode()) + { + // Validate user inputs. + Assert(codim <= dim, ExcImpossibleInDim(dim)); + Assert(this->size() > 0, ExcEmptyObject()); + for (const auto &fe : fes) + AssertIndexRange(fe, this->size()); + } // There may also be others, in which case we'll check if any of these // elements is able to dominate all others. If one was found, we stop @@ -250,13 +253,14 @@ namespace hp if (fes.size() == 1) return *fes.begin(); -#ifdef DEBUG - // Validate user inputs. - Assert(codim <= dim, ExcImpossibleInDim(dim)); - Assert(this->size() > 0, ExcEmptyObject()); - for (const auto &fe : fes) - AssertIndexRange(fe, this->size()); -#endif + if constexpr (running_in_debug_mode()) + { + // Validate user inputs. + Assert(codim <= dim, ExcImpossibleInDim(dim)); + Assert(this->size() > 0, ExcEmptyObject()); + for (const auto &fe : fes) + AssertIndexRange(fe, this->size()); + } // There may also be others, in which case we'll check if any of these // elements is dominated by all others. If one was found, we stop @@ -391,17 +395,18 @@ namespace hp identities_graph.emplace(Node(fe_index_1, identity.first), Node(fe_index_2, identity.second)); -#ifdef DEBUG - // Now verify that indeed the graph is symmetric: If one element - // declares that certain ones of its DoFs are to be unified with those - // of the other, then the other one should agree with this. As a - // consequence of this test succeeding, we know that the graph is actually - // undirected. - for (const auto &edge : identities_graph) - Assert(identities_graph.find({edge.second, edge.first}) != - identities_graph.end(), - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // Now verify that indeed the graph is symmetric: If one element + // declares that certain ones of its DoFs are to be unified with those + // of the other, then the other one should agree with this. As a + // consequence of this test succeeding, we know that the graph is + // actually undirected. + for (const auto &edge : identities_graph) + Assert(identities_graph.find({edge.second, edge.first}) != + identities_graph.end(), + ExcInternalError()); + } // The next step is that we ought to verify that if there is an identity // between (fe1,dof1) and (fe2,dof2), as well as with (fe2,dof2) and @@ -475,32 +480,35 @@ namespace hp for (const Edge &e : sub_graph) identities_graph.erase(e); -#ifdef DEBUG - // There are three checks we ought to perform: - // - That the sub-graph is undirected, i.e. that every edge appears - // in both directions - for (const auto &edge : sub_graph) - Assert(sub_graph.find({edge.second, edge.first}) != sub_graph.end(), - ExcInternalError()); - - // - None of the nodes in the sub-graph should have appeared in - // any of the other sub-graphs. If they did, then we have a bug - // in extracting sub-graphs. This is actually more easily checked - // the other way around: none of the nodes of the sub-graph we - // just extracted should be in any of the edges of the *remaining* - // graph - for (const Node &n : sub_graph_nodes) - for (const Edge &e : identities_graph) - Assert((n != e.first) && (n != e.second), ExcInternalError()); - // - Second, the sub-graph we just extracted needs to be complete, - // i.e., - // be a "clique". We check this by counting how many edges it has. - // for 'n' nodes in 'N', we need to have n*(n-1) edges (we store - // both directed edges). - Assert(sub_graph.size() == - sub_graph_nodes.size() * (sub_graph_nodes.size() - 1), - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + // There are three checks we ought to perform: + // - That the sub-graph is undirected, i.e. that every edge + // appears + // in both directions + for (const auto &edge : sub_graph) + Assert(sub_graph.find({edge.second, edge.first}) != + sub_graph.end(), + ExcInternalError()); + + // - None of the nodes in the sub-graph should have appeared in + // any of the other sub-graphs. If they did, then we have a bug + // in extracting sub-graphs. This is actually more easily + // checked the other way around: none of the nodes of the + // sub-graph we just extracted should be in any of the edges of + // the *remaining* graph + for (const Node &n : sub_graph_nodes) + for (const Edge &e : identities_graph) + Assert((n != e.first) && (n != e.second), ExcInternalError()); + // - Second, the sub-graph we just extracted needs to be complete, + // i.e., + // be a "clique". We check this by counting how many edges it + // has. for 'n' nodes in 'N', we need to have n*(n-1) edges (we + // store both directed edges). + Assert(sub_graph.size() == + sub_graph_nodes.size() * (sub_graph_nodes.size() - 1), + ExcInternalError()); + } // At this point we're sure that we have extracted a complete // sub-graph ("clique"). The DoFs involved are all identical then, and diff --git a/source/hp/refinement.cc b/source/hp/refinement.cc index 045c0f5e03..a83d7b1dfe 100644 --- a/source/hp/refinement.cc +++ b/source/hp/refinement.cc @@ -600,12 +600,13 @@ namespace hp if (future_fe_indices_on_coarsened_cells.find(parent) == future_fe_indices_on_coarsened_cells.end()) { -#ifdef DEBUG - for (const auto &child : parent->child_iterators()) - Assert(child->is_active() && child->coarsen_flag_set(), - typename Triangulation< - dim>::ExcInconsistentCoarseningFlags()); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &child : parent->child_iterators()) + Assert(child->is_active() && child->coarsen_flag_set(), + typename Triangulation< + dim>::ExcInconsistentCoarseningFlags()); + } parent_future_fe_index = internal::hp::DoFHandlerImplementation:: diff --git a/source/lac/dynamic_sparsity_pattern.cc b/source/lac/dynamic_sparsity_pattern.cc index 7bf802faa1..69a59cbd80 100644 --- a/source/lac/dynamic_sparsity_pattern.cc +++ b/source/lac/dynamic_sparsity_pattern.cc @@ -44,14 +44,15 @@ DynamicSparsityPattern::Line::add_entries(ForwardIterator begin, { // in debug mode, check whether the // indices really are sorted. -#ifdef DEBUG - { - ForwardIterator test = begin, test1 = begin; - ++test1; - for (; test1 != end; ++test, ++test1) - Assert(*test1 > *test, ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + ForwardIterator test = begin, test1 = begin; + ++test1; + for (; test1 != end; ++test, ++test1) + Assert(*test1 > *test, ExcInternalError()); + } + } if (entries.empty() || entries.back() < *begin) { diff --git a/source/lac/petsc_matrix_base.cc b/source/lac/petsc_matrix_base.cc index ada3a2220e..da5ea634d3 100644 --- a/source/lac/petsc_matrix_base.cc +++ b/source/lac/petsc_matrix_base.cc @@ -59,13 +59,14 @@ namespace PETScWrappers // iterator for an empty line (what // would it point to?) Assert(ncols != 0, ExcInternalError()); -# ifdef DEBUG - for (PetscInt j = 0; j < ncols; ++j) + if constexpr (running_in_debug_mode()) { - const auto column = static_cast(colnums[j]); - AssertIntegerConversion(column, colnums[j]); + for (PetscInt j = 0; j < ncols; ++j) + { + const auto column = static_cast(colnums[j]); + AssertIntegerConversion(column, colnums[j]); + } } -# endif colnum_cache = std::make_shared>(colnums, colnums + ncols); value_cache = @@ -165,10 +166,11 @@ namespace PETScWrappers assert_is_compressed(); // now set all the entries of these rows to zero -# ifdef DEBUG - for (const auto &row : rows) - AssertIntegerConversion(static_cast(row), row); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &row : rows) + AssertIntegerConversion(static_cast(row), row); + } const std::vector petsc_rows(rows.begin(), rows.end()); // call the functions. note that we have @@ -197,10 +199,11 @@ namespace PETScWrappers assert_is_compressed(); // now set all the entries of these rows to zero -# ifdef DEBUG - for (const auto &row : rows) - AssertIntegerConversion(static_cast(row), row); -# endif + if constexpr (running_in_debug_mode()) + { + for (const auto &row : rows) + AssertIntegerConversion(static_cast(row), row); + } const std::vector petsc_rows(rows.begin(), rows.end()); // call the functions. note that we have @@ -260,25 +263,28 @@ namespace PETScWrappers MatrixBase::compress(const VectorOperation::values operation) { { -# ifdef DEBUG - // Check that all processors agree that last_action is the same (or none!) - - int my_int_last_action = last_action; - int all_int_last_action; - - const int ierr = MPI_Allreduce(&my_int_last_action, - &all_int_last_action, - 1, - MPI_INT, - MPI_BOR, - get_mpi_communicator()); - AssertThrowMPI(ierr); - - AssertThrow(all_int_last_action != - (VectorOperation::add | VectorOperation::insert), - ExcMessage("Error: not all processors agree on the last " - "VectorOperation before this compress() call.")); -# endif + if constexpr (running_in_debug_mode()) + { + // Check that all processors agree that last_action is the same (or + // none!) + + int my_int_last_action = last_action; + int all_int_last_action; + + const int ierr = MPI_Allreduce(&my_int_last_action, + &all_int_last_action, + 1, + MPI_INT, + MPI_BOR, + get_mpi_communicator()); + AssertThrowMPI(ierr); + + AssertThrow(all_int_last_action != + (VectorOperation::add | VectorOperation::insert), + ExcMessage( + "Error: not all processors agree on the last " + "VectorOperation before this compress() call.")); + } } AssertThrow( diff --git a/source/lac/petsc_parallel_sparse_matrix.cc b/source/lac/petsc_parallel_sparse_matrix.cc index 0511b307e1..40c361ab49 100644 --- a/source/lac/petsc_parallel_sparse_matrix.cc +++ b/source/lac/petsc_parallel_sparse_matrix.cc @@ -206,30 +206,30 @@ namespace PETScWrappers Assert(local_rows.is_ascending_and_one_to_one(communicator), ExcNotImplemented()); -# ifdef DEBUG - { - // check indexsets - types::global_dof_index row_owners = - Utilities::MPI::sum(local_rows.n_elements(), communicator); - types::global_dof_index col_owners = - Utilities::MPI::sum(local_columns.n_elements(), communicator); - Assert(row_owners == sparsity_pattern.n_rows(), - ExcMessage( - std::string( - "Each row has to be owned by exactly one owner (n_rows()=") + - std::to_string(sparsity_pattern.n_rows()) + - " but sum(local_rows.n_elements())=" + - std::to_string(row_owners) + ")")); - Assert( - col_owners == sparsity_pattern.n_cols(), - ExcMessage( - std::string( - "Each column has to be owned by exactly one owner (n_cols()=") + - std::to_string(sparsity_pattern.n_cols()) + - " but sum(local_columns.n_elements())=" + - std::to_string(col_owners) + ")")); - } -# endif + if constexpr (running_in_debug_mode()) + { + // check indexsets + types::global_dof_index row_owners = + Utilities::MPI::sum(local_rows.n_elements(), communicator); + types::global_dof_index col_owners = + Utilities::MPI::sum(local_columns.n_elements(), communicator); + Assert( + row_owners == sparsity_pattern.n_rows(), + ExcMessage( + std::string( + "Each row has to be owned by exactly one owner (n_rows()=") + + std::to_string(sparsity_pattern.n_rows()) + + " but sum(local_rows.n_elements())=" + + std::to_string(row_owners) + ")")); + Assert( + col_owners == sparsity_pattern.n_cols(), + ExcMessage( + std::string( + "Each column has to be owned by exactly one owner (n_cols()=") + + std::to_string(sparsity_pattern.n_cols()) + + " but sum(local_columns.n_elements())=" + + std::to_string(col_owners) + ")")); + } // create the matrix. We do not set row length but set the @@ -517,30 +517,30 @@ namespace PETScWrappers Assert(local_rows.is_ascending_and_one_to_one(communicator), ExcNotImplemented()); -# ifdef DEBUG - { - // check indexsets - const types::global_dof_index row_owners = - Utilities::MPI::sum(local_rows.n_elements(), communicator); - const types::global_dof_index col_owners = - Utilities::MPI::sum(local_columns.n_elements(), communicator); - Assert(row_owners == sparsity_pattern.n_rows(), - ExcMessage( - std::string( - "Each row has to be owned by exactly one owner (n_rows()=") + - std::to_string(sparsity_pattern.n_rows()) + - " but sum(local_rows.n_elements())=" + - std::to_string(row_owners) + ")")); - Assert( - col_owners == sparsity_pattern.n_cols(), - ExcMessage( - std::string( - "Each column has to be owned by exactly one owner (n_cols()=") + - std::to_string(sparsity_pattern.n_cols()) + - " but sum(local_columns.n_elements())=" + - std::to_string(col_owners) + ")")); - } -# endif + if constexpr (running_in_debug_mode()) + { + // check indexsets + const types::global_dof_index row_owners = + Utilities::MPI::sum(local_rows.n_elements(), communicator); + const types::global_dof_index col_owners = + Utilities::MPI::sum(local_columns.n_elements(), communicator); + Assert( + row_owners == sparsity_pattern.n_rows(), + ExcMessage( + std::string( + "Each row has to be owned by exactly one owner (n_rows()=") + + std::to_string(sparsity_pattern.n_rows()) + + " but sum(local_rows.n_elements())=" + + std::to_string(row_owners) + ")")); + Assert( + col_owners == sparsity_pattern.n_cols(), + ExcMessage( + std::string( + "Each column has to be owned by exactly one owner (n_cols()=") + + std::to_string(sparsity_pattern.n_cols()) + + " but sum(local_columns.n_elements())=" + + std::to_string(col_owners) + ")")); + } PetscErrorCode ierr; // create the local to global mappings as arrays. diff --git a/source/lac/petsc_parallel_vector.cc b/source/lac/petsc_parallel_vector.cc index ff25f6cf9c..bd16e1eea4 100644 --- a/source/lac/petsc_parallel_vector.cc +++ b/source/lac/petsc_parallel_vector.cc @@ -317,33 +317,32 @@ namespace PETScWrappers Assert(size() == n, ExcDimensionMismatch(size(), n)); -# ifdef DEBUG - { - // test ghost allocation in debug mode - PetscInt begin, end; + if constexpr (running_in_debug_mode()) + { + // test ghost allocation in debug mode + PetscInt begin, end; - ierr = VecGetOwnershipRange(vector, &begin, &end); - AssertThrow(ierr == 0, ExcPETScError(ierr)); + ierr = VecGetOwnershipRange(vector, &begin, &end); + AssertThrow(ierr == 0, ExcPETScError(ierr)); - AssertDimension(locally_owned_size, - static_cast(end - begin)); + AssertDimension(locally_owned_size, + static_cast(end - begin)); - Vec l; - ierr = VecGhostGetLocalForm(vector, &l); - AssertThrow(ierr == 0, ExcPETScError(ierr)); + Vec l; + ierr = VecGhostGetLocalForm(vector, &l); + AssertThrow(ierr == 0, ExcPETScError(ierr)); - PetscInt lsize; - ierr = VecGetSize(l, &lsize); - AssertThrow(ierr == 0, ExcPETScError(ierr)); + PetscInt lsize; + ierr = VecGetSize(l, &lsize); + AssertThrow(ierr == 0, ExcPETScError(ierr)); - ierr = VecGhostRestoreLocalForm(vector, &l); - AssertThrow(ierr == 0, ExcPETScError(ierr)); + ierr = VecGhostRestoreLocalForm(vector, &l); + AssertThrow(ierr == 0, ExcPETScError(ierr)); - AssertDimension(lsize, - end - begin + - static_cast(ghost_indices.n_elements())); - } -# endif + AssertDimension(lsize, + end - begin + + static_cast(ghost_indices.n_elements())); + } } diff --git a/source/lac/petsc_vector_base.cc b/source/lac/petsc_vector_base.cc index e1bd867953..a21266ac34 100644 --- a/source/lac/petsc_vector_base.cc +++ b/source/lac/petsc_vector_base.cc @@ -545,25 +545,28 @@ namespace PETScWrappers "vectors.")); { -# ifdef DEBUG - // Check that all processors agree that last_action is the same (or none!) - - int my_int_last_action = last_action; - int all_int_last_action; - - const int ierr = MPI_Allreduce(&my_int_last_action, - &all_int_last_action, - 1, - MPI_INT, - MPI_BOR, - get_mpi_communicator()); - AssertThrowMPI(ierr); - - AssertThrow(all_int_last_action != - (VectorOperation::add | VectorOperation::insert), - ExcMessage("Error: not all processors agree on the last " - "VectorOperation before this compress() call.")); -# endif + if constexpr (running_in_debug_mode()) + { + // Check that all processors agree that last_action is the same (or + // none!) + + int my_int_last_action = last_action; + int all_int_last_action; + + const int ierr = MPI_Allreduce(&my_int_last_action, + &all_int_last_action, + 1, + MPI_INT, + MPI_BOR, + get_mpi_communicator()); + AssertThrowMPI(ierr); + + AssertThrow(all_int_last_action != + (VectorOperation::add | VectorOperation::insert), + ExcMessage( + "Error: not all processors agree on the last " + "VectorOperation before this compress() call.")); + } } AssertThrow( diff --git a/source/lac/scalapack.cc b/source/lac/scalapack.cc index 953d9c1514..a91d471b89 100644 --- a/source/lac/scalapack.cc +++ b/source/lac/scalapack.cc @@ -368,12 +368,15 @@ ScaLAPACKMatrix::copy_from(const LAPACKFullMatrix &B, const unsigned int this_mpi_process( Utilities::MPI::this_mpi_process(this->grid->mpi_communicator)); -# ifdef DEBUG - Assert(Utilities::MPI::max(rank, this->grid->mpi_communicator) == rank, - ExcMessage("All processes have to call routine with identical rank")); - Assert(Utilities::MPI::min(rank, this->grid->mpi_communicator) == rank, - ExcMessage("All processes have to call routine with identical rank")); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(Utilities::MPI::max(rank, this->grid->mpi_communicator) == rank, + ExcMessage( + "All processes have to call routine with identical rank")); + Assert(Utilities::MPI::min(rank, this->grid->mpi_communicator) == rank, + ExcMessage( + "All processes have to call routine with identical rank")); + } // root process has to be active in the grid of A if (this_mpi_process == rank) @@ -538,12 +541,15 @@ ScaLAPACKMatrix::copy_to(LAPACKFullMatrix &B, const unsigned int this_mpi_process( Utilities::MPI::this_mpi_process(this->grid->mpi_communicator)); -# ifdef DEBUG - Assert(Utilities::MPI::max(rank, this->grid->mpi_communicator) == rank, - ExcMessage("All processes have to call routine with identical rank")); - Assert(Utilities::MPI::min(rank, this->grid->mpi_communicator) == rank, - ExcMessage("All processes have to call routine with identical rank")); -# endif + if constexpr (running_in_debug_mode()) + { + Assert(Utilities::MPI::max(rank, this->grid->mpi_communicator) == rank, + ExcMessage( + "All processes have to call routine with identical rank")); + Assert(Utilities::MPI::min(rank, this->grid->mpi_communicator) == rank, + ExcMessage( + "All processes have to call routine with identical rank")); + } if (this_mpi_process == rank) { diff --git a/source/lac/sparsity_tools.cc b/source/lac/sparsity_tools.cc index c76f101eae..571895a492 100644 --- a/source/lac/sparsity_tools.cc +++ b/source/lac/sparsity_tools.cc @@ -836,11 +836,12 @@ namespace SparsityTools } current_neighbors.resize(write_index); -#ifdef DEBUG - for (const types::global_dof_index node : current_neighbors) - Assert(touched_nodes[node] == available_node, - ExcInternalError()); -#endif + if constexpr (running_in_debug_mode()) + { + for (const types::global_dof_index node : current_neighbors) + Assert(touched_nodes[node] == available_node, + ExcInternalError()); + } // No more neighbors left -> terminate loop if (current_neighbors.empty()) diff --git a/source/lac/trilinos_sparse_matrix.cc b/source/lac/trilinos_sparse_matrix.cc index 5684d47199..f1eacec7b4 100644 --- a/source/lac/trilinos_sparse_matrix.cc +++ b/source/lac/trilinos_sparse_matrix.cc @@ -1316,18 +1316,21 @@ namespace TrilinosWrappers { Assert(m() == n(), ExcNotQuadratic()); -# ifdef DEBUG - // use operator() in debug mode because - // it checks if this is a valid element - // (in parallel) - return operator()(i, i); -# else - // Trilinos doesn't seem to have a - // more efficient way to access the - // diagonal than by just using the - // standard el(i,j) function. - return el(i, i); -# endif + if constexpr (running_in_debug_mode()) + { + // use operator() in debug mode because + // it checks if this is a valid element + // (in parallel) + return operator()(i, i); + } + else + { + // Trilinos doesn't seem to have a + // more efficient way to access the + // diagonal than by just using the + // standard el(i,j) function. + return el(i, i); + } } @@ -1635,10 +1638,11 @@ namespace TrilinosWrappers col_indices); col_value_ptr = values; n_columns = n_cols; -# ifdef DEBUG - for (size_type j = 0; j < n_cols; ++j) - AssertIsFinite(values[j]); -# endif + if constexpr (running_in_debug_mode()) + { + for (size_type j = 0; j < n_cols; ++j) + AssertIsFinite(values[j]); + } } else { @@ -1717,45 +1721,49 @@ namespace TrilinosWrappers AssertThrow(ierr == 0, ExcTrilinosError(ierr)); } -# ifdef DEBUG - if (ierr > 0) + if constexpr (running_in_debug_mode()) { - std::cout << "------------------------------------------" << std::endl; - std::cout << "Got error " << ierr << " in row " << row << " of proc " - << matrix->RowMap().Comm().MyPID() - << " when trying to add the columns:" << std::endl; - for (TrilinosWrappers::types::int_type i = 0; i < n_columns; ++i) - std::cout << col_index_ptr[i] << " "; - std::cout << std::endl << std::endl; - std::cout << "Matrix row " - << (matrix->RowMap().MyGID( - static_cast(row)) == - false ? - "(nonlocal part)" : - "") - << " has the following indices:" << std::endl; - std::vector indices; - const Epetra_CrsGraph *graph = - (nonlocal_matrix.get() != nullptr && - matrix->RowMap().MyGID( - static_cast(row)) == false) ? - &nonlocal_matrix->Graph() : - &matrix->Graph(); - - indices.resize(graph->NumGlobalIndices(row)); - int n_indices = 0; - graph->ExtractGlobalRowCopy(row, - indices.size(), - n_indices, - indices.data()); - AssertDimension(n_indices, indices.size()); - - for (TrilinosWrappers::types::int_type i = 0; i < n_indices; ++i) - std::cout << indices[i] << " "; - std::cout << std::endl << std::endl; - Assert(ierr <= 0, ExcAccessToNonPresentElement(row, col_index_ptr[0])); + if (ierr > 0) + { + std::cout << "------------------------------------------" + << std::endl; + std::cout << "Got error " << ierr << " in row " << row + << " of proc " << matrix->RowMap().Comm().MyPID() + << " when trying to add the columns:" << std::endl; + for (TrilinosWrappers::types::int_type i = 0; i < n_columns; ++i) + std::cout << col_index_ptr[i] << " "; + std::cout << std::endl << std::endl; + std::cout << "Matrix row " + << (matrix->RowMap().MyGID( + static_cast( + row)) == false ? + "(nonlocal part)" : + "") + << " has the following indices:" << std::endl; + std::vector indices; + const Epetra_CrsGraph *graph = + (nonlocal_matrix.get() != nullptr && + matrix->RowMap().MyGID( + static_cast(row)) == + false) ? + &nonlocal_matrix->Graph() : + &matrix->Graph(); + + indices.resize(graph->NumGlobalIndices(row)); + int n_indices = 0; + graph->ExtractGlobalRowCopy(row, + indices.size(), + n_indices, + indices.data()); + AssertDimension(n_indices, indices.size()); + + for (TrilinosWrappers::types::int_type i = 0; i < n_indices; ++i) + std::cout << indices[i] << " "; + std::cout << std::endl << std::endl; + Assert(ierr <= 0, + ExcAccessToNonPresentElement(row, col_index_ptr[0])); + } } -# endif Assert(ierr >= 0, ExcTrilinosError(ierr)); } diff --git a/source/lac/trilinos_sparsity_pattern.cc b/source/lac/trilinos_sparsity_pattern.cc index 57336d018a..91cebeccd5 100644 --- a/source/lac/trilinos_sparsity_pattern.cc +++ b/source/lac/trilinos_sparsity_pattern.cc @@ -557,15 +557,16 @@ namespace TrilinosWrappers IndexSet nonlocal_partitioner = writable_rows; AssertDimension(nonlocal_partitioner.size(), row_parallel_partitioning.size()); -# ifdef DEBUG - { - IndexSet tmp = writable_rows & row_parallel_partitioning; - Assert(tmp == row_parallel_partitioning, - ExcMessage( - "The set of writable rows passed to this method does not " - "contain the locally owned rows, which is not allowed.")); - } -# endif + if constexpr (running_in_debug_mode()) + { + { + IndexSet tmp = writable_rows & row_parallel_partitioning; + Assert(tmp == row_parallel_partitioning, + ExcMessage( + "The set of writable rows passed to this method does not " + "contain the locally owned rows, which is not allowed.")); + } + } nonlocal_partitioner.subtract_set(row_parallel_partitioning); if (Utilities::MPI::n_mpi_processes(communicator) > 1) { diff --git a/source/lac/trilinos_tpetra_sparsity_pattern.cc b/source/lac/trilinos_tpetra_sparsity_pattern.cc index d27cba16f0..7c4857d225 100644 --- a/source/lac/trilinos_tpetra_sparsity_pattern.cc +++ b/source/lac/trilinos_tpetra_sparsity_pattern.cc @@ -584,15 +584,16 @@ namespace LinearAlgebra IndexSet nonlocal_partitioner = writable_rows; AssertDimension(nonlocal_partitioner.size(), row_parallel_partitioning.size()); -# ifdef DEBUG - { - IndexSet tmp = writable_rows & row_parallel_partitioning; - Assert(tmp == row_parallel_partitioning, - ExcMessage( - "The set of writable rows passed to this method does not " - "contain the locally owned rows, which is not allowed.")); - } -# endif + if constexpr (running_in_debug_mode()) + { + { + IndexSet tmp = writable_rows & row_parallel_partitioning; + Assert(tmp == row_parallel_partitioning, + ExcMessage( + "The set of writable rows passed to this method does not " + "contain the locally owned rows, which is not allowed.")); + } + } nonlocal_partitioner.subtract_set(row_parallel_partitioning); if (Utilities::MPI::n_mpi_processes(communicator) > 1) { diff --git a/source/lac/trilinos_vector.cc b/source/lac/trilinos_vector.cc index 9aef10ad7a..f1f5a8c338 100644 --- a/source/lac/trilinos_vector.cc +++ b/source/lac/trilinos_vector.cc @@ -188,12 +188,13 @@ namespace TrilinosWrappers else owned_elements = parallel_partitioner; -# ifdef DEBUG - const size_type n_elements_global = - Utilities::MPI::sum(owned_elements.n_elements(), communicator); + if constexpr (running_in_debug_mode()) + { + const size_type n_elements_global = + Utilities::MPI::sum(owned_elements.n_elements(), communicator); - Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); -# endif + Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); + } last_action = Zero; } @@ -269,14 +270,15 @@ namespace TrilinosWrappers last_action = Insert; } -# ifdef DEBUG - const Epetra_MpiComm *comm_ptr = - dynamic_cast(&(v.vector->Comm())); - Assert(comm_ptr != nullptr, ExcInternalError()); - const size_type n_elements_global = - Utilities::MPI::sum(owned_elements.n_elements(), comm_ptr->Comm()); - Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + const Epetra_MpiComm *comm_ptr = + dynamic_cast(&(v.vector->Comm())); + Assert(comm_ptr != nullptr, ExcInternalError()); + const size_type n_elements_global = + Utilities::MPI::sum(owned_elements.n_elements(), comm_ptr->Comm()); + Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); + } } @@ -346,15 +348,16 @@ namespace TrilinosWrappers } else vector = std::move(actual_vec); -# ifdef DEBUG - const Epetra_MpiComm *comm_ptr = - dynamic_cast(&(vector->Comm())); - Assert(comm_ptr != nullptr, ExcInternalError()); - const size_type n_elements_global = - Utilities::MPI::sum(owned_elements.n_elements(), comm_ptr->Comm()); - - Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); -# endif + if constexpr (running_in_debug_mode()) + { + const Epetra_MpiComm *comm_ptr = + dynamic_cast(&(vector->Comm())); + Assert(comm_ptr != nullptr, ExcInternalError()); + const size_type n_elements_global = + Utilities::MPI::sum(owned_elements.n_elements(), comm_ptr->Comm()); + + Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); + } } @@ -407,12 +410,13 @@ namespace TrilinosWrappers last_action = Zero; -# ifdef DEBUG - const size_type n_elements_global = - Utilities::MPI::sum(owned_elements.n_elements(), communicator); + if constexpr (running_in_debug_mode()) + { + const size_type n_elements_global = + Utilities::MPI::sum(owned_elements.n_elements(), communicator); - Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); -# endif + Assert(has_ghosts || n_elements_global == size(), ExcInternalError()); + } } @@ -646,24 +650,24 @@ namespace TrilinosWrappers } -# ifdef DEBUG - // check that every process has decided to use the same mode. This will - // otherwise result in undefined behavior in the call to - // GlobalAssemble(). - const double double_mode = mode; - const Epetra_MpiComm *comm_ptr = - dynamic_cast(&(trilinos_partitioner().Comm())); - Assert(comm_ptr != nullptr, ExcInternalError()); - - const Utilities::MPI::MinMaxAvg result = - Utilities::MPI::min_max_avg(double_mode, comm_ptr->GetMpiComm()); - Assert(result.max == result.min, - ExcMessage( - "Not all processors agree whether the last operation on " - "this vector was an addition or a set operation. This will " - "prevent the compress() operation from succeeding.")); - -# endif + if constexpr (running_in_debug_mode()) + { + // check that every process has decided to use the same mode. This + // will otherwise result in undefined behavior in the call to + // GlobalAssemble(). + const double double_mode = mode; + const Epetra_MpiComm *comm_ptr = dynamic_cast( + &(trilinos_partitioner().Comm())); + Assert(comm_ptr != nullptr, ExcInternalError()); + + const Utilities::MPI::MinMaxAvg result = + Utilities::MPI::min_max_avg(double_mode, comm_ptr->GetMpiComm()); + Assert(result.max == result.min, + ExcMessage( + "Not all processors agree whether the last operation on " + "this vector was an addition or a set operation. This will " + "prevent the compress() operation from succeeding.")); + } // Now pass over the information about what we did last to the vector. if (nonlocal_vector.get() == nullptr || mode != Add) diff --git a/source/matrix_free/dof_info.cc b/source/matrix_free/dof_info.cc index f53362c61f..23737c0123 100644 --- a/source/matrix_free/dof_info.cc +++ b/source/matrix_free/dof_info.cc @@ -164,10 +164,11 @@ namespace internal const unsigned int n_owned = (vector_partitioner->local_range().second - vector_partitioner->local_range().first); const std::size_t n_ghosts = ghost_dofs.size(); -#ifdef DEBUG - for (const auto dof_index : dof_indices) - AssertIndexRange(dof_index, n_owned + n_ghosts); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto dof_index : dof_indices) + AssertIndexRange(dof_index, n_owned + n_ghosts); + } const unsigned int n_components = start_components.back(); std::vector ghost_numbering(n_ghosts); @@ -474,54 +475,59 @@ namespace internal new_rowstart_plain.swap(row_starts_plain_indices); new_hanging_node_constraint_masks.swap(hanging_node_constraint_masks); -#ifdef DEBUG - // sanity check 1: all indices should be smaller than the number of dofs - // locally owned plus the number of ghosts - const unsigned int index_range = - (vector_partitioner->local_range().second - - vector_partitioner->local_range().first) + - vector_partitioner->ghost_indices().n_elements(); - for (const auto dof_index : dof_indices) - AssertIndexRange(dof_index, index_range); - - // sanity check 2: for the constraint indicators, the first index should - // be smaller than the number of indices in the row, and the second - // index should be smaller than the number of constraints in the - // constraint pool. - for (unsigned int row = 0; row < task_info.cell_partition_data.back(); - ++row) + if constexpr (running_in_debug_mode()) { - const unsigned int row_length_ind = - row_starts[(row * vectorization_length + 1) * n_components].first - - row_starts[row * vectorization_length * n_components].first; - AssertIndexRange( - row_starts[(row * vectorization_length + 1) * n_components].second, - constraint_indicator.size() + 1); - const std::pair * - con_it = - constraint_indicator.data() + - row_starts[row * vectorization_length * n_components].second, - *end_con = - constraint_indicator.data() + - row_starts[(row * vectorization_length + 1) * n_components].second; - for (; con_it != end_con; ++con_it) + // sanity check 1: all indices should be smaller than the number of + // dofs locally owned plus the number of ghosts + const unsigned int index_range = + (vector_partitioner->local_range().second - + vector_partitioner->local_range().first) + + vector_partitioner->ghost_indices().n_elements(); + for (const auto dof_index : dof_indices) + AssertIndexRange(dof_index, index_range); + + // sanity check 2: for the constraint indicators, the first index + // should be smaller than the number of indices in the row, and the + // second index should be smaller than the number of constraints in + // the constraint pool. + for (unsigned int row = 0; row < task_info.cell_partition_data.back(); + ++row) { - AssertIndexRange(con_it->first, row_length_ind + 1); - AssertIndexRange(con_it->second, - constraint_pool_row_index.size() - 1); + const unsigned int row_length_ind = + row_starts[(row * vectorization_length + 1) * n_components] + .first - + row_starts[row * vectorization_length * n_components].first; + AssertIndexRange( + row_starts[(row * vectorization_length + 1) * n_components] + .second, + constraint_indicator.size() + 1); + const std::pair + *con_it = + constraint_indicator.data() + + row_starts[row * vectorization_length * n_components].second, + *end_con = + constraint_indicator.data() + + row_starts[(row * vectorization_length + 1) * n_components] + .second; + for (; con_it != end_con; ++con_it) + { + AssertIndexRange(con_it->first, row_length_ind + 1); + AssertIndexRange(con_it->second, + constraint_pool_row_index.size() - 1); + } } - } - // sanity check 3: check the number of cells once again - unsigned int n_active_cells = 0; - for (unsigned int c = 0; c < *(task_info.cell_partition_data.end() - 2); - ++c) - if (irregular_cells[c] > 0) - n_active_cells += irregular_cells[c]; - else - n_active_cells += vectorization_length; - AssertDimension(n_active_cells, task_info.n_active_cells); -#endif + // sanity check 3: check the number of cells once again + unsigned int n_active_cells = 0; + for (unsigned int c = 0; + c < *(task_info.cell_partition_data.end() - 2); + ++c) + if (irregular_cells[c] > 0) + n_active_cells += irregular_cells[c]; + else + n_active_cells += vectorization_length; + AssertDimension(n_active_cells, task_info.n_active_cells); + } compute_cell_index_compression(irregular_cells); } diff --git a/source/matrix_free/task_info.cc b/source/matrix_free/task_info.cc index 54b033bc62..58b5f24191 100644 --- a/source/matrix_free/task_info.cc +++ b/source/matrix_free/task_info.cc @@ -1136,12 +1136,13 @@ namespace internal cell_partition_data.push_back(n_cell_batches + n_ghost_batches); partition_row_index.back() = cell_partition_data.size() - 1; -#ifdef DEBUG - std::vector renumber_cpy(renumbering); - std::sort(renumber_cpy.begin(), renumber_cpy.end()); - for (unsigned int i = 0; i < renumber_cpy.size(); ++i) - AssertDimension(i, renumber_cpy[i]); -#endif + if constexpr (running_in_debug_mode()) + { + std::vector renumber_cpy(renumbering); + std::sort(renumber_cpy.begin(), renumber_cpy.end()); + for (unsigned int i = 0; i < renumber_cpy.size(); ++i) + AssertDimension(i, renumber_cpy[i]); + } } @@ -1302,15 +1303,16 @@ namespace internal partition_list = renumbering; -#ifdef DEBUG - // in debug mode, check that the partition color list is one-to-one - { - std::vector sorted_pc_list(partition_color_list); - std::sort(sorted_pc_list.begin(), sorted_pc_list.end()); - for (unsigned int i = 0; i < sorted_pc_list.size(); ++i) - Assert(sorted_pc_list[i] == i, ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + // in debug mode, check that the partition color list is one-to-one + { + std::vector sorted_pc_list(partition_color_list); + std::sort(sorted_pc_list.begin(), sorted_pc_list.end()); + for (unsigned int i = 0; i < sorted_pc_list.size(); ++i) + Assert(sorted_pc_list[i] == i, ExcInternalError()); + } + } // set the start list for each block and compute the renumbering of // cells @@ -1369,14 +1371,15 @@ namespace internal AssertDimension(counter_macro, n_cell_batches); // check that the renumbering is one-to-one -#ifdef DEBUG - { - std::vector sorted_renumbering(renumbering); - std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); - for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) - Assert(sorted_renumbering[i] == i, ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + std::vector sorted_renumbering(renumbering); + std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); + for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) + Assert(sorted_renumbering[i] == i, ExcInternalError()); + } + } update_task_info( @@ -1483,15 +1486,16 @@ namespace internal partition_2layers_list); } - // in debug mode, check that the partition_2layers_list is one-to-one -#ifdef DEBUG - { - std::vector sorted_pc_list(partition_2layers_list); - std::sort(sorted_pc_list.begin(), sorted_pc_list.end()); - for (unsigned int i = 0; i < sorted_pc_list.size(); ++i) - Assert(sorted_pc_list[i] == i, ExcInternalError()); - } -#endif + // in debug mode, check that the partition_2layers_list is one-to-one + if constexpr (running_in_debug_mode()) + { + { + std::vector sorted_pc_list(partition_2layers_list); + std::sort(sorted_pc_list.begin(), sorted_pc_list.end()); + for (unsigned int i = 0; i < sorted_pc_list.size(); ++i) + Assert(sorted_pc_list[i] == i, ExcInternalError()); + } + } // Set the new renumbering std::vector renumbering_in(n_active_cells, 0); @@ -1566,14 +1570,15 @@ namespace internal AssertDimension(counter, n_active_cells); AssertDimension(counter_macro, n_cell_batches); // check that the renumbering is one-to-one -#ifdef DEBUG - { - std::vector sorted_renumbering(renumbering); - std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); - for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) - Assert(sorted_renumbering[i] == i, ExcInternalError()); - } -#endif + if constexpr (running_in_debug_mode()) + { + { + std::vector sorted_renumbering(renumbering); + std::sort(sorted_renumbering.begin(), sorted_renumbering.end()); + for (unsigned int i = 0; i < sorted_renumbering.size(); ++i) + Assert(sorted_renumbering[i] == i, ExcInternalError()); + } + } } // Update the task_info with the more information for the thread graph. diff --git a/source/multigrid/mg_transfer_internal.cc b/source/multigrid/mg_transfer_internal.cc index b79adad727..eb38d7867a 100644 --- a/source/multigrid/mg_transfer_internal.cc +++ b/source/multigrid/mg_transfer_internal.cc @@ -365,13 +365,14 @@ namespace internal AssertThrowMPI(ierr); requests.clear(); } -# ifdef DEBUG - // Make sure in debug mode, that everybody sent/received all packages - // on this level. If a deadlock occurs here, the list of expected - // senders is not computed correctly. - const int ierr = MPI_Barrier(tria->get_mpi_communicator()); - AssertThrowMPI(ierr); -# endif + if constexpr (running_in_debug_mode()) + { + // Make sure in debug mode, that everybody sent/received all + // packages on this level. If a deadlock occurs here, the list of + // expected senders is not computed correctly. + const int ierr = MPI_Barrier(tria->get_mpi_communicator()); + AssertThrowMPI(ierr); + } } #endif @@ -634,38 +635,39 @@ namespace internal dirichlet_indices.clear(); weights_on_refined.clear(); -#ifdef DEBUG - if (mg_constrained_dofs) + if constexpr (running_in_debug_mode()) { - const unsigned int n_levels = - dof_handler.get_triangulation().n_global_levels(); - - for (unsigned int l = 0; l < n_levels; ++l) + if (mg_constrained_dofs) { - const auto &constraints = - mg_constrained_dofs->get_user_constraint_matrix(l); - - // no inhomogeneities are supported - AssertDimension(constraints.n_inhomogeneities(), 0); + const unsigned int n_levels = + dof_handler.get_triangulation().n_global_levels(); - for (const auto dof : constraints.get_local_lines()) + for (unsigned int l = 0; l < n_levels; ++l) { - const auto *entries_ptr = - constraints.get_constraint_entries(dof); + const auto &constraints = + mg_constrained_dofs->get_user_constraint_matrix(l); - if (entries_ptr == nullptr) - continue; + // no inhomogeneities are supported + AssertDimension(constraints.n_inhomogeneities(), 0); - // only homogeneous or identity constraints are supported - Assert((entries_ptr->size() == 0) || - ((entries_ptr->size() == 1) && - (std::abs((*entries_ptr)[0].second - 1.) < - 100 * std::numeric_limits::epsilon())), - ExcNotImplemented()); + for (const auto dof : constraints.get_local_lines()) + { + const auto *entries_ptr = + constraints.get_constraint_entries(dof); + + if (entries_ptr == nullptr) + continue; + + // only homogeneous or identity constraints are supported + Assert((entries_ptr->size() == 0) || + ((entries_ptr->size() == 1) && + (std::abs((*entries_ptr)[0].second - 1.) < + 100 * std::numeric_limits::epsilon())), + ExcNotImplemented()); + } } } } -#endif // we collect all child DoFs of a mother cell together. For faster // tensorized operations, we align the degrees of freedom diff --git a/source/multigrid/multigrid.cc b/source/multigrid/multigrid.cc index 07c4b6529f..c6584299df 100644 --- a/source/multigrid/multigrid.cc +++ b/source/multigrid/multigrid.cc @@ -84,13 +84,15 @@ MGTransferBlock::prolongate(const unsigned int to_level, Assert(dst.n_blocks() == this->n_mg_blocks, ExcDimensionMismatch(dst.n_blocks(), this->n_mg_blocks)); -#ifdef DEBUG - if (this->mg_constrained_dofs != nullptr) - Assert(this->mg_constrained_dofs->get_user_constraint_matrix(to_level - 1) - .get_local_lines() - .size() == 0, - ExcNotImplemented()); -#endif + if constexpr (running_in_debug_mode()) + { + if (this->mg_constrained_dofs != nullptr) + Assert(this->mg_constrained_dofs + ->get_user_constraint_matrix(to_level - 1) + .get_local_lines() + .size() == 0, + ExcNotImplemented()); + } // Multiplicate with prolongation // matrix, but only those blocks @@ -268,13 +270,15 @@ MGTransferBlockSelect::prolongate(const unsigned int to_level, Assert((to_level >= 1) && (to_level <= prolongation_matrices.size()), ExcIndexRange(to_level, 1, prolongation_matrices.size() + 1)); -#ifdef DEBUG - if (this->mg_constrained_dofs != nullptr) - Assert(this->mg_constrained_dofs->get_user_constraint_matrix(to_level - 1) - .get_local_lines() - .size() == 0, - ExcNotImplemented()); -#endif + if constexpr (running_in_debug_mode()) + { + if (this->mg_constrained_dofs != nullptr) + Assert(this->mg_constrained_dofs + ->get_user_constraint_matrix(to_level - 1) + .get_local_lines() + .size() == 0, + ExcNotImplemented()); + } prolongation_matrices[to_level - 1] ->block(selected_block, selected_block) diff --git a/source/numerics/data_out_resample.cc b/source/numerics/data_out_resample.cc index 04b1d14833..9107745f71 100644 --- a/source/numerics/data_out_resample.cc +++ b/source/numerics/data_out_resample.cc @@ -150,14 +150,15 @@ DataOutResample::build_patches( const auto &dh = *data_ptr->dof_handler; -#ifdef DEBUG - for (const auto &fe : dh.get_fe_collection()) - Assert( - fe.n_base_elements() == 1, - ExcMessage( - "This class currently only supports scalar elements and elements " - "with a single base element.")); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &fe : dh.get_fe_collection()) + Assert( + fe.n_base_elements() == 1, + ExcMessage( + "This class currently only supports scalar elements and elements " + "with a single base element.")); + } for (unsigned int comp = 0; comp < dh.get_fe_collection().n_components(); ++comp) diff --git a/source/numerics/data_out_stack.cc b/source/numerics/data_out_stack.cc index 6f5a722e56..c9553d2bbe 100644 --- a/source/numerics/data_out_stack.cc +++ b/source/numerics/data_out_stack.cc @@ -94,26 +94,27 @@ DataOutStack::declare_data_vector( const std::vector &names, const VectorType vector_type) { -#ifdef DEBUG - // make sure this function is - // not called after some parameter - // values have already been - // processed - Assert(patches.empty(), ExcDataAlreadyAdded()); - - // also make sure that no name is - // used twice - for (const auto &name : names) + if constexpr (running_in_debug_mode()) { - for (const auto &data_set : dof_data) - for (const auto &data_set_name : data_set.names) - Assert(name != data_set_name, ExcNameAlreadyUsed(name)); + // make sure this function is + // not called after some parameter + // values have already been + // processed + Assert(patches.empty(), ExcDataAlreadyAdded()); + + // also make sure that no name is + // used twice + for (const auto &name : names) + { + for (const auto &data_set : dof_data) + for (const auto &data_set_name : data_set.names) + Assert(name != data_set_name, ExcNameAlreadyUsed(name)); - for (const auto &data_set : cell_data) - for (const auto &data_set_name : data_set.names) - Assert(name != data_set_name, ExcNameAlreadyUsed(name)); + for (const auto &data_set : cell_data) + for (const auto &data_set_name : data_set.names) + Assert(name != data_set_name, ExcNameAlreadyUsed(name)); + } } -#endif switch (vector_type) { diff --git a/source/numerics/solution_transfer.cc b/source/numerics/solution_transfer.cc index aefc0222f3..d8c0970e0d 100644 --- a/source/numerics/solution_transfer.cc +++ b/source/numerics/solution_transfer.cc @@ -368,12 +368,13 @@ SolutionTransfer::pack_callback( // In case of coarsening, we need to find a suitable FE index // for the parent cell. We choose the 'least dominant fe' // on all children from the associated FECollection. -#ifdef DEBUG - for (const auto &child : cell->child_iterators()) - Assert(child->is_active() && child->coarsen_flag_set(), - typename dealii::Triangulation< - dim>::ExcInconsistentCoarseningFlags()); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &child : cell->child_iterators()) + Assert(child->is_active() && child->coarsen_flag_set(), + typename dealii::Triangulation< + dim>::ExcInconsistentCoarseningFlags()); + } fe_index = dealii::internal::hp::DoFHandlerImplementation:: dominated_future_fe_on_children(cell); @@ -767,16 +768,17 @@ namespace Legacy n_dofs_old = dof_handler->n_dofs(); const unsigned int in_size = all_in.size(); -#ifdef DEBUG - Assert(in_size != 0, - ExcMessage("The array of input vectors you pass to this " - "function has no elements. This is not useful.")); - for (unsigned int i = 0; i < in_size; ++i) + if constexpr (running_in_debug_mode()) { - Assert(all_in[i].size() == n_dofs_old, - ExcDimensionMismatch(all_in[i].size(), n_dofs_old)); + Assert(in_size != 0, + ExcMessage("The array of input vectors you pass to this " + "function has no elements. This is not useful.")); + for (unsigned int i = 0; i < in_size; ++i) + { + Assert(all_in[i].size() == n_dofs_old, + ExcDimensionMismatch(all_in[i].size(), n_dofs_old)); + } } -#endif // We need to access dof indices on the entire domain. For // parallel::shared::Triangulations, ownership of cells might change. If @@ -928,21 +930,24 @@ namespace Legacy std::vector &all_out) const { const unsigned int size = all_in.size(); -#ifdef DEBUG - Assert(prepared_for == coarsening_and_refinement, ExcNotPrepared()); - Assert(all_out.size() == size, ExcDimensionMismatch(all_out.size(), size)); - for (unsigned int i = 0; i < size; ++i) - Assert(all_in[i].size() == n_dofs_old, - ExcDimensionMismatch(all_in[i].size(), n_dofs_old)); - for (unsigned int i = 0; i < all_out.size(); ++i) - Assert(all_out[i].size() == dof_handler->n_dofs(), - ExcDimensionMismatch(all_out[i].size(), dof_handler->n_dofs())); - for (unsigned int i = 0; i < size; ++i) - for (unsigned int j = 0; j < size; ++j) - Assert(&all_in[i] != &all_out[j], - ExcMessage("Vectors cannot be used as input and output" - " at the same time!")); -#endif + if constexpr (running_in_debug_mode()) + { + Assert(prepared_for == coarsening_and_refinement, ExcNotPrepared()); + Assert(all_out.size() == size, + ExcDimensionMismatch(all_out.size(), size)); + for (unsigned int i = 0; i < size; ++i) + Assert(all_in[i].size() == n_dofs_old, + ExcDimensionMismatch(all_in[i].size(), n_dofs_old)); + for (unsigned int i = 0; i < all_out.size(); ++i) + Assert(all_out[i].size() == dof_handler->n_dofs(), + ExcDimensionMismatch(all_out[i].size(), + dof_handler->n_dofs())); + for (unsigned int i = 0; i < size; ++i) + for (unsigned int j = 0; j < size; ++j) + Assert(&all_in[i] != &all_out[j], + ExcMessage("Vectors cannot be used as input and output" + " at the same time!")); + } // We need to access dof indices on the entire domain. For // parallel::shared::Triangulations, ownership of cells might change. If diff --git a/source/opencascade/manifold_lib.cc b/source/opencascade/manifold_lib.cc index 10d8c38cdb..44006b00c7 100644 --- a/source/opencascade/manifold_lib.cc +++ b/source/opencascade/manifold_lib.cc @@ -131,13 +131,15 @@ namespace OpenCASCADE const Point &candidate) const { (void)surrounding_points; -# ifdef DEBUG - for (unsigned int i = 0; i < surrounding_points.size(); ++i) - Assert(closest_point(sh, surrounding_points[i], tolerance) - .distance(surrounding_points[i]) < - std::max(tolerance * surrounding_points[i].norm(), tolerance), - ExcPointNotOnManifold(surrounding_points[i])); -# endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = 0; i < surrounding_points.size(); ++i) + Assert(closest_point(sh, surrounding_points[i], tolerance) + .distance(surrounding_points[i]) < + std::max(tolerance * surrounding_points[i].norm(), + tolerance), + ExcPointNotOnManifold(surrounding_points[i])); + } return closest_point(sh, candidate, tolerance); } @@ -174,13 +176,15 @@ namespace OpenCASCADE const Point &candidate) const { (void)surrounding_points; -# ifdef DEBUG - for (unsigned int i = 0; i < surrounding_points.size(); ++i) - Assert(closest_point(sh, surrounding_points[i], tolerance) - .distance(surrounding_points[i]) < - std::max(tolerance * surrounding_points[i].norm(), tolerance), - ExcPointNotOnManifold(surrounding_points[i])); -# endif + if constexpr (running_in_debug_mode()) + { + for (unsigned int i = 0; i < surrounding_points.size(); ++i) + Assert(closest_point(sh, surrounding_points[i], tolerance) + .distance(surrounding_points[i]) < + std::max(tolerance * surrounding_points[i].norm(), + tolerance), + ExcPointNotOnManifold(surrounding_points[i])); + } return line_intersection(sh, candidate, direction, tolerance); } @@ -234,14 +238,15 @@ namespace OpenCASCADE constexpr int spacedim = 3; TopoDS_Shape out_shape; Tensor<1, spacedim> average_normal; -# ifdef DEBUG - for (const auto &point : surrounding_points) + if constexpr (running_in_debug_mode()) { - Assert(closest_point(sh, point, tolerance).distance(point) < - std::max(tolerance * point.norm(), tolerance), - ExcPointNotOnManifold(point)); + for (const auto &point : surrounding_points) + { + Assert(closest_point(sh, point, tolerance).distance(point) < + std::max(tolerance * point.norm(), tolerance), + ExcPointNotOnManifold(point)); + } } -# endif switch (surrounding_points.size()) { diff --git a/source/particles/particle_handler.cc b/source/particles/particle_handler.cc index 9ba6713e90..fb5c87dbe1 100644 --- a/source/particles/particle_handler.cc +++ b/source/particles/particle_handler.cc @@ -337,31 +337,33 @@ namespace Particles owned_particles_end->particles.empty(), ExcInternalError()); -#ifdef DEBUG - // check that no cache element hits the three anchor states in the list of - // particles - for (const auto &it : cells_to_particle_cache) - Assert(it != particles.begin() && it != owned_particles_end && - it != --(particles.end()), - ExcInternalError()); - - // check that we only have locally owned particles in the first region of - // cells; note that we skip the very first anchor element - for (auto it = particle_container_owned_begin(); - it != particle_container_owned_end(); - ++it) - Assert(it->cell->is_locally_owned(), ExcInternalError()); - - // check that the cache is consistent with the iterators - std::vector verify_cache( - triangulation->n_active_cells(), particles.end()); - for (auto it = particles.begin(); it != particles.end(); ++it) - if (!it->particles.empty()) - verify_cache[it->cell->active_cell_index()] = it; + if constexpr (running_in_debug_mode()) + { + // check that no cache element hits the three anchor states in the list + // of particles + for (const auto &it : cells_to_particle_cache) + Assert(it != particles.begin() && it != owned_particles_end && + it != --(particles.end()), + ExcInternalError()); - for (unsigned int i = 0; i < verify_cache.size(); ++i) - Assert(verify_cache[i] == cells_to_particle_cache[i], ExcInternalError()); -#endif + // check that we only have locally owned particles in the first region + // of cells; note that we skip the very first anchor element + for (auto it = particle_container_owned_begin(); + it != particle_container_owned_end(); + ++it) + Assert(it->cell->is_locally_owned(), ExcInternalError()); + + // check that the cache is consistent with the iterators + std::vector verify_cache( + triangulation->n_active_cells(), particles.end()); + for (auto it = particles.begin(); it != particles.end(); ++it) + if (!it->particles.empty()) + verify_cache[it->cell->active_cell_index()] = it; + + for (unsigned int i = 0; i < verify_cache.size(); ++i) + Assert(verify_cache[i] == cells_to_particle_cache[i], + ExcInternalError()); + } // now compute local result with the function above and then compute the // collective results @@ -775,10 +777,11 @@ namespace Particles if (!properties.empty()) { AssertDimension(properties.size(), positions.size()); -#ifdef DEBUG - for (const auto &p : properties) - AssertDimension(p.size(), n_properties_per_particle()); -#endif + if constexpr (running_in_debug_mode()) + { + for (const auto &p : properties) + AssertDimension(p.size(), n_properties_per_particle()); + } } if (!ids.empty())