From: Wolfgang Bangerth Date: Fri, 8 Sep 2023 14:43:46 +0000 (-0600) Subject: Work around a common situation in sequential programs. X-Git-Tag: relicensing~496^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F15789%2Fhead;p=dealii.git Work around a common situation in sequential programs. --- diff --git a/include/deal.II/lac/affine_constraints.templates.h b/include/deal.II/lac/affine_constraints.templates.h index 729a86b781..b685d379e5 100644 --- a/include/deal.II/lac/affine_constraints.templates.h +++ b/include/deal.II/lac/affine_constraints.templates.h @@ -2590,7 +2590,7 @@ AffineConstraints::distribute(VectorType &vec) const // the last else is for the simple case (sequential vector) const IndexSet vec_owned_elements = vec.locally_owned_elements(); - if (dealii::is_serial_vector::value == false) + if constexpr (dealii::is_serial_vector::value == false) { // 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 @@ -2606,12 +2606,46 @@ AffineConstraints::distribute(VectorType &vec) const #endif VectorType ghosted_vector; - internal::import_vector_with_ghost_elements( - vec, - vec_owned_elements, - needed_elements_for_distribute, - ghosted_vector, - std::integral_constant::value>()); + + // It is possible that the user is using a parallel vector type, + // but is running a non-parallel program (for example, step-31 + // does this). In this case, it is (perhaps?) not a bug to not + // set an IndexSet for the local_lines and the + // locally_owned_lines -- they are simply both empty sets in + // that case. If that is so, we could just assign + // 'ghosted_vector=vec;'. But this is dangerous. Not having set + // index sets could also have been a bug, and we would get + // downstream errors about accessing elements that are not + // locally available. Rather, if no index sets were provided, + // simply import the *entire* vector. + if (local_lines != IndexSet()) + { + Assert(needed_elements_for_distribute != IndexSet(), + ExcInternalError()); + internal::import_vector_with_ghost_elements( + vec, + vec_owned_elements, + needed_elements_for_distribute, + ghosted_vector, + std::integral_constant::value>()); + } + else + { + Assert(needed_elements_for_distribute == IndexSet(), + ExcInternalError()); + + // TODO: We should really consider it a bug if this parallel + // truly is distributed (and not just a parallel vector type + // used for a sequential program). Assert that we are really + // working in a sequential context. + + internal::import_vector_with_ghost_elements( + vec, + vec_owned_elements, + complete_index_set(vec_owned_elements.size()), + ghosted_vector, + std::integral_constant::value>()); + } for (const ConstraintLine &line : lines) if (vec_owned_elements.is_element(line.index))