From e99d20ee92b39e94b36d6c77dab872358d966d73 Mon Sep 17 00:00:00 2001 From: Peter Munch Date: Wed, 26 Jul 2023 09:10:11 +0200 Subject: [PATCH] DataOut::add_mg_data_vector(): copy vector and update ghost values --- doc/news/changes/minor/20230725Munch | 5 + .../numerics/data_out_dof_data.templates.h | 106 ++++++++++-------- 2 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 doc/news/changes/minor/20230725Munch diff --git a/doc/news/changes/minor/20230725Munch b/doc/news/changes/minor/20230725Munch new file mode 100644 index 0000000000..5607d533c4 --- /dev/null +++ b/doc/news/changes/minor/20230725Munch @@ -0,0 +1,5 @@ +New: Similar to the DataOut::add_data_vector() case, +DataOut::add_mg_data_vector() now also copies the vector +and performs the ghost-vector update internally. +
+(Peter Munch, 2023/07/25) diff --git a/include/deal.II/numerics/data_out_dof_data.templates.h b/include/deal.II/numerics/data_out_dof_data.templates.h index 8506cb24a9..a8b708acf3 100644 --- a/include/deal.II/numerics/data_out_dof_data.templates.h +++ b/include/deal.II/numerics/data_out_dof_data.templates.h @@ -915,15 +915,21 @@ namespace internal std::enable_if_t::value, VectorType> * = nullptr> void - create_dof_vector(const DoFHandler &dof_handler, - const VectorType & src, - LinearAlgebra::distributed::BlockVector &dst) + create_dof_vector( + const DoFHandler & dof_handler, + const VectorType & src, + LinearAlgebra::distributed::BlockVector &dst, + const unsigned int level = numbers::invalid_unsigned_int) { - IndexSet locally_relevant_dofs; - DoFTools::extract_locally_relevant_dofs(dof_handler, - locally_relevant_dofs); + const IndexSet &locally_owned_dofs = + (level == numbers::invalid_unsigned_int) ? + dof_handler.locally_owned_dofs() : + dof_handler.locally_owned_mg_dofs(level); - const IndexSet &locally_owned_dofs = dof_handler.locally_owned_dofs(); + const IndexSet locally_relevant_dofs = + (level == numbers::invalid_unsigned_int) ? + DoFTools::extract_locally_relevant_dofs(dof_handler) : + DoFTools::extract_locally_relevant_level_dofs(dof_handler, level); std::vector n_indices_per_block( src.n_blocks()); @@ -977,23 +983,32 @@ namespace internal std::enable_if_t::value, VectorType> * = nullptr> void - create_dof_vector(const DoFHandler &dof_handler, - const VectorType & src, - LinearAlgebra::distributed::BlockVector &dst) + create_dof_vector( + const DoFHandler & dof_handler, + const VectorType & src, + LinearAlgebra::distributed::BlockVector &dst, + const unsigned int level = numbers::invalid_unsigned_int) { - Assert(dof_handler.locally_owned_dofs().is_contiguous(), + const IndexSet &locally_owned_dofs = + (level == numbers::invalid_unsigned_int) ? + dof_handler.locally_owned_dofs() : + dof_handler.locally_owned_mg_dofs(level); + + const IndexSet locally_relevant_dofs = + (level == numbers::invalid_unsigned_int) ? + DoFTools::extract_locally_relevant_dofs(dof_handler) : + DoFTools::extract_locally_relevant_level_dofs(dof_handler, level); + + + Assert(locally_owned_dofs.is_contiguous(), ExcMessage( "You are trying to add a non-block vector with non-contiguous " "locally-owned index sets. This is not possible. Please " "consider to use an adequate block vector!")); - IndexSet locally_relevant_dofs; - DoFTools::extract_locally_relevant_dofs(dof_handler, - locally_relevant_dofs); - dst.reinit(1); - dst.block(0).reinit(dof_handler.locally_owned_dofs(), + dst.block(0).reinit(locally_owned_dofs, locally_relevant_dofs, dof_handler.get_communicator()); copy_locally_owned_data_from(src, dst.block(0)); @@ -1542,10 +1557,11 @@ namespace internal * MGLevelObject given on the specific level instead of * interpolating data to coarser cells. */ - template + template class MGDataEntry : public DataEntryBase { public: + template MGDataEntry(const DoFHandler *dofs, const MGLevelObject *vectors, const std::vector & names, @@ -1555,8 +1571,15 @@ namespace internal : DataEntryBase(dofs, names, data_component_interpretation) - , vectors(vectors) - {} + { + AssertDimension(vectors->min_level(), 0); + + this->vectors.resize(vectors->min_level(), vectors->max_level()); + + for (unsigned int l = vectors->min_level(); l <= vectors->max_level(); + ++l) + create_dof_vector(*dofs, (*vectors)[l], this->vectors[l], l); + } virtual double get_cell_data_value( @@ -1643,12 +1666,9 @@ namespace internal virtual bool is_complex_valued() const override { - Assert( - numbers::NumberTraits::is_complex == - false, - ExcNotImplemented()); - return numbers::NumberTraits< - typename VectorType::value_type>::is_complex; + Assert(numbers::NumberTraits::is_complex == false, + ExcNotImplemented()); + return numbers::NumberTraits::is_complex; } /** @@ -1657,7 +1677,7 @@ namespace internal virtual void clear() override { - vectors = nullptr; + vectors.clear(); } /** @@ -1671,14 +1691,15 @@ namespace internal } private: - const MGLevelObject *vectors; + MGLevelObject> + vectors; }; - template + template double - MGDataEntry::get_cell_data_value( + MGDataEntry::get_cell_data_value( const unsigned int cell_number, const ComponentExtractor extract_component) const { @@ -1691,9 +1712,9 @@ namespace internal - template + template void - MGDataEntry::get_function_values( + MGDataEntry::get_function_values( const FEValuesBase &fe_patch_values, const ComponentExtractor extract_component, std::vector & patch_values) const @@ -1707,7 +1728,7 @@ namespace internal fe_patch_values.get_cell()->index(), this->dof_handler); - const VectorType *vector = &((*vectors)[dof_cell->level()]); + const auto *vector = &(vectors[dof_cell->level()]); const unsigned int dofs_per_cell = this->dof_handler->get_fe(0).n_dofs_per_cell(); @@ -1715,10 +1736,8 @@ namespace internal std::vector dof_indices(dofs_per_cell); dof_cell->get_mg_dof_indices(dof_indices); std::vector values(dofs_per_cell); - VectorHelper::extract(*vector, - dof_indices, - extract_component, - values); + VectorHelper>:: + extract(*vector, dof_indices, extract_component, values); std::fill(patch_values.begin(), patch_values.end(), 0.0); for (unsigned int i = 0; i < dofs_per_cell; ++i) @@ -1729,9 +1748,9 @@ namespace internal - template + template void - MGDataEntry::get_function_values( + MGDataEntry::get_function_values( const FEValuesBase & fe_patch_values, const ComponentExtractor extract_component, std::vector> &patch_values_system) const @@ -1745,7 +1764,7 @@ namespace internal fe_patch_values.get_cell()->index(), this->dof_handler); - const VectorType *vector = &((*vectors)[dof_cell->level()]); + const auto *vector = &(vectors[dof_cell->level()]); const unsigned int dofs_per_cell = this->dof_handler->get_fe(0).n_dofs_per_cell(); @@ -1753,10 +1772,8 @@ namespace internal std::vector dof_indices(dofs_per_cell); dof_cell->get_mg_dof_indices(dof_indices); std::vector values(dofs_per_cell); - VectorHelper::extract(*vector, - dof_indices, - extract_component, - values); + VectorHelper>:: + extract(*vector, dof_indices, extract_component, values); const unsigned int n_components = fe_patch_values.get_fe().n_components(); const unsigned int n_eval_points = fe_patch_values.n_quadrature_points; @@ -2068,7 +2085,8 @@ DataOut_DoFData::add_mg_data_vector( "Invalid number of entries in data_component_interpretation.")); auto new_entry = std::make_unique< - internal::DataOutImplementation::MGDataEntry>( + internal::DataOutImplementation:: + MGDataEntry>( &dof_handler, &data, deduced_names, data_component_interpretation); dof_data.emplace_back(std::move(new_entry)); } -- 2.39.5