From: Peter Munch Date: Sat, 15 Jul 2023 12:34:58 +0000 (+0200) Subject: Use MGTransferGlobalCoarsening also for local smoothing X-Git-Tag: relicensing~613^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4924a83f3f9d6ed4dc872b1ae6d070eb28d3b974;p=dealii.git Use MGTransferGlobalCoarsening also for local smoothing --- diff --git a/include/deal.II/multigrid/mg_transfer.h b/include/deal.II/multigrid/mg_transfer.h index 6f7c7e6071..a4740892eb 100644 --- a/include/deal.II/multigrid/mg_transfer.h +++ b/include/deal.II/multigrid/mg_transfer.h @@ -386,8 +386,7 @@ protected: /** * The mg_constrained_dofs of the level systems. */ - SmartPointer> - mg_constrained_dofs; + SmartPointer mg_constrained_dofs; private: /** @@ -575,10 +574,7 @@ protected: /** * The mg_constrained_dofs of the level systems. */ - SmartPointer< - const MGConstrainedDoFs, - MGLevelGlobalTransfer>> - mg_constrained_dofs; + SmartPointer mg_constrained_dofs; /** * In the function copy_to_mg, we need to access ghosted entries of the diff --git a/include/deal.II/multigrid/mg_transfer_global_coarsening.h b/include/deal.II/multigrid/mg_transfer_global_coarsening.h index 3a72e69c9c..bd58012b31 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.h @@ -320,6 +320,7 @@ protected: */ bool fine_element_is_continuous; +public: /** * Partitioner needed by the intermediate vector. */ @@ -330,6 +331,7 @@ protected: */ std::shared_ptr partitioner_fine; +protected: /** * Internal vector needed for collecting all degrees of freedom of the fine * cells. It is only initialized if the fine-level DoF indices touch DoFs @@ -831,19 +833,22 @@ private: * * The implementation of this class is explained in detail in @cite munch2022gc. */ -template -class MGTransferGlobalCoarsening : public dealii::MGTransferBase +template +class MGTransferMF : public dealii::MGLevelGlobalTransfer< + LinearAlgebra::distributed::Vector> { public: /** * Value type. */ - using Number = typename VectorType::value_type; + using VectorType = LinearAlgebra::distributed::Vector; /** * Default constructor. + * + * @note See also MGTransferMatrixFree. */ - MGTransferGlobalCoarsening() = default; + MGTransferMF() = default; /** * @name Global coarsening. @@ -860,10 +865,9 @@ public: * std::unique_ptr to the actual transfer operator. */ template - MGTransferGlobalCoarsening( - const MGLevelObject &transfer, - const std::function - &initialize_dof_vector = {}); + MGTransferMF(const MGLevelObject &transfer, + const std::function + &initialize_dof_vector = {}); /** * Set two-level transfers. @@ -906,7 +910,7 @@ public: * * @note See also MGTransferMatrixFree. */ - MGTransferGlobalCoarsening(const MGConstrainedDoFs &mg_constrained_dofs); + MGTransferMF(const MGConstrainedDoFs &mg_constrained_dofs); /** * Initialize the constraints to be used in build(). @@ -1011,7 +1015,7 @@ public: /** * Like the above function but with a user-provided DoFHandler as * additional argument. However, this DoFHandler is not used internally, but - * is required to be able to use MGTransferGlobalCoarsening and + * is required to be able to use MGTransferMF and * MGTransferMatrixFree as template argument. */ template @@ -1048,6 +1052,13 @@ public: unsigned int max_level() const; + /** + * Clear all data fields and brings the class into a condition similar + * to after having called the default constructor. + */ + void + clear(); + /** @} */ private: @@ -1072,15 +1083,12 @@ private: /** * Function to initialize internal level vectors. */ + template void - initialize_dof_vector(const unsigned int level, VectorType &vector) const; - - /** - * MGConstrainedDoFs passed during build(). - * - * @note See also MGTransferMatrixFree. - */ - SmartPointer mg_constrained_dofs; + initialize_dof_vector(const unsigned int level, + VectorType & vector, + const InVector & vector_reference, + const bool omit_zeroing_entries) const; /** * Internal transfer operator. @@ -1106,44 +1114,109 @@ private: /** * This class works with LinearAlgebra::distributed::BlockVector and * performs exactly the same transfer operations for each block as - * MGTransferGlobalCoarsening. + * MGTransferMF. */ -template -class MGTransferBlockGlobalCoarsening - : public MGTransferBlockMatrixFreeBase< - dim, - typename VectorType::value_type, - MGTransferGlobalCoarsening> +template +class MGTransferBlockMF + : public MGTransferBlockMatrixFreeBase> { public: /** * Constructor. */ - MGTransferBlockGlobalCoarsening( - const MGTransferGlobalCoarsening &transfer_operator); + MGTransferBlockMF(const MGTransferMF &transfer_operator); + + /** + * Constructor. + * + * @note See also MGTransferBlockMatrixFree. + */ + MGTransferBlockMF() = default; + + /** + * Constructor. + * + * @note See also MGTransferBlockMatrixFree. + */ + MGTransferBlockMF(const MGConstrainedDoFs &mg_constrained_dofs); + + /** + * Constructor. + * + * @note See also MGTransferBlockMatrixFree. + */ + MGTransferBlockMF(const std::vector &mg_constrained_dofs); + + /** + * Initialize the constraints to be used in build(). + * + * @note See also MGTransferBlockMatrixFree. + */ + void + initialize_constraints(const MGConstrainedDoFs &mg_constrained_dofs); + + /** + * Same as above for the case that each block has its own DoFHandler. + * + * @note See also MGTransferBlockMatrixFree. + */ + void + initialize_constraints( + const std::vector &mg_constrained_dofs); + + /** + * Actually build the information for the prolongation for each level. + * + * @note See also MGTransferBlockMatrixFree. + */ + void + build(const DoFHandler &dof_handler); + + /** + * Same as above for the case that each block has its own DoFHandler. + * + * @note See also MGTransferBlockMatrixFree. + */ + void + build(const std::vector *> &dof_handler); protected: - const MGTransferGlobalCoarsening & + const MGTransferMF & get_matrix_free_transfer(const unsigned int b) const override; private: + /** + * Internal non-block version of transfer operation. + */ + std::vector> transfer_operators_internal; + /** * Non-block version of transfer operation. */ - const MGTransferGlobalCoarsening &transfer_operator; + std::vector>> transfer_operators; }; +template +using MGTransferGlobalCoarsening = + MGTransferMF; + +template +using MGTransferBlockGlobalCoarsening = + MGTransferBlockMF; + + + #ifndef DOXYGEN /* ----------------------- Inline functions --------------------------------- */ -template +template template -MGTransferGlobalCoarsening::MGTransferGlobalCoarsening( +MGTransferMF::MGTransferMF( const MGLevelObject &transfer, const std::function &initialize_dof_vector) @@ -1154,19 +1227,10 @@ MGTransferGlobalCoarsening::MGTransferGlobalCoarsening( -template -MGTransferGlobalCoarsening::MGTransferGlobalCoarsening( - const MGConstrainedDoFs &mg_constrained_dofs) -{ - this->initialize_constraints(mg_constrained_dofs); -} - - - -template +template template void -MGTransferGlobalCoarsening::intitialize_two_level_transfers( +MGTransferMF::intitialize_two_level_transfers( const MGLevelObject &transfer) { this->intitialize_transfer_references(transfer); @@ -1174,52 +1238,10 @@ MGTransferGlobalCoarsening::intitialize_two_level_transfers( -template -void -MGTransferGlobalCoarsening::initialize_constraints( - const MGConstrainedDoFs &mg_constrained_dofs) -{ - this->mg_constrained_dofs = &mg_constrained_dofs; -} - - - -template -void -MGTransferGlobalCoarsening::intitialize_internal_transfer( - const DoFHandler & dof_handler, - const SmartPointer &mg_constrained_dofs) -{ - const unsigned int min_level = 0; - const unsigned int max_level = - dof_handler.get_triangulation().n_global_levels() - 1; - - MGLevelObject> constraints( - min_level, max_level); - - if (mg_constrained_dofs) - for (unsigned int l = min_level; l <= max_level; ++l) - mg_constrained_dofs->merge_constraints( - constraints[l], - l, - /*add_boundary_indices*/ true, - /*add_refinement_edge_indices*/ false, - /*add_level_constraints*/ true, - /*add_user_constraints*/ true); - - this->internal_transfer.resize(min_level, max_level); - - for (unsigned int l = min_level; l < max_level; ++l) - internal_transfer[l + 1].reinit_geometric_transfer( - dof_handler, dof_handler, constraints[l + 1], constraints[l], l + 1, l); -} - - - -template +template template void -MGTransferGlobalCoarsening::intitialize_transfer_references( +MGTransferMF::intitialize_transfer_references( const MGLevelObject &transfer) { const unsigned int min_level = transfer.min_level(); @@ -1235,190 +1257,171 @@ MGTransferGlobalCoarsening::intitialize_transfer_references( -template +template +template void -MGTransferGlobalCoarsening::build( - const std::vector> - &external_partitioners) +MGTransferMF::initialize_dof_vector( + const unsigned int level, + VectorType & vec, + const InVector & vec_reference, + const bool omit_zeroing_entries) const { - this->external_partitioners = external_partitioners; + std::shared_ptr partitioner; - if (this->external_partitioners.size() > 0) + if (external_partitioners.empty()) { - const unsigned int min_level = transfer.min_level(); - const unsigned int max_level = transfer.max_level(); - - AssertDimension(this->external_partitioners.size(), transfer.n_levels()); - - for (unsigned int l = min_level + 1; l <= max_level; ++l) - transfer[l]->enable_inplace_operations_if_possible( - this->external_partitioners[l - 1 - min_level], - this->external_partitioners[l - min_level]); + partitioner = vec_reference.get_partitioner(); } -} - - - -template -void -MGTransferGlobalCoarsening::build( - const std::function - &initialize_dof_vector) -{ - if (initialize_dof_vector) + else { - const unsigned int min_level = transfer.min_level(); - const unsigned int max_level = transfer.max_level(); - const unsigned int n_levels = transfer.n_levels(); + Assert(transfer.min_level() <= level && level <= transfer.max_level(), + ExcInternalError()); - std::vector> - external_partitioners(n_levels); + partitioner = external_partitioners[level - transfer.min_level()]; + } - for (unsigned int l = min_level; l <= max_level; ++l) - { - LinearAlgebra::distributed::Vector - vector; - initialize_dof_vector(l, vector); - external_partitioners[l - min_level] = vector.get_partitioner(); - } + // check if vectors are already correctly initalized - this->build(external_partitioners); - } - else + // yes: same partitioners are used + if (vec.get_partitioner().get() == partitioner.get()) { - this->build(); + if (omit_zeroing_entries == false) + vec = 0; + return; // nothing to do } -} - + // yes: vectors are compatible + if (vec.size() == partitioner->size() && + vec.locally_owned_size() == partitioner->locally_owned_size()) + { + if (omit_zeroing_entries == false) + vec = 0; + return; // nothing to do + } -template -void -MGTransferGlobalCoarsening::build( - const DoFHandler &dof_handler, - const std::vector> - &external_partitioners) -{ - this->intitialize_internal_transfer(dof_handler, mg_constrained_dofs); - this->intitialize_transfer_references(internal_transfer); - this->build(external_partitioners); + // no + vec.reinit(partitioner, omit_zeroing_entries); } -template -void -MGTransferGlobalCoarsening::build( - const DoFHandler &dof_handler, - const std::function - &initialize_dof_vector) -{ - this->intitialize_internal_transfer(dof_handler, mg_constrained_dofs); - this->intitialize_transfer_references(internal_transfer); - this->build(initialize_dof_vector); -} - - - -template +template +template void -MGTransferGlobalCoarsening::initialize_dof_vector( - const unsigned int level, - VectorType & vec) const +MGTransferMF::copy_to_mg(const DoFHandler & dof_handler, + MGLevelObject &dst, + const InVector & src) const { - AssertDimension(transfer.n_levels(), external_partitioners.size()); - AssertIndexRange(level, transfer.max_level() + 1); - - const auto &external_partitioner = - external_partitioners[level - transfer.min_level()]; - - if (vec.get_partitioner().get() != external_partitioner.get()) - vec.reinit(external_partitioner); -} + (void)dof_handler; + for (unsigned int level = dst.min_level(); level <= dst.max_level(); ++level) + { + const bool zero_out_values = + (this->perform_plain_copy == false && + this->perform_renumbered_plain_copy == false) || + level != dst.max_level(); + this->initialize_dof_vector(level, dst[level], src, !zero_out_values); + } -template -void -MGTransferGlobalCoarsening::prolongate( - const unsigned int to_level, - VectorType & dst, - const VectorType & src) const -{ - dst = 0; - prolongate_and_add(to_level, dst, src); -} + if (this->perform_plain_copy) + { + dst[dst.max_level()].copy_locally_owned_data_from(src); + } + else if (this->perform_renumbered_plain_copy) + { + auto &dst_level = dst[dst.max_level()]; + for (unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i) + dst_level.local_element(this->copy_indices.back()(1, i)) = + src.local_element(i); + } + else + { + this->ghosted_global_vector = src; + this->ghosted_global_vector.update_ghost_values(); + for (unsigned int l = dst.max_level() + 1; l != dst.min_level();) + { + --l; -template -void -MGTransferGlobalCoarsening::prolongate_and_add( - const unsigned int to_level, - VectorType & dst, - const VectorType & src) const -{ - this->transfer[to_level]->prolongate_and_add(dst, src); -} + auto &dst_level = dst[l]; + const auto copy_unknowns = [&](const auto &indices) { + for (unsigned int i = 0; i < indices.n_cols(); ++i) + dst_level.local_element(indices(1, i)) = + this->ghosted_global_vector.local_element(indices(0, i)); + }; + copy_unknowns(this->copy_indices[l]); + copy_unknowns(this->copy_indices_level_mine[l]); -template -void -MGTransferGlobalCoarsening::restrict_and_add( - const unsigned int from_level, - VectorType & dst, - const VectorType & src) const -{ - this->transfer[from_level]->restrict_and_add(dst, src); + dst_level.compress(VectorOperation::insert); + } + } } -template -template +template +template void -MGTransferGlobalCoarsening::copy_to_mg( - const DoFHandler & dof_handler, - MGLevelObject &dst, - const InVector & src) const +MGTransferMF::copy_from_mg( + const DoFHandler & dof_handler, + OutVector & dst, + const MGLevelObject &src) const { (void)dof_handler; - for (unsigned int level = dst.min_level(); level <= dst.max_level(); ++level) + if (this->perform_plain_copy) { - initialize_dof_vector(level, dst[level]); - - if (level == dst.max_level()) - dst[level].copy_locally_owned_data_from(src); - else - dst[level] = 0.0; + dst.zero_out_ghost_values(); + dst.copy_locally_owned_data_from(src[src.max_level()]); } -} + else if (this->perform_renumbered_plain_copy) + { + const auto &src_level = src[src.max_level()]; + dst.zero_out_ghost_values(); + for (unsigned int i = 0; i < this->copy_indices.back().n_cols(); ++i) + dst.local_element(i) = + src_level.local_element(this->copy_indices.back()(1, i)); + } + else + { + dst = 0; + for (unsigned int l = src.min_level(); l <= src.max_level(); ++l) + { + auto &ghosted_vector = this->ghosted_level_vector[l]; + if (this->ghosted_level_vector[l].size() > 0) + ghosted_vector = src[l]; + const auto *const ghosted_vector_ptr = + (this->ghosted_level_vector[l].size() > 0) ? &ghosted_vector : + &src[l]; -template -template -void -MGTransferGlobalCoarsening::copy_from_mg( - const DoFHandler & dof_handler, - OutVector & dst, - const MGLevelObject &src) const -{ - (void)dof_handler; + ghosted_vector_ptr->update_ghost_values(); + + const auto copy_unknowns = [&](const auto &indices) { + for (unsigned int i = 0; i < indices.n_cols(); ++i) + dst.local_element(indices(0, i)) = + ghosted_vector_ptr->local_element(indices(1, i)); + }; - dst.copy_locally_owned_data_from(src[src.max_level()]); + copy_unknowns(this->copy_indices[l]); + copy_unknowns(this->copy_indices_global_mine[l]); + } + dst.compress(VectorOperation::insert); + } } -template +template template void -MGTransferGlobalCoarsening::interpolate_to_mg( - MGLevelObject &dst, - const InVector & src) const +MGTransferMF::interpolate_to_mg(MGLevelObject &dst, + const InVector &src) const { const unsigned int min_level = transfer.min_level(); const unsigned int max_level = transfer.max_level(); @@ -1427,62 +1430,71 @@ MGTransferGlobalCoarsening::interpolate_to_mg( AssertDimension(max_level, dst.max_level()); for (unsigned int level = min_level; level <= max_level; ++level) - initialize_dof_vector(level, dst[level]); - - dst[transfer.max_level()].copy_locally_owned_data_from(src); - - for (unsigned int l = max_level; l > min_level; --l) - this->transfer[l]->interpolate(dst[l - 1], dst[l]); -} + { + const bool zero_out_values = false; + this->initialize_dof_vector(level, dst[level], src, !zero_out_values); + } + if (this->perform_plain_copy) + { + dst[max_level].copy_locally_owned_data_from(src); + for (unsigned int l = max_level; l > min_level; --l) + this->transfer[l]->interpolate(dst[l - 1], dst[l]); + } + else if (this->perform_renumbered_plain_copy) + { + auto &dst_level = dst[max_level]; -template -template -void -MGTransferGlobalCoarsening::interpolate_to_mg( - const DoFHandler & dof_handler, - MGLevelObject &dst, - const InVector & src) const -{ - (void)dof_handler; + for (unsigned int i = 0; i < this->solution_copy_indices.back().n_cols(); + ++i) + dst_level.local_element(this->solution_copy_indices.back()(1, i)) = + src.local_element(i); - this->interpolate_to_mg(dst, src); -} + for (unsigned int l = max_level; l > min_level; --l) + this->transfer[l]->interpolate(dst[l - 1], dst[l]); + } + else + { + this->solution_ghosted_global_vector = src; + this->solution_ghosted_global_vector.update_ghost_values(); + for (unsigned int l = max_level + 1; l != min_level;) + { + --l; + auto &dst_level = dst[l]; -template -std::size_t -MGTransferGlobalCoarsening::memory_consumption() const -{ - std::size_t size = 0; + const auto copy_unknowns = [&](const auto &indices) { + for (unsigned int i = 0; i < indices.n_cols(); ++i) + dst_level.local_element(indices(1, i)) = + this->solution_ghosted_global_vector.local_element( + indices(0, i)); + }; - const unsigned int min_level = transfer.min_level(); - const unsigned int max_level = transfer.max_level(); + copy_unknowns(this->solution_copy_indices[l]); + copy_unknowns(this->solution_copy_indices_level_mine[l]); - for (unsigned int l = min_level + 1; l <= max_level; ++l) - size += this->transfer[l]->memory_consumption(); + dst_level.compress(VectorOperation::insert); - return size; + if (l != min_level) + this->transfer[l]->interpolate(dst[l - 1], dst[l]); + } + } } -template -inline unsigned int -MGTransferGlobalCoarsening::min_level() const +template +template +void +MGTransferMF::interpolate_to_mg(const DoFHandler &dof_handler, + MGLevelObject &dst, + const InVector &src) const { - return transfer.min_level(); -} - - + (void)dof_handler; -template -inline unsigned int -MGTransferGlobalCoarsening::max_level() const -{ - return transfer.max_level(); + this->interpolate_to_mg(dst, src); } #endif 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 4b67862f64..40c28dc18e 100644 --- a/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h +++ b/include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h @@ -1229,17 +1229,17 @@ namespace internal (mg_level_coarse + 1 == mg_level_fine), ExcNotImplemented()); - if (mg_level_fine != numbers::invalid_unsigned_int) - AssertIndexRange(mg_level_fine, - MGTools::max_level_for_coarse_mesh( - dof_handler_fine.get_triangulation()) + - 1); - - if (mg_level_coarse != numbers::invalid_unsigned_int) - AssertIndexRange(mg_level_coarse, - MGTools::max_level_for_coarse_mesh( - dof_handler_coarse.get_triangulation()) + - 1); + // if (mg_level_fine != numbers::invalid_unsigned_int) + // AssertIndexRange(mg_level_fine, + // MGTools::max_level_for_coarse_mesh( + // dof_handler_fine.get_triangulation()) + + // 1); + // + // if (mg_level_coarse != numbers::invalid_unsigned_int) + // AssertIndexRange(mg_level_coarse, + // MGTools::max_level_for_coarse_mesh( + // dof_handler_coarse.get_triangulation()) + + // 1); const GlobalCoarseningFineDoFHandlerView view(dof_handler_fine, dof_handler_coarse, @@ -3440,27 +3440,345 @@ MGTwoLevelTransferBase>:: -template -MGTransferBlockGlobalCoarsening:: - MGTransferBlockGlobalCoarsening( - const MGTransferGlobalCoarsening &transfer_operator) - : MGTransferBlockMatrixFreeBase>( - true) - , transfer_operator(transfer_operator) -{} +template +MGTransferMF::MGTransferMF( + const MGConstrainedDoFs &mg_constrained_dofs) +{ + this->initialize_constraints(mg_constrained_dofs); +} + + + +template +void +MGTransferMF::initialize_constraints( + const MGConstrainedDoFs &mg_constrained_dofs) +{ + this->mg_constrained_dofs = &mg_constrained_dofs; +} + + + +template +void +MGTransferMF::intitialize_internal_transfer( + const DoFHandler & dof_handler, + const SmartPointer &mg_constrained_dofs) +{ + const unsigned int min_level = 0; + const unsigned int max_level = + dof_handler.get_triangulation().n_global_levels() - 1; + + MGLevelObject> constraints( + min_level, max_level); + + if (mg_constrained_dofs) + for (unsigned int l = min_level; l <= max_level; ++l) + mg_constrained_dofs->merge_constraints( + constraints[l], + l, + /*add_boundary_indices*/ true, + /*add_refinement_edge_indices*/ false, + /*add_level_constraints*/ true, + /*add_user_constraints*/ true); + + this->internal_transfer.resize(min_level, max_level); + + for (unsigned int l = min_level; l < max_level; ++l) + internal_transfer[l + 1].reinit_geometric_transfer( + dof_handler, dof_handler, constraints[l + 1], constraints[l], l + 1, l); +} + + + +template +void +MGTransferMF::build( + const std::vector> + &external_partitioners) +{ + this->external_partitioners = external_partitioners; + + if (this->external_partitioners.size() > 0) + { + const unsigned int min_level = transfer.min_level(); + const unsigned int max_level = transfer.max_level(); + + AssertDimension(this->external_partitioners.size(), transfer.n_levels()); + + for (unsigned int l = min_level + 1; l <= max_level; ++l) + transfer[l]->enable_inplace_operations_if_possible( + this->external_partitioners[l - 1 - min_level], + this->external_partitioners[l - min_level]); + } + else + { + const unsigned int min_level = transfer.min_level(); + const unsigned int max_level = transfer.max_level(); + + for (unsigned int l = min_level + 1; l <= max_level; ++l) + { + if (l == min_level + 1) + this->external_partitioners.push_back( + transfer[l]->partitioner_coarse); + + this->external_partitioners.push_back(transfer[l]->partitioner_fine); + } + } + + this->perform_plain_copy = true; + this->perform_renumbered_plain_copy = false; +} + + + +template +void +MGTransferMF::build( + const std::function + &initialize_dof_vector) +{ + if (initialize_dof_vector) + { + const unsigned int min_level = transfer.min_level(); + const unsigned int max_level = transfer.max_level(); + const unsigned int n_levels = transfer.n_levels(); + + std::vector> + external_partitioners(n_levels); + + for (unsigned int l = min_level; l <= max_level; ++l) + { + LinearAlgebra::distributed::Vector + vector; + initialize_dof_vector(l, vector); + external_partitioners[l - min_level] = vector.get_partitioner(); + } + + this->build(external_partitioners); + } + else + { + this->build(); + } +} + + + +template +void +MGTransferMF::build( + const DoFHandler &dof_handler, + const std::vector> + &external_partitioners) +{ + this->intitialize_internal_transfer(dof_handler, this->mg_constrained_dofs); + this->intitialize_transfer_references(internal_transfer); + this->build(external_partitioners); + this->fill_and_communicate_copy_indices(dof_handler); +} + + + +template +void +MGTransferMF::build( + const DoFHandler &dof_handler, + const std::function + &initialize_dof_vector) +{ + this->intitialize_internal_transfer(dof_handler, this->mg_constrained_dofs); + this->intitialize_transfer_references(internal_transfer); + this->build(initialize_dof_vector); + this->fill_and_communicate_copy_indices(dof_handler); +} + + + +template +void +MGTransferMF::prolongate(const unsigned int to_level, + VectorType & dst, + const VectorType & src) const +{ + dst = 0; + prolongate_and_add(to_level, dst, src); +} + + + +template +void +MGTransferMF::prolongate_and_add(const unsigned int to_level, + VectorType & dst, + const VectorType & src) const +{ + this->transfer[to_level]->prolongate_and_add(dst, src); +} + + + +template +void +MGTransferMF::restrict_and_add(const unsigned int from_level, + VectorType & dst, + const VectorType & src) const +{ + this->transfer[from_level]->restrict_and_add(dst, src); +} + + + +template +std::size_t +MGTransferMF::memory_consumption() const +{ + std::size_t size = 0; + + const unsigned int min_level = transfer.min_level(); + const unsigned int max_level = transfer.max_level(); + + for (unsigned int l = min_level + 1; l <= max_level; ++l) + size += this->transfer[l]->memory_consumption(); + + return size; +} + + + +template +inline unsigned int +MGTransferMF::min_level() const +{ + return transfer.min_level(); +} + + + +template +inline unsigned int +MGTransferMF::max_level() const +{ + return transfer.max_level(); +} + + +template +inline void +MGTransferMF::clear() +{ + MGLevelGlobalTransfer::clear(); + + internal_transfer.clear(); + transfer.clear(); + external_partitioners.clear(); +} + + + +template +MGTransferBlockMF::MGTransferBlockMF( + const MGTransferMF &transfer_operator) + : MGTransferBlockMatrixFreeBase>(true) +{ + this->transfer_operators = {&transfer_operator}; +} + + + +template +MGTransferBlockMF::MGTransferBlockMF( + const MGConstrainedDoFs &mg_constrained_dofs) + : MGTransferBlockMatrixFreeBase>(true) +{ + initialize_constraints(mg_constrained_dofs); +} + + + +template +MGTransferBlockMF::MGTransferBlockMF( + const std::vector &mg_constrained_dofs) + : MGTransferBlockMatrixFreeBase>(false) +{ + initialize_constraints(mg_constrained_dofs); +} + + + +template +void +MGTransferBlockMF::initialize_constraints( + const MGConstrainedDoFs &mg_constrained_dofs) +{ + this->transfer_operators_internal.clear(); + this->transfer_operators.clear(); + + Assert(this->same_for_all, + ExcMessage("This object was initialized with support for usage with " + "one DoFHandler for each block, but this method assumes " + "that the same DoFHandler is used for all the blocks!")); + + this->transfer_operators_internal.emplace_back(mg_constrained_dofs); + this->transfer_operators = {&transfer_operators_internal.back()}; +} -template -const MGTransferGlobalCoarsening & -MGTransferBlockGlobalCoarsening::get_matrix_free_transfer( +template +void +MGTransferBlockMF::initialize_constraints( + const std::vector &mg_constrained_dofs) +{ + this->transfer_operators_internal.clear(); + this->transfer_operators.clear(); + + Assert(!this->same_for_all, + ExcMessage("This object was initialized with support for using " + "the same DoFHandler for all the blocks, but this " + "method assumes that there is a separate DoFHandler " + "for each block!")); + + for (const auto &dofs : mg_constrained_dofs) + this->transfer_operators_internal.emplace_back(dofs); + + for (const auto &transfer : this->transfer_operators_internal) + this->transfer_operators.emplace_back(&transfer); +} + + + +template +void +MGTransferBlockMF::build(const DoFHandler &dof_handler) +{ + AssertDimension(transfer_operators.size(), 1); + this->transfer_operators_internal[0].build(dof_handler); +} + + + +template +void +MGTransferBlockMF::build( + const std::vector *> &dof_handler) +{ + AssertDimension(transfer_operators.size(), dof_handler.size()); + AssertDimension(transfer_operators_internal.size(), dof_handler.size()); + + for (unsigned int i = 0; i < dof_handler.size(); ++i) + this->transfer_operators_internal[i].build(*dof_handler[i]); +} + + + +template +const MGTransferMF & +MGTransferBlockMF::get_matrix_free_transfer( const unsigned int b) const { - (void)b; - AssertDimension(b, 0); - return transfer_operator; + AssertIndexRange(b, transfer_operators.size()); + return *transfer_operators[b]; } namespace internal diff --git a/source/multigrid/mg_level_global_transfer.cc b/source/multigrid/mg_level_global_transfer.cc index 5abd0f0eff..61fd9ba060 100644 --- a/source/multigrid/mg_level_global_transfer.cc +++ b/source/multigrid/mg_level_global_transfer.cc @@ -160,11 +160,8 @@ namespace template void fill_internal( - const DoFHandler &mg_dof, - SmartPointer< - const MGConstrainedDoFs, - MGLevelGlobalTransfer>> - mg_constrained_dofs, + const DoFHandler & mg_dof, + SmartPointer mg_constrained_dofs, const MPI_Comm mpi_communicator, const bool transfer_solution_vectors, std::vector> & copy_indices, diff --git a/source/multigrid/mg_transfer_global_coarsening.inst.in b/source/multigrid/mg_transfer_global_coarsening.inst.in index 49edd3085d..62a9600349 100644 --- a/source/multigrid/mg_transfer_global_coarsening.inst.in +++ b/source/multigrid/mg_transfer_global_coarsening.inst.in @@ -30,11 +30,9 @@ for (deal_II_dimension : DIMENSIONS; S1 : REAL_SCALARS) template class MGTransferBlockMatrixFreeBase< deal_II_dimension, S1, - MGTransferGlobalCoarsening>>; - template class MGTransferBlockGlobalCoarsening< - deal_II_dimension, - LinearAlgebra::distributed::Vector>; + MGTransferMF>; + template class MGTransferMF; + template class MGTransferBlockMF; } for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS) diff --git a/tests/multigrid-global-coarsening/interpolate_to_mg.cc b/tests/multigrid-global-coarsening/interpolate_to_mg.cc new file mode 100644 index 0000000000..296393181b --- /dev/null +++ b/tests/multigrid-global-coarsening/interpolate_to_mg.cc @@ -0,0 +1,275 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test MGTransferMatrixFree::interpolate_to_mg() +// for a scalar field + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include + +#include "../tests.h" + + + +template +class SimpleField : public Function +{ +public: + SimpleField() + : Function(1) + {} + + double + value(const Point &p, const unsigned int component = 0) const + { + (void)component; + return p[0] * 2. + p[1] - 10.; + } +}; + + +template +void +test(const unsigned int n_glob_ref = 2, const unsigned int n_ref = 0) +{ + SimpleField function; + + deallog << "dim=" << dim << std::endl; + MPI_Comm mpi_communicator(MPI_COMM_WORLD); + unsigned int myid = Utilities::MPI::this_mpi_process(mpi_communicator); + unsigned int numproc = Utilities::MPI::n_mpi_processes(mpi_communicator); + + deallog << "numproc=" << numproc << std::endl; + + parallel::distributed::Triangulation triangulation( + mpi_communicator, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(triangulation, 5, -1, 1); + // now do some refinement + triangulation.refine_global(n_glob_ref); + for (unsigned int ref = 0; ref < n_ref; ++ref) + { + for (typename Triangulation::active_cell_iterator cell = + triangulation.begin_active(); + cell != triangulation.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + triangulation.execute_coarsening_and_refinement(); + } + + FE_Q fe(fe_degree); + DoFHandler dof_handler(triangulation); + + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + IndexSet locally_owned_dofs, locally_relevant_dofs; + locally_owned_dofs = dof_handler.locally_owned_dofs(); + DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs); + + // constraints: + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + constraints.close(); + + + // interpolate: + LinearAlgebra::distributed::Vector fine_projection; + fine_projection.reinit(locally_owned_dofs, + locally_relevant_dofs, + mpi_communicator); + VectorTools::project(dof_handler, + constraints, + QGauss(n_q_points + 2), + function, + fine_projection); + fine_projection.update_ghost_values(); + + // output for debug purposes: + if (false) + { + DataOut data_out; + data_out.attach_dof_handler(dof_handler); + data_out.add_data_vector(fine_projection, "projection"); + + Vector subdomain(triangulation.n_active_cells()); + for (unsigned int i = 0; i < subdomain.size(); ++i) + subdomain(i) = triangulation.locally_owned_subdomain(); + data_out.add_data_vector(subdomain, "subdomain"); + data_out.build_patches(); + const std::string filename = + "output_" + Utilities::int_to_string(myid) + ".vtu"; + std::ofstream output(filename); + data_out.write_vtu(output); + + const std::string mg_mesh = "mg_mesh"; + GridOut grid_out; + grid_out.write_mesh_per_processor_as_vtu(triangulation, + mg_mesh, + true, + true); + } + + // MG hanging node constraints + // we do not add extra zero Dirichlet BC here + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof_handler); + + // MG transfer: + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof_handler); + + // now the core of the test: + const unsigned int max_level = + dof_handler.get_triangulation().n_global_levels() - 1; + const unsigned int min_level = 0; + MGLevelObject> + level_projection(min_level, max_level); + for (unsigned int level = min_level; level <= max_level; ++level) + { + IndexSet set; + DoFTools::extract_locally_relevant_level_dofs(dof_handler, level, set); + level_projection[level].reinit(dof_handler.locally_owned_mg_dofs(level), + set, + mpi_communicator); + } + mg_transfer.interpolate_to_mg(dof_handler, level_projection, fine_projection); + + // now go through all GMG levels and make sure FE field can represent + // analytic function exactly: + QGauss quadrature(n_q_points); + std::vector q_values(quadrature.size()); + + FEValues fe_values(fe, + quadrature, + update_values | update_quadrature_points); + for (unsigned int level = max_level + 1; level != min_level;) + { + --level; + + level_projection[level].update_ghost_values(); + + std::vector dof_indices(fe.dofs_per_cell); + typename DoFHandler::cell_iterator cell = dof_handler.begin(level); + typename DoFHandler::cell_iterator endc = dof_handler.end(level); + for (; cell != endc; ++cell) + if (cell->is_locally_owned_on_level()) + { + fe_values.reinit(cell); + cell->get_mg_dof_indices(dof_indices); + fe_values.get_function_values(level_projection[level], + dof_indices, + q_values); + + const std::vector> &q_points = + fe_values.get_quadrature_points(); + + for (unsigned int q = 0; q < q_points.size(); ++q) + { + const double diff = q_values[q] - function.value(q_points[q]); + if (std::abs(diff) > 1e-10) + { + std::cout << "dofs: "; + for (const auto i : dof_indices) + std::cout << i << ' '; + std::cout << std::endl << "values: "; + std::vector local_values( + dof_indices.size()); + level_projection[level].extract_subvector_to(dof_indices, + local_values); + for (const auto v : local_values) + std::cout << v << ' '; + std::cout << std::endl + << "val(q)=" << q_values[q] << std::endl; + std::cout << "MGTransfer indices:" << std::endl; + mg_transfer.print_indices(std::cout); + AssertThrow(false, + ExcMessage("Level " + std::to_string(level) + + " Diff " + std::to_string(diff) + + " center_x " + + std::to_string(cell->center()[0]) + + " center_y " + + std::to_string(cell->center()[1]))); + } + } + } + } + + deallog << "Ok" << std::endl; +} + + + +int +main(int argc, char *argv[]) +{ + Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + MPILogInitAll log; + + test<2>(); + test<2, 1>(0, 1); +} diff --git a/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=1.output b/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=1.output new file mode 100644 index 0000000000..dad0ed2a3a --- /dev/null +++ b/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=1.output @@ -0,0 +1,7 @@ + +DEAL:0::dim=2 +DEAL:0::numproc=1 +DEAL:0::Ok +DEAL:0::dim=2 +DEAL:0::numproc=1 +DEAL:0::Ok diff --git a/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..a4a680237e --- /dev/null +++ b/tests/multigrid-global-coarsening/interpolate_to_mg.with_p4est=true.mpirun=3.output @@ -0,0 +1,23 @@ + +DEAL:0::dim=2 +DEAL:0::numproc=3 +DEAL:0::Ok +DEAL:0::dim=2 +DEAL:0::numproc=3 +DEAL:0::Ok + +DEAL:1::dim=2 +DEAL:1::numproc=3 +DEAL:1::Ok +DEAL:1::dim=2 +DEAL:1::numproc=3 +DEAL:1::Ok + + +DEAL:2::dim=2 +DEAL:2::numproc=3 +DEAL:2::Ok +DEAL:2::dim=2 +DEAL:2::numproc=3 +DEAL:2::Ok + diff --git a/tests/multigrid-global-coarsening/interpolate_to_mg_01.cc b/tests/multigrid-global-coarsening/interpolate_to_mg_01.cc new file mode 100644 index 0000000000..a58f98554c --- /dev/null +++ b/tests/multigrid-global-coarsening/interpolate_to_mg_01.cc @@ -0,0 +1,134 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2021 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test function MGTransferMatrixFree::interpolate_to_mg() for periodic +// boundaries + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include "../tests.h" + +template +class RightHandSideFunction : public Function +{ +public: + RightHandSideFunction(const unsigned int n_components) + : Function(n_components) + {} + + virtual double + value(const Point &p, const unsigned int component = 0) const + { + return p[component % dim] * p[component % dim]; + } +}; + +template +void +test() +{ + const unsigned int fe_degree = 1; + + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + + GridGenerator::hyper_cube(tria, -1., 1., true); + + std::vector>>> + tria_matched_pairs; + GridTools::collect_periodic_faces(tria, 0, 1, 0, tria_matched_pairs); + tria.add_periodicity(tria_matched_pairs); + tria.refine_global(2); + + const FE_Q fe(fe_degree); + DoFHandler dof_handler(tria); + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs); + + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + + std::vector< + GridTools::PeriodicFacePair::cell_iterator>> + dof_matched_pairs; + GridTools::collect_periodic_faces(dof_handler, 0, 1, 0, dof_matched_pairs); + DoFTools::make_periodicity_constraints(dof_matched_pairs, + constraints); + constraints.close(); + + LinearAlgebra::distributed::Vector qsol( + dof_handler.locally_owned_dofs(), locally_relevant_dofs, MPI_COMM_WORLD); + + VectorTools::interpolate(MappingQ1(), + dof_handler, + RightHandSideFunction(1), + qsol); + + MGLevelObject> mg_qsol; + MGConstrainedDoFs mg_constrained_dofs; + MGTransferMF mg_transfer; + + unsigned int n_tria_levels = tria.n_global_levels(); + mg_qsol.resize(0, n_tria_levels - 1); + + mg_constrained_dofs.initialize(dof_handler); + mg_transfer.initialize_constraints(mg_constrained_dofs); + mg_transfer.build(dof_handler); + + mg_transfer.interpolate_to_mg(dof_handler, mg_qsol, qsol); + + for (unsigned int i = mg_qsol.min_level(); i <= mg_qsol.max_level(); ++i) + deallog << mg_qsol[i].l2_norm() << std::endl; + + deallog << "OK" << std::endl; +} + + + +int +main(int argc, char *argv[]) +{ + Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + MPILogInitAll all; + + test<2>(); +} diff --git a/tests/multigrid-global-coarsening/interpolate_to_mg_01.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/interpolate_to_mg_01.with_p4est=true.mpirun=2.output new file mode 100644 index 0000000000..5bc629fc1d --- /dev/null +++ b/tests/multigrid-global-coarsening/interpolate_to_mg_01.with_p4est=true.mpirun=2.output @@ -0,0 +1,11 @@ + +DEAL:0::2.00000 +DEAL:0::2.44949 +DEAL:0::3.25960 +DEAL:0::OK + +DEAL:1::2.00000 +DEAL:1::2.44949 +DEAL:1::3.25960 +DEAL:1::OK + diff --git a/tests/multigrid-global-coarsening/mg_data_out_04.cc b/tests/multigrid-global-coarsening/mg_data_out_04.cc new file mode 100644 index 0000000000..7504161416 --- /dev/null +++ b/tests/multigrid-global-coarsening/mg_data_out_04.cc @@ -0,0 +1,123 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2006 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// Test DataOut::add_mg_data_vector in parallel + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "../tests.h" + + +template +void +do_test() +{ + parallel::distributed::Triangulation triangulation( + MPI_COMM_WORLD, + dealii::Triangulation::none, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + + GridGenerator::hyper_cube(triangulation); + triangulation.refine_global(1); + triangulation.begin_active()->set_refine_flag(); + triangulation.execute_coarsening_and_refinement(); + + FE_Q fe(1); + DoFHandler dof_handler(triangulation); + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + // Make FE vector + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs); + + using VectorType = LinearAlgebra::distributed::Vector; + VectorType global_dof_vector; + global_dof_vector.reinit(dof_handler.locally_owned_dofs(), + locally_relevant_dofs, + MPI_COMM_WORLD); + + VectorTools::interpolate(dof_handler, + Functions::SquareFunction(), + global_dof_vector); + global_dof_vector.update_ghost_values(); + + { + DataOut data_out; + data_out.attach_dof_handler(dof_handler); + data_out.add_data_vector(dof_handler, + global_dof_vector, + std::vector(1, "data")); + data_out.build_patches(0); + data_out.write_gnuplot(deallog.get_file_stream()); + data_out.write_vtu_in_parallel("base.vtu", MPI_COMM_WORLD); + } + + { + MGLevelObject dof_vector(0, + triangulation.n_global_levels() - 1); + MGTransferMF transfer; + + transfer.build(dof_handler); + transfer.interpolate_to_mg(dof_handler, dof_vector, global_dof_vector); + + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + { + deallog << "* level " << level << std::endl; + DataOut data_out; + data_out.set_cell_selection( + [level](const typename Triangulation::cell_iterator &cell) { + return (cell->level() == static_cast(level) && + cell->is_locally_owned_on_level()); + }); + data_out.attach_triangulation(triangulation); + dof_vector[level].update_ghost_values(); + data_out.add_mg_data_vector(dof_handler, dof_vector, "data"); + data_out.build_patches(0); + data_out.write_gnuplot(deallog.get_file_stream()); + data_out.write_vtu_in_parallel(std::string("level") + + Utilities::to_string(level) + ".vtu", + MPI_COMM_WORLD); + } + } +} + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + MPILogInitAll log; + + do_test<2>(); + // do_test<3>(); + return 0; +} diff --git a/tests/multigrid-global-coarsening/mg_data_out_04.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/mg_data_out_04.with_p4est=true.mpirun=2.output new file mode 100644 index 0000000000..568ac41070 --- /dev/null +++ b/tests/multigrid-global-coarsening/mg_data_out_04.with_p4est=true.mpirun=2.output @@ -0,0 +1,163 @@ + +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 0.00000 +0.250000 0.00000 0.0625000 + +0.00000 0.250000 0.0625000 +0.250000 0.250000 0.125000 + + +0.250000 0.00000 0.0625000 +0.500000 0.00000 0.250000 + +0.250000 0.250000 0.125000 +0.500000 0.250000 0.312500 + + +0.00000 0.250000 0.0625000 +0.250000 0.250000 0.125000 + +0.00000 0.500000 0.250000 +0.250000 0.500000 0.312500 + + +0.250000 0.250000 0.125000 +0.500000 0.250000 0.312500 + +0.250000 0.500000 0.312500 +0.500000 0.500000 0.500000 + + +DEAL:0::* level 0 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 0.00000 +1.00000 0.00000 1.00000 + +0.00000 1.00000 1.00000 +1.00000 1.00000 2.00000 + + +DEAL:0::* level 1 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 0.00000 +0.500000 0.00000 0.250000 + +0.00000 0.500000 0.250000 +0.500000 0.500000 0.500000 + + +DEAL:0::* level 2 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 0.00000 +0.250000 0.00000 0.0625000 + +0.00000 0.250000 0.0625000 +0.250000 0.250000 0.125000 + + +0.250000 0.00000 0.0625000 +0.500000 0.00000 0.250000 + +0.250000 0.250000 0.125000 +0.500000 0.250000 0.312500 + + +0.00000 0.250000 0.0625000 +0.250000 0.250000 0.125000 + +0.00000 0.500000 0.250000 +0.250000 0.500000 0.312500 + + +0.250000 0.250000 0.125000 +0.500000 0.250000 0.312500 + +0.250000 0.500000 0.312500 +0.500000 0.500000 0.500000 + + + +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.500000 0.00000 0.250000 +1.00000 0.00000 1.00000 + +0.500000 0.500000 0.500000 +1.00000 0.500000 1.25000 + + +0.00000 0.500000 0.250000 +0.500000 0.500000 0.500000 + +0.00000 1.00000 1.00000 +0.500000 1.00000 1.25000 + + +0.500000 0.500000 0.500000 +1.00000 0.500000 1.25000 + +0.500000 1.00000 1.25000 +1.00000 1.00000 2.00000 + + +DEAL:1::* level 0 +DEAL:1::* level 1 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.500000 0.00000 0.250000 +1.00000 0.00000 1.00000 + +0.500000 0.500000 0.500000 +1.00000 0.500000 1.25000 + + +0.00000 0.500000 0.250000 +0.500000 0.500000 0.500000 + +0.00000 1.00000 1.00000 +0.500000 1.00000 1.25000 + + +0.500000 0.500000 0.500000 +1.00000 0.500000 1.25000 + +0.500000 1.00000 1.25000 +1.00000 1.00000 2.00000 + + +DEAL:1::* level 2 + diff --git a/tests/multigrid-global-coarsening/mg_data_out_05.cc b/tests/multigrid-global-coarsening/mg_data_out_05.cc new file mode 100644 index 0000000000..5848f0ecd6 --- /dev/null +++ b/tests/multigrid-global-coarsening/mg_data_out_05.cc @@ -0,0 +1,151 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2006 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// Test DataOut::add_mg_data_vector in parallel for a vector valued dof function + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "../tests.h" + + +template +void +do_test() +{ + parallel::distributed::Triangulation triangulation( + MPI_COMM_WORLD, + dealii::Triangulation::none, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + + GridGenerator::hyper_cube(triangulation); + triangulation.refine_global(1); + triangulation.begin_active()->set_refine_flag(); + triangulation.execute_coarsening_and_refinement(); + + FESystem fe(FE_DGQ(1), dim + 1); + + DoFHandler dof_handler(triangulation); + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + // Make FE vector + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs); + + using VectorType = LinearAlgebra::distributed::Vector; + VectorType global_dof_vector; + global_dof_vector.reinit(dof_handler.locally_owned_dofs(), + locally_relevant_dofs, + MPI_COMM_WORLD); + + QGauss quadrature(3); + + FunctionParser function(dim == 2 ? "y;-x;x*x+y*y" : + "y;-x;0;x*x+y*y+z*z"); + + AffineConstraints constraints; + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + constraints.close(); + VectorTools::project( + dof_handler, constraints, quadrature, function, global_dof_vector); + /* VectorTools::interpolate(dof_handler, + Functions::SquareFunction(), + global_dof_vector); + */ + + global_dof_vector.update_ghost_values(); + + std::vector names(dim, "vec"); + names.emplace_back("my_scalar"); + std::vector + interpretation(dim, + DataComponentInterpretation::component_is_part_of_vector); + interpretation.emplace_back(DataComponentInterpretation::component_is_scalar); + + { + DataOut data_out; + data_out.attach_dof_handler(dof_handler); + data_out.add_data_vector(dof_handler, + global_dof_vector, + names, + interpretation); + data_out.build_patches(0); + data_out.write_gnuplot(deallog.get_file_stream()); + data_out.write_vtu_in_parallel("base.vtu", MPI_COMM_WORLD); + } + + { + MGLevelObject dof_vector(0, + triangulation.n_global_levels() - 1); + MGTransferMF transfer; + + transfer.build(dof_handler); + transfer.interpolate_to_mg(dof_handler, dof_vector, global_dof_vector); + + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + { + deallog << "* level " << level << std::endl; + DataOut data_out; + data_out.set_cell_selection( + [level](const typename Triangulation::cell_iterator &cell) { + return (cell->level() == static_cast(level) && + cell->is_locally_owned_on_level()); + }); + data_out.attach_triangulation(triangulation); + dof_vector[level].update_ghost_values(); + data_out.add_mg_data_vector(dof_handler, dof_vector, "data"); + data_out.add_mg_data_vector(dof_handler, + dof_vector, + names, + interpretation); + data_out.build_patches(0); + data_out.write_gnuplot(deallog.get_file_stream()); + data_out.write_vtu_in_parallel(std::string("level") + + Utilities::to_string(level) + ".vtu", + MPI_COMM_WORLD); + } + } +} + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + MPILogInitAll log; + + do_test<2>(); + // do_test<3>(); + return 0; +} diff --git a/tests/multigrid-global-coarsening/mg_data_out_05.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/mg_data_out_05.with_p4est=true.mpirun=2.output new file mode 100644 index 0000000000..b816a43ec9 --- /dev/null +++ b/tests/multigrid-global-coarsening/mg_data_out_05.with_p4est=true.mpirun=2.output @@ -0,0 +1,163 @@ + +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 -6.93889e-17 2.77556e-17 -0.0208333 +0.250000 0.00000 -5.55112e-17 -0.250000 0.0416667 + +0.00000 0.250000 0.250000 2.77556e-17 0.0416667 +0.250000 0.250000 0.250000 -0.250000 0.104167 + + +0.250000 0.00000 -6.93889e-17 -0.250000 0.0416667 +0.500000 0.00000 -5.55112e-17 -0.500000 0.229167 + +0.250000 0.250000 0.250000 -0.250000 0.104167 +0.500000 0.250000 0.250000 -0.500000 0.291667 + + +0.00000 0.250000 0.250000 2.77556e-17 0.0416667 +0.250000 0.250000 0.250000 -0.250000 0.104167 + +0.00000 0.500000 0.500000 2.77556e-17 0.229167 +0.250000 0.500000 0.500000 -0.250000 0.291667 + + +0.250000 0.250000 0.250000 -0.250000 0.104167 +0.500000 0.250000 0.250000 -0.500000 0.291667 + +0.250000 0.500000 0.500000 -0.250000 0.291667 +0.500000 0.500000 0.500000 -0.500000 0.479167 + + +DEAL:0::* level 0 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 -2.35922e-16 1.24900e-16 -0.333333 -2.35922e-16 1.24900e-16 -0.333333 +1.00000 0.00000 5.55112e-17 -1.00000 0.666667 5.55112e-17 -1.00000 0.666667 + +0.00000 1.00000 1.00000 1.66533e-16 0.666667 1.00000 1.66533e-16 0.666667 +1.00000 1.00000 1.00000 -1.00000 1.66667 1.00000 -1.00000 1.66667 + + +DEAL:0::* level 1 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 -3.46945e-17 6.93889e-18 -0.0833333 -3.46945e-17 6.93889e-18 -0.0833333 +0.500000 0.00000 0.00000 -0.500000 0.166667 0.00000 -0.500000 0.166667 + +0.00000 0.500000 0.500000 1.11022e-16 0.166667 0.500000 1.11022e-16 0.166667 +0.500000 0.500000 0.500000 -0.500000 0.416667 0.500000 -0.500000 0.416667 + + +DEAL:0::* level 2 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.00000 0.00000 -6.93889e-17 2.77556e-17 -0.0208333 -6.93889e-17 2.77556e-17 -0.0208333 +0.250000 0.00000 -5.55112e-17 -0.250000 0.0416667 -5.55112e-17 -0.250000 0.0416667 + +0.00000 0.250000 0.250000 2.77556e-17 0.0416667 0.250000 2.77556e-17 0.0416667 +0.250000 0.250000 0.250000 -0.250000 0.104167 0.250000 -0.250000 0.104167 + + +0.250000 0.00000 -6.93889e-17 -0.250000 0.0416667 -6.93889e-17 -0.250000 0.0416667 +0.500000 0.00000 -5.55112e-17 -0.500000 0.229167 -5.55112e-17 -0.500000 0.229167 + +0.250000 0.250000 0.250000 -0.250000 0.104167 0.250000 -0.250000 0.104167 +0.500000 0.250000 0.250000 -0.500000 0.291667 0.250000 -0.500000 0.291667 + + +0.00000 0.250000 0.250000 2.77556e-17 0.0416667 0.250000 2.77556e-17 0.0416667 +0.250000 0.250000 0.250000 -0.250000 0.104167 0.250000 -0.250000 0.104167 + +0.00000 0.500000 0.500000 2.77556e-17 0.229167 0.500000 2.77556e-17 0.229167 +0.250000 0.500000 0.500000 -0.250000 0.291667 0.500000 -0.250000 0.291667 + + +0.250000 0.250000 0.250000 -0.250000 0.104167 0.250000 -0.250000 0.104167 +0.500000 0.250000 0.250000 -0.500000 0.291667 0.250000 -0.500000 0.291667 + +0.250000 0.500000 0.500000 -0.250000 0.291667 0.500000 -0.250000 0.291667 +0.500000 0.500000 0.500000 -0.500000 0.479167 0.500000 -0.500000 0.479167 + + + +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.500000 0.00000 -1.38778e-16 -0.500000 0.166667 +1.00000 0.00000 -1.11022e-16 -1.00000 0.916667 + +0.500000 0.500000 0.500000 -0.500000 0.416667 +1.00000 0.500000 0.500000 -1.00000 1.16667 + + +0.00000 0.500000 0.500000 5.55112e-17 0.166667 +0.500000 0.500000 0.500000 -0.500000 0.416667 + +0.00000 1.00000 1.00000 5.55112e-17 0.916667 +0.500000 1.00000 1.00000 -0.500000 1.16667 + + +0.500000 0.500000 0.500000 -0.500000 0.416667 +1.00000 0.500000 0.500000 -1.00000 1.16667 + +0.500000 1.00000 1.00000 -0.500000 1.16667 +1.00000 1.00000 1.00000 -1.00000 1.91667 + + +DEAL:1::* level 0 +DEAL:1::* level 1 +# This file was generated by the deal.II library. + + +# +# For a description of the GNUPLOT format see the GNUPLOT manual. +# +# +0.500000 0.00000 -1.38778e-16 -0.500000 0.166667 -1.38778e-16 -0.500000 0.166667 +1.00000 0.00000 -1.11022e-16 -1.00000 0.916667 -1.11022e-16 -1.00000 0.916667 + +0.500000 0.500000 0.500000 -0.500000 0.416667 0.500000 -0.500000 0.416667 +1.00000 0.500000 0.500000 -1.00000 1.16667 0.500000 -1.00000 1.16667 + + +0.00000 0.500000 0.500000 5.55112e-17 0.166667 0.500000 5.55112e-17 0.166667 +0.500000 0.500000 0.500000 -0.500000 0.416667 0.500000 -0.500000 0.416667 + +0.00000 1.00000 1.00000 5.55112e-17 0.916667 1.00000 5.55112e-17 0.916667 +0.500000 1.00000 1.00000 -0.500000 1.16667 1.00000 -0.500000 1.16667 + + +0.500000 0.500000 0.500000 -0.500000 0.416667 0.500000 -0.500000 0.416667 +1.00000 0.500000 0.500000 -1.00000 1.16667 0.500000 -1.00000 1.16667 + +0.500000 1.00000 1.00000 -0.500000 1.16667 1.00000 -0.500000 1.16667 +1.00000 1.00000 1.00000 -1.00000 1.91667 1.00000 -1.00000 1.91667 + + +DEAL:1::* level 2 + diff --git a/tests/multigrid-global-coarsening/multigrid_dg_periodic.cc b/tests/multigrid-global-coarsening/multigrid_dg_periodic.cc new file mode 100644 index 0000000000..736aa64be5 --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_periodic.cc @@ -0,0 +1,639 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// same as multigrid_dg_sip but using periodic boundary conditions + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler &dof_handler, + const unsigned int n_q_points_1d, + const unsigned int level = numbers::invalid_unsigned_int) + { + fe_degree = dof_handler.get_fe().degree; + + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + addit_data.mapping_update_flags_inner_faces = + (update_gradients | update_JxW_values); + addit_data.mapping_update_flags_boundary_faces = + (update_gradients | update_JxW_values); + AffineConstraints constraints; + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + data.loop(&LaplaceOperator::local_apply, + &LaplaceOperator::local_apply_face, + &LaplaceOperator::local_apply_boundary, + this, + dst, + src); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + local_apply_face( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + FEFaceEvaluation fe_eval_neighbor(data, false); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval_neighbor.reinit(face); + + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval_neighbor.read_dof_values(src); + fe_eval_neighbor.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + VectorizedArray sigmaF = + (std::abs((fe_eval.normal_vector(0) * + fe_eval.inverse_jacobian(0))[dim - 1]) + + std::abs((fe_eval.normal_vector(0) * + fe_eval_neighbor.inverse_jacobian(0))[dim - 1])) * + (number)(std::max(fe_degree, 1) * (fe_degree + 1.0)); + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = + (fe_eval.get_value(q) - fe_eval_neighbor.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + fe_eval.get_normal_derivative(q) + + fe_eval_neighbor.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval_neighbor.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + fe_eval_neighbor.submit_value(-average_valgrad, q); + } + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + fe_eval_neighbor.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + fe_eval_neighbor.distribute_local_to_global(dst); + } + } + + void + local_apply_boundary( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + VectorizedArray sigmaF = + std::abs( + (fe_eval.normal_vector(0) * fe_eval.inverse_jacobian(0))[dim - 1]) * + (number)(std::max(1, fe_degree) * (fe_degree + 1.0)) * 2.; + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = fe_eval.get_value(q); + VectorizedArray average_valgrad = + -fe_eval.get_normal_derivative(q); + average_valgrad += average_value * sigmaF * 2.0; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + } + + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.loop(&LaplaceOperator::local_diagonal_cell, + &LaplaceOperator::local_diagonal_face, + &LaplaceOperator::local_diagonal_boundary, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + void + local_diagonal_face( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &face_range) const + { + FEFaceEvaluation phi(data, true); + FEFaceEvaluation phi_outer(data, false); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + phi.reinit(face); + phi_outer.reinit(face); + + VectorizedArray sigmaF = + (std::abs((phi.normal_vector(0) * phi.inverse_jacobian(0))[dim - 1]) + + std::abs( + (phi.normal_vector(0) * phi_outer.inverse_jacobian(0))[dim - 1])) * + (number)(std::max(fe_degree, 1) * (fe_degree + 1.0)); + + // Compute phi part + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi_outer.begin_dof_values()[j] = VectorizedArray(); + phi_outer.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = + (phi.get_value(q) - phi_outer.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + phi.get_normal_derivative(q) + + phi_outer.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + phi.submit_normal_derivative(-average_value, q); + phi.submit_value(average_valgrad, q); + } + phi.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + + // Compute phi_outer part + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi_outer.begin_dof_values()[j] = VectorizedArray(); + phi_outer.begin_dof_values()[i] = 1.; + phi_outer.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = + (phi.get_value(q) - phi_outer.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + phi.get_normal_derivative(q) + + phi_outer.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + phi_outer.submit_normal_derivative(-average_value, q); + phi_outer.submit_value(-average_valgrad, q); + } + phi_outer.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + local_diagonal_vector[i] = phi_outer.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi_outer.begin_dof_values()[i] = local_diagonal_vector[i]; + phi_outer.distribute_local_to_global(dst); + } + } + + void + local_diagonal_boundary( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &face_range) const + { + FEFaceEvaluation phi(data); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + phi.reinit(face); + + VectorizedArray sigmaF = + std::abs((phi.normal_vector(0) * phi.inverse_jacobian(0))[dim - 1]) * + (number)(std::max(1, fe_degree) * (fe_degree + 1.0)) * 2.; + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = phi.get_value(q); + VectorizedArray average_valgrad = + -phi.get_normal_derivative(q); + average_valgrad += average_value * sigmaF * 2.0; + phi.submit_normal_derivative(-average_value, q); + phi.submit_value(average_valgrad, q); + } + + phi.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + int fe_degree; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MATRIX &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-7, false, false); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MATRIX *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const unsigned int n_q_points_1d) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(n_q_points_1d); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, dof, n_q_points_1d); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].initialize(mapping, dof, n_q_points_1d, level); + + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 20.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer; + mg_transfer.build(dof, partitioners); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + ReductionControl control(30, 1e-20, 1e-10); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test(const unsigned int fe_degree) +{ + for (unsigned int i = 5; i < 9 - fe_degree; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + dealii::Triangulation::none, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + // set boundary ids on boundaries to the number of the face + for (unsigned int face = 2; face < GeometryInfo::faces_per_cell; + ++face) + tria.begin()->face(face)->set_all_boundary_ids(face); + + std::vector< + GridTools::PeriodicFacePair::cell_iterator>> + periodic_faces; + for (unsigned int d = 1; d < dim; ++d) + GridTools::collect_periodic_faces( + tria, 2 * d, 2 * d + 1, d, periodic_faces); + tria.add_periodicity(periodic_faces); + + tria.refine_global(i - dim); + + FE_DGQ fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof, fe_degree + 1); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + + { + deallog.push("2d"); + test<2>(1); + test<2>(2); + deallog.pop(); + deallog.push("3d"); + test<3>(1); + test<3>(2); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=1.output b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=1.output new file mode 100644 index 0000000000..4624baa08f --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=1.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 7 value 1.80729e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 8 value 8.73511e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 8 value 4.57619e-10 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 7 value 1.07430e-09 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 8 value 1.87005e-10 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 4 value 7.99677e-17 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.27740e-11 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 7 value 2.41331e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 8 value 1.14978e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 9 value 1.16347e-09 diff --git a/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..7630f429b1 --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=3.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 7 value 1.80729e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 8 value 8.73511e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 8 value 4.57619e-10 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 7 value 1.07430e-09 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 8 value 1.87005e-10 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 4 value 9.91449e-17 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.27740e-11 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 7 value 2.41331e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 8 value 1.14978e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 9 value 1.16347e-09 diff --git a/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=5.output b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=5.output new file mode 100644 index 0000000000..e2e33e652a --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_periodic.with_lapack=true.with_trilinos=true.with_p4est=true.mpirun=5.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 7 value 1.80729e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 8 value 8.73511e-11 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 8 value 4.57619e-10 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 7 value 1.07430e-09 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 8 value 1.87005e-10 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 4 value 7.23452e-17 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.27740e-11 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 7 value 2.41331e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 8 value 1.14978e-09 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 9 value 1.16347e-09 diff --git a/tests/multigrid-global-coarsening/multigrid_dg_sip_01.cc b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.cc new file mode 100644 index 0000000000..eabd921d71 --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.cc @@ -0,0 +1,629 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// test of a multigrid solver including face integration (DG case, symmetric +// interior penalty + Nitsche). + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler &dof_handler, + const unsigned int n_q_points_1d, + const unsigned int level = numbers::invalid_unsigned_int) + { + fe_degree = dof_handler.get_fe().degree; + + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + addit_data.mapping_update_flags_inner_faces = + (update_gradients | update_JxW_values); + addit_data.mapping_update_flags_boundary_faces = + (update_gradients | update_JxW_values); + AffineConstraints constraints; + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + if (!src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner)) + { + LinearAlgebra::distributed::Vector src_copy; + src_copy.reinit(data.get_dof_info().vector_partitioner); + src_copy = src; + const_cast &>(src).swap( + src_copy); + } + if (!dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner)) + { + LinearAlgebra::distributed::Vector dst_copy; + dst_copy.reinit(data.get_dof_info().vector_partitioner); + dst_copy = dst; + dst.swap(dst_copy); + } + dst.zero_out_ghost_values(); + data.loop(&LaplaceOperator::local_apply, + &LaplaceOperator::local_apply_face, + &LaplaceOperator::local_apply_boundary, + this, + dst, + src); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + data.initialize_dof_vector(vector); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + return inverse_diagonal_entries; + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + local_apply_face( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + FEFaceEvaluation fe_eval_neighbor(data, false); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval_neighbor.reinit(face); + + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval_neighbor.read_dof_values(src); + fe_eval_neighbor.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + VectorizedArray sigmaF = + (std::abs((fe_eval.normal_vector(0) * + fe_eval.inverse_jacobian(0))[dim - 1]) + + std::abs((fe_eval.normal_vector(0) * + fe_eval_neighbor.inverse_jacobian(0))[dim - 1])) * + (number)(std::max(fe_degree, 1) * (fe_degree + 1.0)); + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = + (fe_eval.get_value(q) - fe_eval_neighbor.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + fe_eval.get_normal_derivative(q) + + fe_eval_neighbor.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval_neighbor.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + fe_eval_neighbor.submit_value(-average_valgrad, q); + } + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + fe_eval_neighbor.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + fe_eval_neighbor.distribute_local_to_global(dst); + } + } + + void + local_apply_boundary( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + VectorizedArray sigmaF = + std::abs( + (fe_eval.normal_vector(0) * fe_eval.inverse_jacobian(0))[dim - 1]) * + number(std::max(fe_degree, 1) * (fe_degree + 1.0)) * 2.0; + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = fe_eval.get_value(q); + VectorizedArray average_valgrad = + -fe_eval.get_normal_derivative(q); + average_valgrad += average_value * sigmaF * 2.0; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + } + + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.loop(&LaplaceOperator::local_diagonal_cell, + &LaplaceOperator::local_diagonal_face, + &LaplaceOperator::local_diagonal_boundary, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + void + local_diagonal_face( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &face_range) const + { + FEFaceEvaluation phi(data, true); + FEFaceEvaluation phi_outer(data, false); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + phi.reinit(face); + phi_outer.reinit(face); + + VectorizedArray sigmaF = + (std::abs((phi.normal_vector(0) * phi.inverse_jacobian(0))[dim - 1]) + + std::abs( + (phi.normal_vector(0) * phi_outer.inverse_jacobian(0))[dim - 1])) * + (number)(std::max(fe_degree, 1) * (fe_degree + 1.0)); + + // Compute phi part + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi_outer.begin_dof_values()[j] = VectorizedArray(); + phi_outer.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = + (phi.get_value(q) - phi_outer.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + phi.get_normal_derivative(q) + + phi_outer.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + phi.submit_normal_derivative(-average_value, q); + phi.submit_value(average_valgrad, q); + } + phi.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + + // Compute phi_outer part + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi_outer.begin_dof_values()[j] = VectorizedArray(); + phi_outer.begin_dof_values()[i] = 1.; + phi_outer.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = + (phi.get_value(q) - phi_outer.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + phi.get_normal_derivative(q) + + phi_outer.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + phi_outer.submit_normal_derivative(-average_value, q); + phi_outer.submit_value(-average_valgrad, q); + } + phi_outer.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + local_diagonal_vector[i] = phi_outer.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi_outer.begin_dof_values()[i] = local_diagonal_vector[i]; + phi_outer.distribute_local_to_global(dst); + } + } + + void + local_diagonal_boundary( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &face_range) const + { + FEFaceEvaluation phi(data); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + phi.reinit(face); + + VectorizedArray sigmaF = + std::abs((phi.normal_vector(0) * phi.inverse_jacobian(0))[dim - 1]) * + number(std::max(fe_degree, 1) * (fe_degree + 1.0)) * 2.0; + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + VectorizedArray average_value = phi.get_value(q); + VectorizedArray average_valgrad = + -phi.get_normal_derivative(q); + average_valgrad += average_value * sigmaF * 2.0; + phi.submit_normal_derivative(-average_value, q); + phi.submit_value(average_valgrad, q); + } + + phi.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + int fe_degree; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MATRIX &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10, false, false); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MATRIX *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const unsigned n_q_points_1d) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(n_q_points_1d); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, dof, n_q_points_1d); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, n_q_points_1d, level); + } + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 20.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MGTransferMF mg_transfer(mg_constrained_dofs); + + mg_transfer.build(dof, [&](const unsigned int level, auto &vec) { + mg_matrices[level].initialize_dof_vector(vec); + }); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test(const unsigned int fe_degree) +{ + for (unsigned int i = 5; i < 9 - fe_degree; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + dealii::Triangulation::none, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_DGQ fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof, fe_degree + 1); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + + { + deallog.push("2d"); + test<2>(1); + test<2>(2); + deallog.pop(); + deallog.push("3d"); + test<3>(1); + test<3>(2); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=1.output b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=1.output new file mode 100644 index 0000000000..3755b9b07c --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=1.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 5 value 3.60502e-07 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 5 value 2.14074e-06 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 5 value 5.99637e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 5 value 1.81901e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 6 value 1.94976e-07 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 6 value 7.43327e-08 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.28298e-06 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 6 value 5.09300e-06 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 6 value 1.73456e-07 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 7 value 5.35539e-07 diff --git a/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=5.output b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=5.output new file mode 100644 index 0000000000..3755b9b07c --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_sip_01.with_lapack=true.with_p4est=true.mpirun=5.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 5 value 3.60502e-07 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 5 value 2.14074e-06 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 5 value 5.99637e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 5 value 1.81901e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 6 value 1.94976e-07 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 6 value 7.43327e-08 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.28298e-06 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 6 value 5.09300e-06 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 6 value 1.73456e-07 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 7 value 5.35539e-07 diff --git a/tests/multigrid-global-coarsening/multigrid_dg_sip_02.cc b/tests/multigrid-global-coarsening/multigrid_dg_sip_02.cc new file mode 100644 index 0000000000..ff8c64f918 --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_sip_02.cc @@ -0,0 +1,547 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// test of a multigrid solver including face integration (DG case, symmetric +// interior penalty + Nitsche). As opposed to multigrid_dg_sip_01, this test +// computes the diagonal using the alternative reinit(cell_index, face_number) + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler &dof_handler, + const unsigned int n_q_points_1d, + const unsigned int level = numbers::invalid_unsigned_int) + { + fe_degree = dof_handler.get_fe().degree; + + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + addit_data.mapping_update_flags_inner_faces = + update_JxW_values | update_normal_vectors | update_jacobians; + addit_data.mapping_update_flags_boundary_faces = + update_JxW_values | update_normal_vectors | update_jacobians; + addit_data.mapping_update_flags_faces_by_cells = + update_JxW_values | update_normal_vectors | update_jacobians; + AffineConstraints constraints; + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + if (!src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner)) + { + LinearAlgebra::distributed::Vector src_copy; + src_copy.reinit(data.get_dof_info().vector_partitioner); + src_copy = src; + const_cast &>(src).swap( + src_copy); + } + if (!dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner)) + { + LinearAlgebra::distributed::Vector dst_copy; + dst_copy.reinit(data.get_dof_info().vector_partitioner); + dst_copy = dst; + dst.swap(dst_copy); + } + dst.zero_out_ghost_values(); + data.loop(&LaplaceOperator::local_apply, + &LaplaceOperator::local_apply_face, + &LaplaceOperator::local_apply_boundary, + this, + dst, + src); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + data.initialize_dof_vector(vector); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + local_apply_face( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + FEFaceEvaluation fe_eval_neighbor(data, false); + + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval_neighbor.reinit(face); + + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval_neighbor.read_dof_values(src); + fe_eval_neighbor.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + VectorizedArray sigmaF = + (std::abs((fe_eval.normal_vector(0) * + fe_eval.inverse_jacobian(0))[dim - 1]) + + std::abs((fe_eval.normal_vector(0) * + fe_eval_neighbor.inverse_jacobian(0))[dim - 1])) * + (number)(std::max(fe_degree, 1) * (fe_degree + 1.0)); + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = + (fe_eval.get_value(q) - fe_eval_neighbor.get_value(q)) * 0.5; + VectorizedArray average_valgrad = + fe_eval.get_normal_derivative(q) + + fe_eval_neighbor.get_normal_derivative(q); + average_valgrad = + average_value * 2. * sigmaF - average_valgrad * 0.5; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval_neighbor.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + fe_eval_neighbor.submit_value(-average_valgrad, q); + } + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + fe_eval_neighbor.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + fe_eval_neighbor.distribute_local_to_global(dst); + } + } + + void + local_apply_boundary( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & face_range) const + { + FEFaceEvaluation fe_eval(data, true); + for (unsigned int face = face_range.first; face < face_range.second; ++face) + { + fe_eval.reinit(face); + fe_eval.read_dof_values(src); + fe_eval.evaluate(EvaluationFlags::values | EvaluationFlags::gradients); + VectorizedArray sigmaF = + std::abs( + (fe_eval.normal_vector(0) * fe_eval.inverse_jacobian(0))[dim - 1]) * + (number)(std::max(1, fe_degree) * (fe_degree + 1.0)) * 2.; + + for (unsigned int q = 0; q < fe_eval.n_q_points; ++q) + { + VectorizedArray average_value = fe_eval.get_value(q); + VectorizedArray average_valgrad = + -fe_eval.get_normal_derivative(q); + average_valgrad += average_value * sigmaF * 2.0; + fe_eval.submit_normal_derivative(-average_value, q); + fe_eval.submit_value(average_valgrad, q); + } + + fe_eval.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + fe_eval.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + FEFaceEvaluation phif(data); + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (const unsigned int face : GeometryInfo::face_indices()) + { + phif.reinit(cell, face); + VectorizedArray sigmaF = + std::abs( + (phif.normal_vector(0) * phif.inverse_jacobian(0))[dim - 1]) * + (number)(std::max(1, fe_degree) * (fe_degree + 1.0)) * 2.; + std::array::size()> + boundary_ids = data.get_faces_by_cells_boundary_id(cell, face); + VectorizedArray factor_boundary; + for (unsigned int v = 0; v < VectorizedArray::size(); ++v) + // interior face + if (boundary_ids[v] == numbers::invalid_boundary_id) + factor_boundary[v] = 0.5; + // Dirichlet boundary + else + factor_boundary[v] = 1.0; + for (unsigned int i = 0; i < phif.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phif.dofs_per_cell; ++j) + phif.begin_dof_values()[j] = VectorizedArray(); + phif.begin_dof_values()[i] = 1.; + phif.evaluate(EvaluationFlags::values | + EvaluationFlags::gradients); + for (unsigned int q = 0; q < phif.n_q_points; ++q) + { + VectorizedArray average_value = + phif.get_value(q) * factor_boundary; + VectorizedArray average_valgrad = + phif.get_normal_derivative(q) * factor_boundary; + average_valgrad = + average_value * 2. * sigmaF - average_valgrad; + phif.submit_normal_derivative(-average_value, q); + phif.submit_value(average_valgrad, q); + } + phif.integrate(EvaluationFlags::values | + EvaluationFlags::gradients); + local_diagonal_vector[i] += phif.begin_dof_values()[i]; + } + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + int fe_degree; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MATRIX &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10, false, false); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MATRIX *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const unsigned int n_q_points_1d) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(n_q_points_1d); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, dof, n_q_points_1d); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, n_q_points_1d, level); + } + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 20.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test(const unsigned int fe_degree) +{ + for (unsigned int i = 5; i < 9 - fe_degree; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + dealii::Triangulation::none, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_DGQ fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof, fe_degree + 1); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + deallog.push("2d"); + test<2>(1); + test<2>(2); + deallog.pop(); + deallog.push("3d"); + test<3>(1); + test<3>(2); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/multigrid_dg_sip_02.with_lapack=true.with_p4est=true.mpirun=5.output b/tests/multigrid-global-coarsening/multigrid_dg_sip_02.with_lapack=true.with_p4est=true.mpirun=5.output new file mode 100644 index 0000000000..3755b9b07c --- /dev/null +++ b/tests/multigrid-global-coarsening/multigrid_dg_sip_02.with_lapack=true.with_p4est=true.mpirun=5.output @@ -0,0 +1,41 @@ + +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 256 +DEAL:2d:cg::Starting value 16.0000 +DEAL:2d:cg::Convergence step 5 value 3.60502e-07 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 1024 +DEAL:2d:cg::Starting value 32.0000 +DEAL:2d:cg::Convergence step 5 value 2.14074e-06 +DEAL:2d::Testing FE_DGQ<2>(1) +DEAL:2d::Number of degrees of freedom: 4096 +DEAL:2d:cg::Starting value 64.0000 +DEAL:2d:cg::Convergence step 5 value 5.99637e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 576 +DEAL:2d:cg::Starting value 24.0000 +DEAL:2d:cg::Convergence step 5 value 1.81901e-06 +DEAL:2d::Testing FE_DGQ<2>(2) +DEAL:2d::Number of degrees of freedom: 2304 +DEAL:2d:cg::Starting value 48.0000 +DEAL:2d:cg::Convergence step 6 value 1.94976e-07 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 512 +DEAL:3d:cg::Starting value 22.6274 +DEAL:3d:cg::Convergence step 6 value 7.43327e-08 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 4096 +DEAL:3d:cg::Starting value 64.0000 +DEAL:3d:cg::Convergence step 6 value 2.28298e-06 +DEAL:3d::Testing FE_DGQ<3>(1) +DEAL:3d::Number of degrees of freedom: 32768 +DEAL:3d:cg::Starting value 181.019 +DEAL:3d:cg::Convergence step 6 value 5.09300e-06 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 1728 +DEAL:3d:cg::Starting value 41.5692 +DEAL:3d:cg::Convergence step 6 value 1.73456e-07 +DEAL:3d::Testing FE_DGQ<3>(2) +DEAL:3d::Number of degrees of freedom: 13824 +DEAL:3d:cg::Starting value 117.576 +DEAL:3d:cg::Convergence step 7 value 5.35539e-07 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid.cc b/tests/multigrid-global-coarsening/parallel_multigrid.cc new file mode 100644 index 0000000000..5e5212d8cd --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid.cc @@ -0,0 +1,452 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// test running a multigrid solver on continuous FE_Q finite elements with +// MatrixFree data structures (otherwise similar to step-37) + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class LaplaceOperator : public Subscriptor +{ +public: + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const std::set &dirichlet_boundaries, + const unsigned int level = numbers::invalid_unsigned_int) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.mg_level = level; + + // extract the constraints due to Dirichlet boundary conditions + AffineConstraints constraints; + Functions::ZeroFunction zero; + std::map *> functions; + for (std::set::const_iterator it = + dirichlet_boundaries.begin(); + it != dirichlet_boundaries.end(); + ++it) + functions[*it] = &zero; + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + const std::set dirichlet_boundaries = {0}; + fine_matrix.initialize(mapping, dof, dirichlet_boundaries); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level); + } + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer; + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner.reset( + new DiagonalMatrix>()); + smoother_data[level].preconditioner->get_vector() = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); +} + + + +template +void +test() +{ + for (unsigned int i = 5; i < 8; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + test<2, 2>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + test<3, 2>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..3d043ad95d --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,145 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 81 +DEAL:2d:cg::Starting value 9.000 +DEAL:2d:cg:cg::Starting value 0.02203 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 0.0001585 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 8.884e-07 +DEAL:2d:cg:cg::Convergence step 1 value 9.863e-23 +DEAL:2d:cg:cg::Starting value 3.123e-09 +DEAL:2d:cg:cg::Convergence step 1 value 3.468e-25 +DEAL:2d:cg::Convergence step 4 value 2.071e-08 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 0.005310 +DEAL:2d:cg:cg::Convergence step 1 value 5.895e-19 +DEAL:2d:cg:cg::Starting value 5.163e-06 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 2.182e-08 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 9.610e-10 +DEAL:2d:cg:cg::Convergence step 1 value 2.134e-25 +DEAL:2d:cg::Convergence step 4 value 2.778e-08 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 0.008242 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 2.754e-06 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 9.820e-09 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 8.188e-12 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg::Convergence step 4 value 8.029e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 3.849 +DEAL:2d:cg:cg::Convergence step 2 value 1.388e-15 +DEAL:2d:cg:cg::Starting value 0.0007035 +DEAL:2d:cg:cg::Convergence step 2 value 7.914e-19 +DEAL:2d:cg:cg::Starting value 4.286e-06 +DEAL:2d:cg:cg::Convergence step 2 value 1.471e-21 +DEAL:2d:cg:cg::Starting value 2.909e-08 +DEAL:2d:cg:cg::Convergence step 2 value 1.896e-23 +DEAL:2d:cg::Convergence step 4 value 3.931e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 14.69 +DEAL:2d:cg:cg::Convergence step 2 value 4.242e-15 +DEAL:2d:cg:cg::Starting value 0.002915 +DEAL:2d:cg:cg::Convergence step 2 value 1.213e-18 +DEAL:2d:cg:cg::Starting value 3.439e-06 +DEAL:2d:cg:cg::Convergence step 2 value 1.583e-21 +DEAL:2d:cg:cg::Starting value 1.212e-08 +DEAL:2d:cg:cg::Convergence step 2 value 1.131e-24 +DEAL:2d:cg::Convergence step 4 value 8.121e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 4225 +DEAL:2d:cg::Starting value 65.00 +DEAL:2d:cg:cg::Starting value 58.09 +DEAL:2d:cg:cg::Convergence step 2 value 4.467e-14 +DEAL:2d:cg:cg::Starting value 0.01056 +DEAL:2d:cg:cg::Convergence step 2 value 9.358e-19 +DEAL:2d:cg:cg::Starting value 2.588e-05 +DEAL:2d:cg:cg::Convergence step 2 value 3.405e-20 +DEAL:2d:cg:cg::Starting value 6.672e-08 +DEAL:2d:cg:cg::Convergence step 2 value 5.007e-23 +DEAL:2d:cg::Convergence step 4 value 1.695e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 125 +DEAL:3d:cg::Starting value 11.18 +DEAL:3d:cg:cg::Starting value 0.5164 +DEAL:3d:cg:cg::Convergence step 1 value 1.147e-16 +DEAL:3d:cg:cg::Starting value 0.02357 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 5.322e-05 +DEAL:3d:cg:cg::Convergence step 1 value 1.182e-20 +DEAL:3d:cg:cg::Starting value 1.537e-07 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg::Convergence step 4 value 3.460e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 0.1824 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 0.004902 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 5.629e-06 +DEAL:3d:cg:cg::Convergence step 1 value 1.250e-21 +DEAL:3d:cg:cg::Starting value 3.386e-10 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg::Convergence step 4 value 1.074e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 0.1633 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 0.0001064 +DEAL:3d:cg:cg::Convergence step 1 value 1.181e-20 +DEAL:3d:cg:cg::Starting value 1.367e-06 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 1.607e-08 +DEAL:3d:cg:cg::Convergence step 1 value 3.568e-24 +DEAL:3d:cg::Convergence step 4 value 5.067e-08 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 1.696 +DEAL:3d:cg:cg::Convergence step 2 value 4.279e-16 +DEAL:3d:cg:cg::Starting value 0.1039 +DEAL:3d:cg:cg::Convergence step 2 value 1.250e-17 +DEAL:3d:cg:cg::Starting value 0.0001780 +DEAL:3d:cg:cg::Convergence step 2 value 1.054e-20 +DEAL:3d:cg:cg::Starting value 5.292e-06 +DEAL:3d:cg:cg::Convergence step 2 value 1.622e-22 +DEAL:3d:cg::Convergence step 4 value 2.351e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 2.288 +DEAL:3d:cg:cg::Convergence step 2 value 1.482e-15 +DEAL:3d:cg:cg::Starting value 0.04493 +DEAL:3d:cg:cg::Convergence step 2 value 2.411e-18 +DEAL:3d:cg:cg::Starting value 0.0007205 +DEAL:3d:cg:cg::Convergence step 2 value 9.281e-20 +DEAL:3d:cg:cg::Starting value 2.913e-06 +DEAL:3d:cg:cg::Convergence step 2 value 5.846e-23 +DEAL:3d:cg::Convergence step 4 value 4.578e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 35937 +DEAL:3d:cg::Starting value 189.6 +DEAL:3d:cg:cg::Starting value 17.19 +DEAL:3d:cg:cg::Convergence step 2 value 1.912e-14 +DEAL:3d:cg:cg::Starting value 0.01678 +DEAL:3d:cg:cg::Convergence step 2 value 4.151e-18 +DEAL:3d:cg:cg::Starting value 0.001099 +DEAL:3d:cg:cg::Convergence step 2 value 2.529e-19 +DEAL:3d:cg:cg::Starting value 9.998e-07 +DEAL:3d:cg:cg::Convergence step 2 value 5.098e-22 +DEAL:3d:cg::Convergence step 4 value 1.784e-05 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output b/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output new file mode 100644 index 0000000000..c7a1fdda48 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output @@ -0,0 +1,145 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 81 +DEAL:2d:cg::Starting value 9.000 +DEAL:2d:cg:cg::Starting value 0.02203 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 0.0001585 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 8.884e-07 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 3.123e-09 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg::Convergence step 4 value 2.071e-08 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 0.005310 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 5.163e-06 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 2.182e-08 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 9.610e-10 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg::Convergence step 4 value 2.778e-08 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 0.008242 +DEAL:2d:cg:cg::Convergence step 1 value 1.830e-18 +DEAL:2d:cg:cg::Starting value 2.754e-06 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 9.820e-09 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg:cg::Starting value 8.188e-12 +DEAL:2d:cg:cg::Convergence step 1 value 0.000 +DEAL:2d:cg::Convergence step 4 value 8.029e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 3.849 +DEAL:2d:cg:cg::Convergence step 2 value 1.863e-15 +DEAL:2d:cg:cg::Starting value 0.0007035 +DEAL:2d:cg:cg::Convergence step 2 value 5.372e-19 +DEAL:2d:cg:cg::Starting value 4.286e-06 +DEAL:2d:cg:cg::Convergence step 2 value 4.258e-21 +DEAL:2d:cg:cg::Starting value 2.909e-08 +DEAL:2d:cg:cg::Convergence step 2 value 1.177e-24 +DEAL:2d:cg::Convergence step 4 value 3.931e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 14.69 +DEAL:2d:cg:cg::Convergence step 2 value 1.771e-14 +DEAL:2d:cg:cg::Starting value 0.002915 +DEAL:2d:cg:cg::Convergence step 2 value 2.794e-18 +DEAL:2d:cg:cg::Starting value 3.439e-06 +DEAL:2d:cg:cg::Convergence step 2 value 1.470e-21 +DEAL:2d:cg:cg::Starting value 1.212e-08 +DEAL:2d:cg:cg::Convergence step 2 value 4.310e-24 +DEAL:2d:cg::Convergence step 4 value 8.121e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 4225 +DEAL:2d:cg::Starting value 65.00 +DEAL:2d:cg:cg::Starting value 58.09 +DEAL:2d:cg:cg::Convergence step 2 value 7.517e-15 +DEAL:2d:cg:cg::Starting value 0.01056 +DEAL:2d:cg:cg::Convergence step 2 value 3.556e-18 +DEAL:2d:cg:cg::Starting value 2.588e-05 +DEAL:2d:cg:cg::Convergence step 2 value 1.590e-20 +DEAL:2d:cg:cg::Starting value 6.672e-08 +DEAL:2d:cg:cg::Convergence step 2 value 3.475e-23 +DEAL:2d:cg::Convergence step 4 value 1.695e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 125 +DEAL:3d:cg::Starting value 11.18 +DEAL:3d:cg:cg::Starting value 0.5164 +DEAL:3d:cg:cg::Convergence step 1 value 1.147e-16 +DEAL:3d:cg:cg::Starting value 0.02357 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 5.322e-05 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 1.537e-07 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg::Convergence step 4 value 3.460e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 0.1824 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 0.004902 +DEAL:3d:cg:cg::Convergence step 1 value 5.443e-19 +DEAL:3d:cg:cg::Starting value 5.629e-06 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 3.386e-10 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg::Convergence step 4 value 1.074e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 0.1633 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 0.0001064 +DEAL:3d:cg:cg::Convergence step 1 value 2.362e-20 +DEAL:3d:cg:cg::Starting value 1.367e-06 +DEAL:3d:cg:cg::Convergence step 1 value 0.000 +DEAL:3d:cg:cg::Starting value 1.607e-08 +DEAL:3d:cg:cg::Convergence step 1 value 3.568e-24 +DEAL:3d:cg::Convergence step 4 value 5.067e-08 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 1.696 +DEAL:3d:cg:cg::Convergence step 2 value 1.987e-16 +DEAL:3d:cg:cg::Starting value 0.1039 +DEAL:3d:cg:cg::Convergence step 2 value 3.578e-18 +DEAL:3d:cg:cg::Starting value 0.0001780 +DEAL:3d:cg:cg::Convergence step 2 value 1.311e-20 +DEAL:3d:cg:cg::Starting value 5.292e-06 +DEAL:3d:cg:cg::Convergence step 2 value 5.646e-22 +DEAL:3d:cg::Convergence step 4 value 2.351e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 2.288 +DEAL:3d:cg:cg::Convergence step 2 value 6.751e-17 +DEAL:3d:cg:cg::Starting value 0.04493 +DEAL:3d:cg:cg::Convergence step 2 value 1.105e-17 +DEAL:3d:cg:cg::Starting value 0.0007205 +DEAL:3d:cg:cg::Convergence step 2 value 1.525e-20 +DEAL:3d:cg:cg::Starting value 2.913e-06 +DEAL:3d:cg:cg::Convergence step 2 value 7.041e-22 +DEAL:3d:cg::Convergence step 4 value 4.578e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 35937 +DEAL:3d:cg::Starting value 189.6 +DEAL:3d:cg:cg::Starting value 17.19 +DEAL:3d:cg:cg::Convergence step 2 value 5.350e-15 +DEAL:3d:cg:cg::Starting value 0.01678 +DEAL:3d:cg:cg::Convergence step 2 value 3.272e-18 +DEAL:3d:cg:cg::Starting value 0.001099 +DEAL:3d:cg:cg::Convergence step 2 value 2.132e-20 +DEAL:3d:cg:cg::Starting value 9.998e-07 +DEAL:3d:cg:cg::Convergence step 2 value 3.927e-22 +DEAL:3d:cg::Convergence step 4 value 1.784e-05 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_02.cc b/tests/multigrid-global-coarsening/parallel_multigrid_02.cc new file mode 100644 index 0000000000..6e1bdfe547 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_02.cc @@ -0,0 +1,291 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// similar to parallel_multigrid.cc but using +// MatrixFreeOperators::LaplaceOperator class + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + +using namespace dealii::MatrixFreeOperators; + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + LaplaceOperator> + fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + for (unsigned int i = 5; i < 7; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + test<2, 2>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + test<3, 2>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..591de5bc49 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,78 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 81 +DEAL:2d:cg::Starting value 9.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg::Convergence step 3 value 6.753e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg::Convergence step 4 value 2.625e-09 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 3.765 +DEAL:2d:cg:cg::Convergence step 1 value 2.359e-16 +DEAL:2d:cg:cg::Starting value 0.0005314 +DEAL:2d:cg:cg::Convergence step 1 value 6.437e-20 +DEAL:2d:cg:cg::Starting value 3.806e-06 +DEAL:2d:cg:cg::Convergence step 1 value 9.264e-23 +DEAL:2d:cg:cg::Starting value 1.628e-08 +DEAL:2d:cg:cg::Convergence step 1 value 1.034e-24 +DEAL:2d:cg::Convergence step 4 value 1.712e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 14.37 +DEAL:2d:cg:cg::Convergence step 1 value 8.327e-16 +DEAL:2d:cg:cg::Starting value 0.002280 +DEAL:2d:cg:cg::Convergence step 1 value 2.711e-20 +DEAL:2d:cg:cg::Starting value 6.550e-06 +DEAL:2d:cg:cg::Convergence step 1 value 1.570e-22 +DEAL:2d:cg:cg::Starting value 5.084e-08 +DEAL:2d:cg:cg::Convergence step 1 value 6.035e-24 +DEAL:2d:cg::Convergence step 4 value 4.315e-08 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 125 +DEAL:3d:cg::Starting value 11.18 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg::Convergence step 3 value 4.383e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg::Convergence step 3 value 1.025e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 0.3870 +DEAL:3d:cg:cg::Convergence step 1 value 4.005e-17 +DEAL:3d:cg:cg::Starting value 0.0005996 +DEAL:3d:cg:cg::Convergence step 1 value 2.717e-20 +DEAL:3d:cg:cg::Starting value 3.381e-07 +DEAL:3d:cg:cg::Convergence step 1 value 1.182e-23 +DEAL:3d:cg:cg::Starting value 5.601e-10 +DEAL:3d:cg:cg::Convergence step 1 value 5.638e-26 +DEAL:3d:cg::Convergence step 4 value 5.998e-09 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 2.248 +DEAL:3d:cg:cg::Convergence step 1 value 8.552e-17 +DEAL:3d:cg:cg::Starting value 0.0007474 +DEAL:3d:cg:cg::Convergence step 1 value 1.057e-19 +DEAL:3d:cg:cg::Starting value 3.260e-06 +DEAL:3d:cg:cg::Convergence step 1 value 4.268e-23 +DEAL:3d:cg:cg::Starting value 1.168e-08 +DEAL:3d:cg:cg::Convergence step 1 value 4.233e-25 +DEAL:3d:cg::Convergence step 4 value 5.811e-08 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output b/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output new file mode 100644 index 0000000000..f77b7fe181 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_02.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output @@ -0,0 +1,78 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 81 +DEAL:2d:cg::Starting value 9.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg::Convergence step 3 value 6.753e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg:cg::Convergence step 0 value 0.000 +DEAL:2d:cg::Convergence step 4 value 2.625e-09 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 289 +DEAL:2d:cg::Starting value 17.00 +DEAL:2d:cg:cg::Starting value 3.765 +DEAL:2d:cg:cg::Convergence step 1 value 2.220e-16 +DEAL:2d:cg:cg::Starting value 0.0005314 +DEAL:2d:cg:cg::Convergence step 1 value 2.282e-20 +DEAL:2d:cg:cg::Starting value 3.806e-06 +DEAL:2d:cg:cg::Convergence step 1 value 2.569e-22 +DEAL:2d:cg:cg::Starting value 1.628e-08 +DEAL:2d:cg:cg::Convergence step 1 value 9.306e-25 +DEAL:2d:cg::Convergence step 4 value 1.712e-08 +DEAL:2d::Testing FE_Q<2>(2) +DEAL:2d::Number of degrees of freedom: 1089 +DEAL:2d:cg::Starting value 33.00 +DEAL:2d:cg:cg::Starting value 14.37 +DEAL:2d:cg:cg::Convergence step 1 value 9.437e-16 +DEAL:2d:cg:cg::Starting value 0.002280 +DEAL:2d:cg:cg::Convergence step 1 value 2.168e-19 +DEAL:2d:cg:cg::Starting value 6.550e-06 +DEAL:2d:cg:cg::Convergence step 1 value 5.823e-22 +DEAL:2d:cg:cg::Starting value 5.084e-08 +DEAL:2d:cg:cg::Convergence step 1 value 4.136e-25 +DEAL:2d:cg::Convergence step 4 value 4.315e-08 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 125 +DEAL:3d:cg::Starting value 11.18 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg::Convergence step 3 value 4.383e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg:cg::Convergence step 0 value 0.000 +DEAL:3d:cg::Convergence step 3 value 1.025e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 729 +DEAL:3d:cg::Starting value 27.00 +DEAL:3d:cg:cg::Starting value 0.3870 +DEAL:3d:cg:cg::Convergence step 1 value 3.850e-18 +DEAL:3d:cg:cg::Starting value 0.0005996 +DEAL:3d:cg:cg::Convergence step 1 value 1.355e-20 +DEAL:3d:cg:cg::Starting value 3.381e-07 +DEAL:3d:cg:cg::Convergence step 1 value 8.779e-24 +DEAL:3d:cg:cg::Starting value 5.601e-10 +DEAL:3d:cg:cg::Convergence step 1 value 4.426e-26 +DEAL:3d:cg::Convergence step 4 value 5.998e-09 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 4913 +DEAL:3d:cg::Starting value 70.09 +DEAL:3d:cg:cg::Starting value 2.248 +DEAL:3d:cg:cg::Convergence step 1 value 2.463e-16 +DEAL:3d:cg:cg::Starting value 0.0007474 +DEAL:3d:cg:cg::Convergence step 1 value 1.924e-20 +DEAL:3d:cg:cg::Starting value 3.260e-06 +DEAL:3d:cg:cg::Convergence step 1 value 2.263e-22 +DEAL:3d:cg:cg::Starting value 1.168e-08 +DEAL:3d:cg:cg::Convergence step 1 value 1.617e-26 +DEAL:3d:cg::Convergence step 4 value 5.811e-08 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.cc new file mode 100644 index 0000000000..8071a1089c --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.cc @@ -0,0 +1,645 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// similar as parallel_multigrid but using adaptive meshes with hanging nodes +// (doing local smoothing) + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class LaplaceOperator : public Subscriptor +{ +public: + LaplaceOperator(){}; + + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const MGConstrainedDoFs &mg_constrained_dofs, + const std::map *> + & dirichlet_boundary, + const unsigned int level = numbers::invalid_unsigned_int) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + AffineConstraints constraints; + if (level == numbers::invalid_unsigned_int) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, relevant_dofs); + constraints.reinit(relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + VectorTools::interpolate_boundary_values(dof_handler, + dirichlet_boundary, + constraints); + } + else + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof_handler, + level, + relevant_dofs); + constraints.reinit(relevant_dofs); + constraints.add_lines(mg_constrained_dofs.get_boundary_indices(level)); + + const std::vector interface_indices = + mg_constrained_dofs.get_refinement_edge_indices(level) + .get_index_vector(); + edge_constrained_indices.clear(); + edge_constrained_indices.reserve(interface_indices.size()); + edge_constrained_values.resize(interface_indices.size()); + const IndexSet &locally_owned = + dof_handler.locally_owned_mg_dofs(level); + for (unsigned int i = 0; i < interface_indices.size(); ++i) + if (locally_owned.is_element(interface_indices[i])) + edge_constrained_indices.push_back( + locally_owned.index_within_set(interface_indices[i])); + have_interface_matrices = + Utilities::MPI::max((unsigned int)edge_constrained_indices.size(), + MPI_COMM_WORLD) > 0; + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + if (level != numbers::invalid_unsigned_int) + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + edge_constrained_values[i] = std::pair( + src.local_element(edge_constrained_indices[i]), + dst.local_element(edge_constrained_indices[i])); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + + // reset edge constrained values, multiply by unit matrix and add into + // destination + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + dst.local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].second + edge_constrained_values[i].first; + } + } + + void + vmult_interface_down( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const double src_val = src.local_element(edge_constrained_indices[i]); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + edge_constrained_values[i] = std::pair( + src_val, dst.local_element(edge_constrained_indices[i])); + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + dst.local_element(c) = 0.; + ++c; + + // reset the src values + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + } + for (; c < dst.locally_owned_size(); ++c) + dst.local_element(c) = 0.; + } + + void + vmult_interface_up( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + LinearAlgebra::distributed::Vector src_cpy(src); + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + src_cpy.local_element(c) = 0.; + ++c; + } + for (; c < src_cpy.locally_owned_size(); ++c) + src_cpy.local_element(c) = 0.; + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src_cpy); + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + dst.local_element(edge_constrained_indices[i]) = 0.; + } + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + inverse_diagonal_entries.local_element(constrained_dofs[i]) = 1.; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + inverse_diagonal_entries.local_element(edge_constrained_indices[i]) = + 1.; + } + + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + std::vector edge_constrained_indices; + mutable std::vector> edge_constrained_values; + bool have_interface_matrices; +}; + + + +template +class MGInterfaceMatrix : public Subscriptor +{ +public: + void + initialize(const LAPLACEOPERATOR &laplace) + { + this->laplace = &laplace; + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + laplace->vmult_interface_down(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + laplace->vmult_interface_up(dst, src); + } + +private: + SmartPointer laplace; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + AffineConstraints hanging_node_constraints; + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + MGConstrainedDoFs mg_constrained_dofs; + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, + dof, + mg_constrained_dofs, + dirichlet_boundary, + numbers::invalid_unsigned_int); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize( + mapping, dof, mg_constrained_dofs, dirichlet_boundary, level); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner.reset( + new DiagonalMatrix>()); + smoother_data[level].preconditioner->get_vector() = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..4e020c6122 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,29 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 5 value 1.167e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 6 value 1.190e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 6 value 1.886e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 6 value 3.143e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 6 value 2.139e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 7 value 4.724e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 8 value 6.234e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output new file mode 100644 index 0000000000..cd898e3eaf --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_01.with_p4est=true.with_trilinos=true.with_lapack=true.mpirun=7.output @@ -0,0 +1,29 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 5 value 1.145e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 6 value 1.176e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 6 value 1.884e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 6 value 3.090e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 6 value 2.139e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 7 value 4.739e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 8 value 6.236e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.cc new file mode 100644 index 0000000000..3e528fb730 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.cc @@ -0,0 +1,333 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// same as parallel_multigrid_adaptive_01, but based on MGTransferMatrixFree +// and using MatrixFreeOperators::LaplaceOperator class. + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + LaplaceOperator> + fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_level_data[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + test<2, 3>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + test<3, 2>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..57d068da86 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,49 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 5 value 1.167e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 6 value 1.190e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 6 value 1.886e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 6 value 3.143e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 64.26 +DEAL:2d:cg::Convergence step 5 value 2.131e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 83.11 +DEAL:2d:cg::Convergence step 6 value 5.783e-07 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 131.0 +DEAL:2d:cg::Convergence step 6 value 6.147e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 6 value 2.139e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 7 value 4.724e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 8 value 6.234e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 82.90 +DEAL:3d:cg::Convergence step 7 value 1.038e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 152.6 +DEAL:3d:cg::Convergence step 7 value 4.360e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=7.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=7.output new file mode 100644 index 0000000000..e5e72f2302 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_02.with_p4est=true.with_lapack=true.mpirun=7.output @@ -0,0 +1,49 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 5 value 1.145e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 6 value 1.176e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 6 value 1.884e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 6 value 3.090e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 64.26 +DEAL:2d:cg::Convergence step 5 value 2.131e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 83.11 +DEAL:2d:cg::Convergence step 6 value 5.788e-07 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 131.0 +DEAL:2d:cg::Convergence step 6 value 6.134e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 6 value 2.139e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 7 value 4.739e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 8 value 6.236e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 82.90 +DEAL:3d:cg::Convergence step 7 value 1.039e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 152.6 +DEAL:3d:cg::Convergence step 7 value 4.352e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.cc new file mode 100644 index 0000000000..7aff6d4606 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.cc @@ -0,0 +1,651 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// same test as parallel_multigrid_adaptive_01 but using +// MGTransferMatrixFree rather the MGTransferPrebuilt (and manually +// implementing the full LaplaceOperator class rather than using the +// operator as in _02) + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const MGConstrainedDoFs &mg_constrained_dofs, + const std::map *> + & dirichlet_boundary, + const unsigned int level, + const bool threaded) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + if (threaded) + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::partition_partition; + else + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + AffineConstraints constraints; + if (level == numbers::invalid_unsigned_int) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, relevant_dofs); + constraints.reinit(relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + VectorTools::interpolate_boundary_values(dof_handler, + dirichlet_boundary, + constraints); + } + else + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof_handler, + level, + relevant_dofs); + constraints.reinit(relevant_dofs); + constraints.add_lines(mg_constrained_dofs.get_boundary_indices(level)); + + const std::vector interface_indices = + mg_constrained_dofs.get_refinement_edge_indices(level) + .get_index_vector(); + edge_constrained_indices.clear(); + edge_constrained_indices.reserve(interface_indices.size()); + edge_constrained_values.resize(interface_indices.size()); + const IndexSet &locally_owned = + dof_handler.locally_owned_mg_dofs(level); + for (unsigned int i = 0; i < interface_indices.size(); ++i) + if (locally_owned.is_element(interface_indices[i])) + edge_constrained_indices.push_back( + locally_owned.index_within_set(interface_indices[i])); + have_interface_matrices = + Utilities::MPI::max((unsigned int)edge_constrained_indices.size(), + MPI_COMM_WORLD) > 0; + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + if (level != numbers::invalid_unsigned_int) + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + edge_constrained_values[i] = std::pair( + src.local_element(edge_constrained_indices[i]), + dst.local_element(edge_constrained_indices[i])); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + + // reset edge constrained values, multiply by unit matrix and add into + // destination + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + dst.local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].second + edge_constrained_values[i].first; + } + } + + void + vmult_interface_down( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const double src_val = src.local_element(edge_constrained_indices[i]); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + edge_constrained_values[i] = std::pair( + src_val, dst.local_element(edge_constrained_indices[i])); + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + dst.local_element(c) = 0.; + ++c; + + // reset the src values + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + } + for (; c < dst.locally_owned_size(); ++c) + dst.local_element(c) = 0.; + } + + void + vmult_interface_up( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + LinearAlgebra::distributed::Vector src_cpy(src); + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + src_cpy.local_element(c) = 0.; + ++c; + } + for (; c < src_cpy.locally_owned_size(); ++c) + src_cpy.local_element(c) = 0.; + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src_cpy); + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + dst.local_element(edge_constrained_indices[i]) = 0.; + } + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + inverse_diagonal_entries.local_element(constrained_dofs[i]) = 1.; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + inverse_diagonal_entries.local_element(edge_constrained_indices[i]) = + 1.; + } + + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + std::vector edge_constrained_indices; + mutable std::vector> edge_constrained_values; + bool have_interface_matrices; +}; + + + +template +class MGInterfaceMatrix : public Subscriptor +{ +public: + void + initialize(const LAPLACEOPERATOR &laplace) + { + this->laplace = &laplace; + } + + void + vmult(LinearAlgebra::distributed::Vector + &dst, + const LinearAlgebra::distributed::Vector< + typename LAPLACEOPERATOR::value_type> &src) const + { + laplace->vmult_interface_down(dst, src); + } + + void + Tvmult( + LinearAlgebra::distributed::Vector + &dst, + const LinearAlgebra::distributed::Vector< + typename LAPLACEOPERATOR::value_type> &src) const + { + laplace->vmult_interface_up(dst, src); + } + +private: + SmartPointer laplace; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const bool threaded) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + AffineConstraints hanging_node_constraints; + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + MGConstrainedDoFs mg_constrained_dofs; + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, + dof, + mg_constrained_dofs, + dirichlet_boundary, + numbers::invalid_unsigned_int, + threaded); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize( + mapping, dof, mg_constrained_dofs, dirichlet_boundary, level, threaded); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner.reset( + new DiagonalMatrix>()); + smoother_data[level].preconditioner->get_vector() = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(8 - 2 * dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + deallog.push("nothread"); + do_test(dof, false); + deallog.pop(); + deallog.push("threaded"); + do_test(dof, true); + deallog.pop(); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, + argv, + testing_max_num_threads()); + + mpi_initlog(); + + test<2, 1, double>(); + test<2, 2, float>(); + test<3, 1, double>(); +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.with_p4est=true.with_lapack=true.mpirun=4.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.with_p4est=true.with_lapack=true.mpirun=4.output new file mode 100644 index 0000000000..3959556cdc --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_03.with_p4est=true.with_lapack=true.mpirun=4.output @@ -0,0 +1,81 @@ + +DEAL:nothread::Testing FE_Q<2>(1) +DEAL:nothread::Number of degrees of freedom: 507 +DEAL:nothread:cg::Starting value 21.9317 +DEAL:nothread:cg::Convergence step 5 value 1.14537e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 507 +DEAL:threaded:cg::Starting value 21.9317 +DEAL:threaded:cg::Convergence step 5 value 1.14537e-06 +DEAL:nothread::Testing FE_Q<2>(1) +DEAL:nothread::Number of degrees of freedom: 881 +DEAL:nothread:cg::Starting value 27.7669 +DEAL:nothread:cg::Convergence step 6 value 1.18996e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 881 +DEAL:threaded:cg::Starting value 27.7669 +DEAL:threaded:cg::Convergence step 6 value 1.18996e-06 +DEAL:nothread::Testing FE_Q<2>(1) +DEAL:nothread::Number of degrees of freedom: 2147 +DEAL:nothread:cg::Starting value 43.2551 +DEAL:nothread:cg::Convergence step 6 value 1.86235e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 2147 +DEAL:threaded:cg::Starting value 43.2551 +DEAL:threaded:cg::Convergence step 6 value 1.86235e-06 +DEAL:nothread::Testing FE_Q<2>(1) +DEAL:nothread::Number of degrees of freedom: 6517 +DEAL:nothread:cg::Starting value 76.9220 +DEAL:nothread:cg::Convergence step 6 value 3.14118e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 6517 +DEAL:threaded:cg::Starting value 76.9220 +DEAL:threaded:cg::Convergence step 6 value 3.14118e-06 +DEAL:nothread::Testing FE_Q<2>(2) +DEAL:nothread::Number of degrees of freedom: 1935 +DEAL:nothread:cg::Starting value 43.0929 +DEAL:nothread:cg::Convergence step 5 value 3.22499e-06 +DEAL:threaded::Testing FE_Q<2>(2) +DEAL:threaded::Number of degrees of freedom: 1935 +DEAL:threaded:cg::Starting value 43.0929 +DEAL:threaded:cg::Convergence step 5 value 3.22490e-06 +DEAL:nothread::Testing FE_Q<2>(2) +DEAL:nothread::Number of degrees of freedom: 3403 +DEAL:nothread:cg::Starting value 55.4346 +DEAL:nothread:cg::Convergence step 6 value 8.67842e-07 +DEAL:threaded::Testing FE_Q<2>(2) +DEAL:threaded::Number of degrees of freedom: 3403 +DEAL:threaded:cg::Starting value 55.4346 +DEAL:threaded:cg::Convergence step 6 value 8.67877e-07 +DEAL:nothread::Testing FE_Q<2>(2) +DEAL:nothread::Number of degrees of freedom: 8417 +DEAL:nothread:cg::Starting value 87.1149 +DEAL:nothread:cg::Convergence step 6 value 5.47729e-07 +DEAL:threaded::Testing FE_Q<2>(2) +DEAL:threaded::Number of degrees of freedom: 8417 +DEAL:threaded:cg::Starting value 87.1149 +DEAL:threaded:cg::Convergence step 6 value 5.47731e-07 +DEAL:nothread::Testing FE_Q<3>(1) +DEAL:nothread::Number of degrees of freedom: 186 +DEAL:nothread:cg::Starting value 12.3693 +DEAL:nothread:cg::Convergence step 4 value 2.87808e-08 +DEAL:threaded::Testing FE_Q<3>(1) +DEAL:threaded::Number of degrees of freedom: 186 +DEAL:threaded:cg::Starting value 12.3693 +DEAL:threaded:cg::Convergence step 4 value 2.87808e-08 +DEAL:nothread::Testing FE_Q<3>(1) +DEAL:nothread::Number of degrees of freedom: 648 +DEAL:nothread:cg::Starting value 21.1424 +DEAL:nothread:cg::Convergence step 6 value 6.44935e-07 +DEAL:threaded::Testing FE_Q<3>(1) +DEAL:threaded::Number of degrees of freedom: 648 +DEAL:threaded:cg::Starting value 21.1424 +DEAL:threaded:cg::Convergence step 6 value 6.44935e-07 +DEAL:nothread::Testing FE_Q<3>(1) +DEAL:nothread::Number of degrees of freedom: 2930 +DEAL:nothread:cg::Starting value 47.1699 +DEAL:nothread:cg::Convergence step 7 value 2.56010e-06 +DEAL:threaded::Testing FE_Q<3>(1) +DEAL:threaded::Number of degrees of freedom: 2930 +DEAL:threaded:cg::Starting value 47.1699 +DEAL:threaded:cg::Convergence step 7 value 2.56010e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.cc new file mode 100644 index 0000000000..185f0d5a9d --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.cc @@ -0,0 +1,330 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// same as parallel_multigrid_adaptive_02, but using mg::SmootherRelaxation +// rather than MGSmootherPrecondition + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + LaplaceOperator> + fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_level_data[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + mg::SmootherRelaxation> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(8 - 2 * dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.with_p4est=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.with_p4est=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..e1896201af --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_04.with_p4est=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,15 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 186 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 648 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 2930 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.cc new file mode 100644 index 0000000000..287b2fd05f --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.cc @@ -0,0 +1,643 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// same test as parallel_multigrid_adaptive_03 but using partition_color + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const MGConstrainedDoFs &mg_constrained_dofs, + const std::map *> + & dirichlet_boundary, + const unsigned int level, + const bool threaded) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + if (threaded) + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::partition_color; + else + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.tasks_block_size = 3; + addit_data.mg_level = level; + AffineConstraints constraints; + if (level == numbers::invalid_unsigned_int) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, relevant_dofs); + constraints.reinit(relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + VectorTools::interpolate_boundary_values(dof_handler, + dirichlet_boundary, + constraints); + } + else + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof_handler, + level, + relevant_dofs); + constraints.reinit(relevant_dofs); + constraints.add_lines(mg_constrained_dofs.get_boundary_indices(level)); + + const std::vector interface_indices = + mg_constrained_dofs.get_refinement_edge_indices(level) + .get_index_vector(); + edge_constrained_indices.clear(); + edge_constrained_indices.reserve(interface_indices.size()); + edge_constrained_values.resize(interface_indices.size()); + const IndexSet &locally_owned = + dof_handler.locally_owned_mg_dofs(level); + for (unsigned int i = 0; i < interface_indices.size(); ++i) + if (locally_owned.is_element(interface_indices[i])) + edge_constrained_indices.push_back( + locally_owned.index_within_set(interface_indices[i])); + have_interface_matrices = + Utilities::MPI::max((unsigned int)edge_constrained_indices.size(), + MPI_COMM_WORLD) > 0; + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + if (level != numbers::invalid_unsigned_int) + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + edge_constrained_values[i] = std::pair( + src.local_element(edge_constrained_indices[i]), + dst.local_element(edge_constrained_indices[i])); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + + // reset edge constrained values, multiply by unit matrix and add into + // destination + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + dst.local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].second + edge_constrained_values[i].first; + } + } + + void + vmult_interface_down( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + // set zero Dirichlet values on the input vector (and remember the src and + // dst values because we need to reset them at the end) + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + const double src_val = src.local_element(edge_constrained_indices[i]); + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = 0.; + edge_constrained_values[i] = std::pair( + src_val, dst.local_element(edge_constrained_indices[i])); + } + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + dst.local_element(c) = 0.; + ++c; + + // reset the src values + const_cast &>(src) + .local_element(edge_constrained_indices[i]) = + edge_constrained_values[i].first; + } + for (; c < dst.locally_owned_size(); ++c) + dst.local_element(c) = 0.; + } + + void + vmult_interface_up( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + Assert(src.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + Assert(dst.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + + dst = 0; + + if (!have_interface_matrices) + return; + + LinearAlgebra::distributed::Vector src_cpy(src); + unsigned int c = 0; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + for (; c < edge_constrained_indices[i]; ++c) + src_cpy.local_element(c) = 0.; + ++c; + } + for (; c < src_cpy.locally_owned_size(); ++c) + src_cpy.local_element(c) = 0.; + + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src_cpy); + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + dst.local_element(edge_constrained_indices[i]) = 0.; + } + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + inverse_diagonal_entries.local_element(constrained_dofs[i]) = 1.; + for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i) + { + inverse_diagonal_entries.local_element(edge_constrained_indices[i]) = + 1.; + } + + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + std::vector edge_constrained_indices; + mutable std::vector> edge_constrained_values; + bool have_interface_matrices; +}; + + + +template +class MGInterfaceMatrix : public Subscriptor +{ +public: + void + initialize(const LAPLACEOPERATOR &laplace) + { + this->laplace = &laplace; + } + + void + vmult(LinearAlgebra::distributed::Vector + &dst, + const LinearAlgebra::distributed::Vector< + typename LAPLACEOPERATOR::value_type> &src) const + { + laplace->vmult_interface_down(dst, src); + } + + void + Tvmult( + LinearAlgebra::distributed::Vector + &dst, + const LinearAlgebra::distributed::Vector< + typename LAPLACEOPERATOR::value_type> &src) const + { + laplace->vmult_interface_up(dst, src); + } + +private: + SmartPointer laplace; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const bool threaded) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + AffineConstraints hanging_node_constraints; + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + MGConstrainedDoFs mg_constrained_dofs; + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + fine_matrix.initialize(mapping, + dof, + mg_constrained_dofs, + dirichlet_boundary, + numbers::invalid_unsigned_int, + threaded); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize( + mapping, dof, mg_constrained_dofs, dirichlet_boundary, level, threaded); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner.reset( + new DiagonalMatrix>()); + smoother_data[level].preconditioner->get_vector() = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(8 - 2 * dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + deallog.push("threaded"); + do_test(dof, true); + deallog.pop(); + } +} + + + +int +main(int argc, char **argv) +{ + // The original issue with partition_color + // is hit with 2 threads and 4 cores. + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 2); + + mpi_initlog(); + + test<2, 1, double>(); +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.with_p4est=true.with_lapack=true.mpirun=4.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.with_p4est=true.with_lapack=true.mpirun=4.output new file mode 100644 index 0000000000..5563de9294 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_05.with_p4est=true.with_lapack=true.mpirun=4.output @@ -0,0 +1,17 @@ + +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 507 +DEAL:threaded:cg::Starting value 21.9317 +DEAL:threaded:cg::Convergence step 5 value 1.14537e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 881 +DEAL:threaded:cg::Starting value 27.7669 +DEAL:threaded:cg::Convergence step 6 value 1.18996e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 2147 +DEAL:threaded:cg::Starting value 43.2551 +DEAL:threaded:cg::Convergence step 6 value 1.86235e-06 +DEAL:threaded::Testing FE_Q<2>(1) +DEAL:threaded::Number of degrees of freedom: 6517 +DEAL:threaded:cg::Starting value 76.9220 +DEAL:threaded:cg::Convergence step 6 value 3.14118e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.cc new file mode 100644 index 0000000000..d97e05dfb7 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.cc @@ -0,0 +1,455 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// similar to parallel_multigrid_adaptive_06ref but using +// MGTransferBlockMatrixFree to solve block-diagonal matrix with Laplace +// operator on diagonals. As expected, when we use a block vector with a single +// block, we get the same results as the reference, non-block solution, i.e. +// +// DEAL:2d:cg::Starting value 21.93 +// DEAL:2d:cg::Convergence step 7 value 1.961e-07 +// +// +// What this test is really for is block operations. As expected we see +// exactly the same number of iterations and the ratio of \sqrt(2) in values, +// i.e. +// +// DEAL:2d:cg::Starting value 31.02 +// DEAL:2d:cg::Convergence step 7 value 2.774e-07 + + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + +/** + * Block-Laplace operator with Block vector. + */ +template > +class BlockLaplace : public Subscriptor +{ +public: + using value_type = typename BlockVectorType::value_type; + using size_type = typename BlockVectorType::size_type; + + BlockLaplace() + : Subscriptor() + {} + + void + initialize(std::shared_ptr> data) + { + laplace.initialize(data); + } + + void + initialize(std::shared_ptr> data, + const MGConstrainedDoFs &mg_constrained_dofs, + const unsigned int level) + { + laplace.initialize(data, mg_constrained_dofs, level); + } + + void + vmult_interface_down(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.vmult_interface_down(dst.block(b), src.block(b)); + } + + void + vmult_interface_up(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.vmult_interface_up(dst.block(b), src.block(b)); + } + + void + vmult(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.vmult(dst.block(b), src.block(b)); + } + + void + Tvmult(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.Tvmult(dst.block(b), src.block(b)); + } + + void + vmult_add(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.vmult_add(dst.block(b), src.block(b)); + } + + void + Tvmult_add(BlockVectorType &dst, const BlockVectorType &src) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.Tvmult_add(dst.block(b), src.block(b)); + } + + void + precondition_Jacobi(BlockVectorType & dst, + const BlockVectorType &src, + const value_type omega) const + { + for (unsigned int b = 0; b < src.n_blocks(); ++b) + laplace.precondition_Jacobi(dst.block(b), src.block(b), omega); + } + + void + compute_diagonal() + { + laplace.compute_diagonal(); + } + + + virtual void + clear() + { + laplace.clear(); + } + +private: + MatrixFreeOperators::LaplaceOperator + laplace; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof, const unsigned int nb) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + BlockLaplace> + fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + LinearAlgebra::distributed::BlockVector in(nb), sol(nb); + for (unsigned int b = 0; b < nb; ++b) + { + fine_level_data->initialize_dof_vector(in.block(b)); + fine_level_data->initialize_dof_vector(sol.block(b)); + } + + in.collect_sizes(); + sol.collect_sizes(); + + // set constant rhs vector + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.block(0).locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.block(0).get_partitioner()->local_to_global(i))) + in.block(0).local_element(i) = 1.; + + for (unsigned int b = 1; b < nb; ++b) + in.block(b) = in.block(0); + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + BlockLaplace>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + MGTransferBlockMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = PreconditionJacobi; + MGSmootherPrecondition> + mg_smoother; + + mg_smoother.initialize(mg_matrices, typename SMOOTHER::AdditionalData(0.8)); + + mg::Matrix> mg_matrix( + mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferBlockMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test(const unsigned int nbands = 1) +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof, nbands); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + test<2, 3>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + test<3, 2>(); + deallog.pop(); + } + + // 2 blocks + { + deallog.push("2d"); + test<2, 1>(2); + test<2, 3>(2); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(2); + test<3, 2>(2); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..322c18c754 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06.with_p4est=true.mpirun=3.output @@ -0,0 +1,97 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 7 value 1.961e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 8 value 2.956e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 7 value 2.063e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 7 value 7.253e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 64.26 +DEAL:2d:cg::Convergence step 9 value 1.536e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 83.11 +DEAL:2d:cg::Convergence step 9 value 8.264e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 131.0 +DEAL:2d:cg::Convergence step 9 value 1.071e-05 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 8 value 3.711e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 8 value 5.151e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 9 value 6.124e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 82.90 +DEAL:3d:cg::Convergence step 9 value 3.485e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 152.6 +DEAL:3d:cg::Convergence step 10 value 2.494e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 31.02 +DEAL:2d:cg::Convergence step 7 value 2.774e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 39.27 +DEAL:2d:cg::Convergence step 8 value 4.180e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 61.17 +DEAL:2d:cg::Convergence step 7 value 2.918e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 108.8 +DEAL:2d:cg::Convergence step 7 value 1.026e-05 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 90.87 +DEAL:2d:cg::Convergence step 9 value 2.172e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 117.5 +DEAL:2d:cg::Convergence step 9 value 1.169e-05 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 185.2 +DEAL:2d:cg::Convergence step 9 value 1.515e-05 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 44.14 +DEAL:3d:cg::Convergence step 8 value 5.248e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 77.78 +DEAL:3d:cg::Convergence step 8 value 7.285e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 107.7 +DEAL:3d:cg::Convergence step 9 value 8.661e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 117.2 +DEAL:3d:cg::Convergence step 9 value 4.929e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 215.8 +DEAL:3d:cg::Convergence step 10 value 3.527e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.cc new file mode 100644 index 0000000000..5e84d27c98 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.cc @@ -0,0 +1,322 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// same as parallel_multigrid_adaptive_02, but with Jacobi smoother. +// The only reason for this test is to provide a reference for +// parallel_multigrid_adaptive_06 + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + LaplaceOperator> + fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_level_data[level].get_vector_partitioner()); + + MGTransferGlobalCoarsening> + mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = PreconditionJacobi; + MGSmootherPrecondition> + mg_smoother; + + mg_smoother.initialize(mg_matrices, typename SMOOTHER::AdditionalData(0.8)); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG< + dim, + LinearAlgebra::distributed::Vector, + MGTransferGlobalCoarsening>> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + { + deallog.push("2d"); + test<2, 1>(); + test<2, 3>(); + deallog.pop(); + deallog.push("3d"); + test<3, 1>(); + test<3, 2>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..8ca82135d3 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_06ref.with_p4est=true.mpirun=3.output @@ -0,0 +1,49 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 21.93 +DEAL:2d:cg::Convergence step 7 value 1.961e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 27.77 +DEAL:2d:cg::Convergence step 8 value 2.956e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 43.26 +DEAL:2d:cg::Convergence step 7 value 2.063e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 76.92 +DEAL:2d:cg::Convergence step 7 value 7.253e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 64.26 +DEAL:2d:cg::Convergence step 9 value 1.536e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 83.11 +DEAL:2d:cg::Convergence step 9 value 8.264e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 131.0 +DEAL:2d:cg::Convergence step 9 value 1.071e-05 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 31.21 +DEAL:3d:cg::Convergence step 8 value 3.711e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 55.00 +DEAL:3d:cg::Convergence step 8 value 5.151e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 76.18 +DEAL:3d:cg::Convergence step 9 value 6.124e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 82.90 +DEAL:3d:cg::Convergence step 9 value 3.485e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 152.6 +DEAL:3d:cg::Convergence step 10 value 2.494e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.cc new file mode 100644 index 0000000000..a08337b02d --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.cc @@ -0,0 +1,496 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// This test is similar to parallel_multigrid_adaptive_06 but we also test +// for different polynomial degree in different blocks. +// We expect to have the same iteration numbers as in +// parallel_multigrid_adaptive_06 with repsect to the highest polynomial +// degree used. + + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + +/** + * Block-Laplace operator with Block vector. + */ +template > +class BlockLaplace : public Subscriptor +{ +public: + using value_type = typename BlockVectorType::value_type; + using size_type = typename BlockVectorType::size_type; + + BlockLaplace() + : Subscriptor() + {} + + void + initialize(std::shared_ptr> data) + { + laplace1.initialize(data, std::vector(1, 0)); + laplace2.initialize(data, std::vector(1, 1)); + } + + void + initialize(std::shared_ptr> data, + const std::vector &mg_constrained_dofs, + const unsigned int level) + { + laplace1.initialize(data, + mg_constrained_dofs[0], + level, + std::vector(1, 0)); + laplace2.initialize(data, + mg_constrained_dofs[1], + level, + std::vector(1, 1)); + } + + void + vmult_interface_down(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.vmult_interface_down(dst.block(0), src.block(0)); + laplace2.vmult_interface_down(dst.block(1), src.block(1)); + } + + void + vmult_interface_up(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.vmult_interface_up(dst.block(0), src.block(0)); + laplace2.vmult_interface_up(dst.block(1), src.block(1)); + } + + void + vmult(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.vmult(dst.block(0), src.block(0)); + laplace2.vmult(dst.block(1), src.block(1)); + } + + void + Tvmult(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.Tvmult(dst.block(0), src.block(0)); + laplace2.Tvmult(dst.block(1), src.block(1)); + } + + void + vmult_add(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.vmult_add(dst.block(0), src.block(0)); + laplace2.vmult_add(dst.block(1), src.block(1)); + } + + void + Tvmult_add(BlockVectorType &dst, const BlockVectorType &src) const + { + laplace1.Tvmult_add(dst.block(0), src.block(0)); + laplace2.Tvmult_add(dst.block(1), src.block(1)); + } + + void + precondition_Jacobi(BlockVectorType & dst, + const BlockVectorType &src, + const value_type omega) const + { + laplace1.precondition_Jacobi(dst.block(0), src.block(0), omega); + laplace2.precondition_Jacobi(dst.block(1), src.block(1), omega); + } + + void + compute_diagonal() + { + laplace1.compute_diagonal(); + laplace2.compute_diagonal(); + } + + + virtual void + clear() + { + laplace1.clear(); + laplace2.clear(); + } + +private: + MatrixFreeOperators::LaplaceOperator + laplace1; + MatrixFreeOperators::LaplaceOperator + laplace2; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const std::vector *> &dof) +{ + const unsigned int nb = 2; + if (std::is_same_v == true) + { + deallog.push("float"); + } + else + {} + + for (unsigned int i = 0; i < dof.size(); ++i) + { + deallog << "Testing " << dof[i]->get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof[i]->n_dofs() + << std::endl; + } + + std::vector locally_relevant_dofs(dof.size()); + for (unsigned int i = 0; i < dof.size(); ++i) + DoFTools::extract_locally_relevant_dofs(*dof[i], locally_relevant_dofs[i]); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + std::vector> constraints(dof.size()); + std::vector *> constraints_ptrs(dof.size()); + for (unsigned int i = 0; i < dof.size(); ++i) + { + constraints[i].reinit(locally_relevant_dofs[i]); + DoFTools::make_hanging_node_constraints(*dof[i], constraints[i]); + VectorTools::interpolate_boundary_values(*dof[i], + dirichlet_boundary, + constraints[i]); + constraints[i].close(); + constraints_ptrs[i] = &constraints[i]; + } + QGauss<1> quad(n_q_points_1d); + constexpr int max_degree = std::max(fe_degree_1, fe_degree_2); + MappingQ mapping(max_degree); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + + std::shared_ptr> fine_level_data( + new MatrixFree()); + fine_level_data->reinit( + mapping, dof, constraints_ptrs, quad, fine_level_additional_data); + + BlockLaplace> + fine_matrix; + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + LinearAlgebra::distributed::BlockVector in(nb), sol(nb); + for (unsigned int b = 0; b < nb; ++b) + { + fine_level_data->initialize_dof_vector(in.block(b), b); + fine_level_data->initialize_dof_vector(sol.block(b), b); + } + + in.collect_sizes(); + sol.collect_sizes(); + + // set constant rhs vector + { + for (unsigned int b = 0; b < nb; ++b) + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + + hanging_node_constraints.reinit(locally_relevant_dofs[b]); + DoFTools::make_hanging_node_constraints(*dof[b], + hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.block(b).locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.block(b).get_partitioner()->local_to_global(i))) + in.block(b).local_element(i) = 1.; + } + } + + // level constraints: + std::vector mg_constrained_dofs(dof.size()); + for (unsigned int i = 0; i < dof.size(); ++i) + { + mg_constrained_dofs[i].initialize(*dof[i]); + mg_constrained_dofs[i].make_zero_boundary_constraints(*dof[i], {0}); + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + BlockLaplace>; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof[0]->get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof[0]->get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof[0]->get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + std::vector> level_constraints(dof.size()); + std::vector *> level_constraints_ptrs( + dof.size()); + for (unsigned int i = 0; i < dof.size(); ++i) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(*dof[i], + level, + relevant_dofs); + level_constraints[i].reinit(relevant_dofs); + level_constraints[i].add_lines( + mg_constrained_dofs[i].get_boundary_indices(level)); + level_constraints[i].close(); + level_constraints_ptrs[i] = &level_constraints[i]; + } + + mg_level_data[level].reinit( + mapping, dof, level_constraints_ptrs, quad, mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof[0]->get_triangulation().n_global_levels() - + 1); + for (unsigned int level = 0; + level < dof[0]->get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + MGTransferBlockMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = PreconditionJacobi; + MGSmootherPrecondition> + mg_smoother; + + mg_smoother.initialize(mg_matrices, typename SMOOTHER::AdditionalData(0.8)); + + mg::Matrix> mg_matrix( + mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferBlockMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + if (std::is_same_v == true) + deallog.pop(); + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof[0]->get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + constexpr int max_degree = std::max(fe_degree_1, fe_degree_2); + const unsigned int n_runs = max_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + (((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2)))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe_1(fe_degree_1); + DoFHandler dof_1(tria); + dof_1.distribute_dofs(fe_1); + dof_1.distribute_mg_dofs(); + + FE_Q fe_2(fe_degree_2); + DoFHandler dof_2(tria); + dof_2.distribute_dofs(fe_2); + dof_2.distribute_mg_dofs(); + + std::vector *> dh_ptrs{&dof_1, &dof_2}; + + constexpr int n_q_points_1d = std::max(fe_degree_1, fe_degree_2) + 1; + do_test(dh_ptrs); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(); + deallog << std::setprecision(4); + + // 2 blocks + { + deallog.push("2d"); + test<2, 1, 1>(); + deallog << std::endl; + test<2, 1, 3>(); + deallog << std::endl; + test<2, 3, 1>(); + deallog.pop(); + deallog << std::endl; + deallog.push("3d"); + test<3, 1, 1>(); + deallog << std::endl; + test<3, 1, 2>(); + deallog << std::endl; + test<3, 2, 1>(); + deallog.pop(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..158a6bcb02 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_07.with_p4est=true.mpirun=3.output @@ -0,0 +1,108 @@ + +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 31.02 +DEAL:2d:cg::Convergence step 7 value 2.774e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 39.27 +DEAL:2d:cg::Convergence step 8 value 4.180e-07 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 61.17 +DEAL:2d:cg::Convergence step 7 value 2.918e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 6517 +DEAL:2d:cg::Starting value 108.8 +DEAL:2d:cg::Convergence step 7 value 1.026e-05 +DEAL:2d:: +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d:cg::Starting value 67.90 +DEAL:2d:cg::Convergence step 9 value 1.556e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d:cg::Starting value 87.62 +DEAL:2d:cg::Convergence step 9 value 8.294e-06 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d:cg::Starting value 137.9 +DEAL:2d:cg::Convergence step 9 value 1.073e-05 +DEAL:2d:: +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 4259 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 507 +DEAL:2d:cg::Starting value 67.90 +DEAL:2d:cg::Convergence step 9 value 1.556e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 7457 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 881 +DEAL:2d:cg::Starting value 87.62 +DEAL:2d:cg::Convergence step 9 value 8.294e-06 +DEAL:2d::Testing FE_Q<2>(3) +DEAL:2d::Number of degrees of freedom: 18535 +DEAL:2d::Testing FE_Q<2>(1) +DEAL:2d::Number of degrees of freedom: 2147 +DEAL:2d:cg::Starting value 137.9 +DEAL:2d:cg::Convergence step 9 value 1.073e-05 +DEAL:: +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 44.14 +DEAL:3d:cg::Convergence step 8 value 5.248e-07 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 77.78 +DEAL:3d:cg::Convergence step 8 value 7.285e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 9566 +DEAL:3d:cg::Starting value 107.7 +DEAL:3d:cg::Convergence step 9 value 8.661e-06 +DEAL:3d:: +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d:cg::Starting value 88.58 +DEAL:3d:cg::Convergence step 9 value 3.537e-06 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d:cg::Starting value 162.2 +DEAL:3d:cg::Convergence step 10 value 2.508e-06 +DEAL:3d:: +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 7494 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 1103 +DEAL:3d:cg::Starting value 88.58 +DEAL:3d:cg::Convergence step 9 value 3.537e-06 +DEAL:3d::Testing FE_Q<3>(2) +DEAL:3d::Number of degrees of freedom: 26548 +DEAL:3d::Testing FE_Q<3>(1) +DEAL:3d::Number of degrees of freedom: 3694 +DEAL:3d:cg::Starting value 162.2 +DEAL:3d:cg::Convergence step 10 value 2.508e-06 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.cc b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.cc new file mode 100644 index 0000000000..5a24c48b5e --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.cc @@ -0,0 +1,429 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// similar to parallel_multigrid_adaptive_02 but without using a separate +// transfer class that builds the appropriate vectors. Furthermore, we want to +// avoid setting some vectors to zero in the cell loop. Rather, +// MatrixFreeOperators::LaplaceOperator::adjust_ghost_range_if_necessary() +// will do that - or rather a variant of that, given that we want to modify +// the cell loop of the LaplaceOperator class and provide our own. This forces +// us to reimplement a few things, but all ideas are the same as in the +// matrix-free operators. + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +using namespace dealii::MatrixFreeOperators; + + +template +class MyLaplaceOperator : public MatrixFreeOperators::LaplaceOperator< + dim, + fe_degree, + fe_degree + 1, + 1, + LinearAlgebra::distributed::Vector> +{ +public: + void + initialize(std::shared_ptr> data, + const MGConstrainedDoFs & mg_constrained_dofs, + const unsigned int level) + { + MatrixFreeOperators::Base>:: + initialize(data, + mg_constrained_dofs, + level, + std::vector({0})); + + const std::vector interface_indices = + mg_constrained_dofs.get_refinement_edge_indices(level).get_index_vector(); + vmult_edge_constrained_indices.clear(); + vmult_edge_constrained_indices.reserve(interface_indices.size()); + vmult_edge_constrained_values.resize(interface_indices.size()); + const IndexSet &locally_owned = + this->data->get_dof_handler(0).locally_owned_mg_dofs(level); + for (unsigned int i = 0; i < interface_indices.size(); ++i) + if (locally_owned.is_element(interface_indices[i])) + vmult_edge_constrained_indices.push_back( + locally_owned.index_within_set(interface_indices[i])); + } + + void + initialize(std::shared_ptr> data, + const std::vector & mask = {}) + { + MatrixFreeOperators::Base>:: + initialize(data, mask); + } + + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + adjust_ghost_range_if_necessary(src); + adjust_ghost_range_if_necessary(dst); + + for (unsigned int i = 0; i < vmult_edge_constrained_indices.size(); ++i) + { + vmult_edge_constrained_values[i] = + src.local_element(vmult_edge_constrained_indices[i]); + const_cast &>(src) + .local_element(vmult_edge_constrained_indices[i]) = 0.; + } + + // zero dst within the loop + this->data->cell_loop( + &MyLaplaceOperator::local_apply, this, dst, src, true); + + for (auto i : this->data->get_constrained_dofs(0)) + dst.local_element(i) = src.local_element(i); + for (unsigned int i = 0; i < vmult_edge_constrained_indices.size(); ++i) + { + dst.local_element(vmult_edge_constrained_indices[i]) = + vmult_edge_constrained_values[i]; + const_cast &>(src) + .local_element(vmult_edge_constrained_indices[i]) = + vmult_edge_constrained_values[i]; + } + } + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.gather_evaluate(src, EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate_scatter(EvaluationFlags::gradients, dst); + } + } + + void + adjust_ghost_range_if_necessary( + const LinearAlgebra::distributed::Vector &vec) const + { + if (vec.get_partitioner().get() == + this->data->get_dof_info(0).vector_partitioner.get()) + return; + + Assert( + vec.get_partitioner()->locally_owned_size() == + this->data->get_dof_info(0).vector_partitioner->locally_owned_size(), + ExcMessage("The vector passed to the vmult() function does not have " + "the correct size for compatibility with MatrixFree.")); + LinearAlgebra::distributed::Vector copy_vec(vec); + this->data->initialize_dof_vector( + const_cast &>(vec), 0); + const_cast &>(vec) + .copy_locally_owned_data_from(copy_vec); + } + + std::vector vmult_edge_constrained_indices; + + mutable std::vector vmult_edge_constrained_values; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, constraints); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + // level constraints: + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + MappingQ mapping(fe_degree + 1); + + MyLaplaceOperator fine_matrix; + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + fine_level_additional_data.tasks_block_size = 3; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + fine_matrix.compute_diagonal(); + + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + { + // this is to make it consistent with parallel_multigrid_adaptive.cc + AffineConstraints hanging_node_constraints; + hanging_node_constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof, hanging_node_constraints); + hanging_node_constraints.close(); + + for (unsigned int i = 0; i < in.locally_owned_size(); ++i) + if (!hanging_node_constraints.is_constrained( + in.get_partitioner()->local_to_global(i))) + in.local_element(i) = 1.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = MyLaplaceOperator; + + MGLevelObject mg_matrices; + MGLevelObject> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(std::make_shared>( + mg_level_data[level]), + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + MGLevelObject> mg_interface_matrices; + mg_interface_matrices.resize(0, + dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_level_data[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 6; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(3); + + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + fine_matrix.clear(); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].clear(); +} + + + +template +void +test() +{ + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(6 - dim); + const unsigned int n_runs = fe_degree == 1 ? 6 - dim : 5 - dim; + for (unsigned int i = 0; i < n_runs; ++i) + { + for (typename Triangulation::active_cell_iterator cell = + tria.begin_active(); + cell != tria.end(); + ++cell) + if (cell->is_locally_owned() && + ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2))) + cell->set_refine_flag(); + tria.execute_coarsening_and_refinement(); + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + mpi_initlog(true); + + test<2, 2>(); +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.with_p4est=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.with_p4est=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..f00e1a40b4 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_adaptive_08.with_p4est=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,47 @@ + +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 1935 +DEAL:cg::Starting value 43.0929 +DEAL:cg:cg::Starting value 2.63785 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 0.000574845 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 4.62010e-05 +DEAL:cg:cg::Convergence step 1 value 6.77626e-21 +DEAL:cg:cg::Starting value 6.27180e-07 +DEAL:cg:cg::Convergence step 1 value 1.05879e-22 +DEAL:cg:cg::Starting value 3.19916e-08 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg::Convergence step 5 value 2.10775e-06 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 3403 +DEAL:cg::Starting value 55.4346 +DEAL:cg:cg::Starting value 3.96150 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 0.00121318 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 9.44668e-05 +DEAL:cg:cg::Convergence step 1 value 1.35525e-20 +DEAL:cg:cg::Starting value 1.80128e-06 +DEAL:cg:cg::Convergence step 1 value 2.11758e-22 +DEAL:cg:cg::Starting value 1.21766e-07 +DEAL:cg:cg::Convergence step 1 value 2.64698e-23 +DEAL:cg:cg::Starting value 5.04178e-09 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg::Convergence step 6 value 4.24128e-07 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 8417 +DEAL:cg::Starting value 87.1149 +DEAL:cg:cg::Starting value 9.09582 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 0.00294550 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 0.000242151 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 3.21426e-06 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 1.60211e-07 +DEAL:cg:cg::Convergence step 1 value 0.00000 +DEAL:cg:cg::Starting value 3.38024e-09 +DEAL:cg:cg::Convergence step 1 value 4.13590e-25 +DEAL:cg::Convergence step 6 value 2.56705e-07 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.cc b/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.cc new file mode 100644 index 0000000000..b29a4c0a0b --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.cc @@ -0,0 +1,498 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + + +// test running a multigrid solver on continuous FE_Q finite elements with +// MatrixFree data structures with parallel::fullydistributd::Triangulation +// (otherwise similar to tests/matrix_free/parallel_multigrid_mf.cc) + +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const std::set &dirichlet_boundaries, + const unsigned int level = numbers::invalid_unsigned_int) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.mg_level = level; + + // extract the constraints due to Dirichlet boundary conditions + AffineConstraints constraints; + Functions::ZeroFunction zero; + std::map *> functions; + for (std::set::const_iterator it = + dirichlet_boundaries.begin(); + it != dirichlet_boundaries.end(); + ++it) + functions[*it] = &zero; + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + const std::set dirichlet_boundaries = {0}; + fine_matrix.initialize(mapping, dof, dirichlet_boundaries); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level); + } + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + + // temporarily disable deallog for the setup of the preconditioner that + // involves a CG solver for eigenvalue estimation + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test() +{ + for (unsigned int i = 5; i < 7; ++i) + { + dealii::Triangulation tria( + Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + GridTools::partition_triangulation_zorder( + Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD), tria); + GridTools::partition_multigrid_levels(tria); + + + parallel::fullydistributed::Triangulation tria_pft(MPI_COMM_WORLD); + + // extract relevant information form pdt + auto construction_data = TriangulationDescription::Utilities:: + create_description_from_triangulation( + tria, + MPI_COMM_WORLD, + TriangulationDescription::Settings::construct_multigrid_hierarchy); + + // actually create triangulation + tria_pft.create_triangulation(construction_data); + + FE_Q fe(fe_degree); + DoFHandler dof(tria_pft); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } + + if (false) + for (unsigned int i = 5; i < 7; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + parallel::fullydistributed::Triangulation tria_pft(MPI_COMM_WORLD); + + // extract relevant information form pdt + auto construction_data = TriangulationDescription::Utilities:: + create_description_from_triangulation( + tria, + MPI_COMM_WORLD, + TriangulationDescription::Settings::construct_multigrid_hierarchy); + + // actually create triangulation + tria_pft.create_triangulation(construction_data); + + FE_Q fe(fe_degree); + DoFHandler dof(tria_pft); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + test<2, 1, double>(); + test<2, 2, float>(); + + test<3, 1, double>(); + test<3, 2, float>(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.with_lapack=true.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.with_lapack=true.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..cd88f52b6e --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_fullydistributed.with_lapack=true.with_p4est=true.mpirun=3.output @@ -0,0 +1,33 @@ + +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 81 +DEAL:cg::Starting value 9.00000 +DEAL:cg::Convergence step 3 value 6.75256e-07 +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 2.62465e-09 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 1.71224e-08 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 1089 +DEAL:cg::Starting value 33.0000 +DEAL:cg::Convergence step 4 value 4.31534e-08 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 125 +DEAL:cg::Starting value 11.1803 +DEAL:cg::Convergence step 3 value 4.38307e-07 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 3 value 1.02520e-06 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 4 value 5.99244e-09 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 70.0928 +DEAL:cg::Convergence step 4 value 5.81100e-08 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_interleave.cc b/tests/multigrid-global-coarsening/parallel_multigrid_interleave.cc new file mode 100644 index 0000000000..bb3f5e7b4c --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_interleave.cc @@ -0,0 +1,461 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Similar test as parallel_multigrid_mf, but using the functionality of +// PreconditionChebyshev to embed vector updates into the matrix-free loops of +// a suitable operator class. + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator() + : n_calls_vmult(0) + {} + + void + print_n_calls_special() + { + // round number of calls to make test more robust + if (n_calls_vmult > 0) + deallog + << "Approx. number of calls to special vmult for Operator of size " + << m() << ": " << (n_calls_vmult + 5) / 10 * 10 << std::endl; + } + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const std::set &dirichlet_boundaries, + const unsigned int level = numbers::invalid_unsigned_int) + { + n_calls_vmult = 0; + const QGauss<1> quad(dof_handler.get_fe().degree + 1); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.mg_level = level; + + // extract the constraints due to Dirichlet boundary conditions + AffineConstraints constraints; + Functions::ZeroFunction zero; + std::map *> functions; + for (std::set::const_iterator it = + dirichlet_boundaries.begin(); + it != dirichlet_boundaries.end(); + ++it) + functions[*it] = &zero; + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src, true); + for (const unsigned int i : data.get_constrained_dofs()) + dst.local_element(i) = src.local_element(i); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::function + &operation_before_loop, + const std::function + &operation_after_loop) const + { + ++n_calls_vmult; + data.cell_loop(&LaplaceOperator::local_apply, + this, + dst, + src, + operation_before_loop, + operation_after_loop); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + for (const unsigned int i : data.get_constrained_dofs()) + dst.local_element(i) += src.local_element(i); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + mutable unsigned int n_calls_vmult; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + const unsigned int fe_degree = dof.get_fe().degree; + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + const std::set dirichlet_boundaries = {0}; + fine_matrix.initialize(mapping, dof, dirichlet_boundaries); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector, except boundary + in = 1.; + { + std::map boundary_values; + VectorTools::interpolate_boundary_values(dof, + 0, + Functions::ZeroFunction(), + boundary_values); + for (const auto it : boundary_values) + if (dof.locally_owned_dofs().is_element(it.first)) + in(it.first) = 0.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level); + } + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + using SMOOTHER = + PreconditionChebyshev>; + mg::SmootherRelaxation> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 4; + smoother_data[level].eig_cg_n_iterations = 10; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + + mg_smoother.initialize(mg_matrices, smoother_data); + MGCoarseGridApplySmoother> + mg_coarse(mg_smoother); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + + // Require a fixed number of iterations rather than a tolerance, in order + // to make output more stable + IterationNumberControl control(6, 1e-15); + + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + // Print statistics + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].print_n_calls_special(); + + fine_matrix.print_n_calls_special(); +} + + + +template +void +test(const unsigned int fe_degree) +{ + for (unsigned int i = 6; i < 8; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + test<2, double>(1); + test<2, float>(3); + + test<3, double>(1); + test<3, float>(2); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_interleave.with_p4est=true.with_lapack=true.mpirun=2.output b/tests/multigrid-global-coarsening/parallel_multigrid_interleave.with_p4est=true.with_lapack=true.mpirun=2.output new file mode 100644 index 0000000000..f91c676e79 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_interleave.with_p4est=true.with_lapack=true.mpirun=2.output @@ -0,0 +1,73 @@ + +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 15.0000 +DEAL:cg::Convergence step 6 value 7.67890e-11 +DEAL::Approx. number of calls to special vmult for Operator of size 4: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 9: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 25: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 81: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 289: 50 +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 1089 +DEAL:cg::Starting value 31.0000 +DEAL:cg::Convergence step 6 value 2.23750e-10 +DEAL::Approx. number of calls to special vmult for Operator of size 4: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 9: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 25: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 81: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 289: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 1089: 50 +DEAL::Testing FE_Q<2>(3) +DEAL::Number of degrees of freedom: 2401 +DEAL:cg::Starting value 47.0000 +DEAL:cg::Convergence step 6 value 5.14228e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 16: 30 +DEAL::Approx. number of calls to special vmult for Operator of size 49: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 169: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 625: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 2401: 50 +DEAL::Testing FE_Q<2>(3) +DEAL::Number of degrees of freedom: 9409 +DEAL:cg::Starting value 95.0000 +DEAL:cg::Convergence step 6 value 1.44454e-08 +DEAL::Approx. number of calls to special vmult for Operator of size 16: 30 +DEAL::Approx. number of calls to special vmult for Operator of size 49: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 169: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 625: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 2401: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 9409: 50 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 18.5203 +DEAL:cg::Convergence step 6 value 1.94706e-11 +DEAL::Approx. number of calls to special vmult for Operator of size 8: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 58.0948 +DEAL:cg::Convergence step 6 value 2.47598e-10 +DEAL::Approx. number of calls to special vmult for Operator of size 8: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 58.0948 +DEAL:cg::Convergence step 6 value 1.17825e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 35937 +DEAL:cg::Starting value 172.601 +DEAL:cg::Convergence step 6 value 4.79055e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 35937: 50 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.cc b/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.cc new file mode 100644 index 0000000000..4bd129c1f9 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.cc @@ -0,0 +1,502 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Similar test as parallel_multigrid_mf, but using the functionality of +// PreconditionChebyshev to embed vector updates into the matrix-free loops of +// a suitable operator class and with additional renumbering of unknowns + +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator() + : n_calls_vmult(0) + {} + + void + print_n_calls_special() + { + // round number of calls to make test more robust + if (n_calls_vmult > 0) + deallog + << "Approx. number of calls to special vmult for Operator of size " + << m() << ": " << (n_calls_vmult + 5) / 10 * 10 << std::endl; + } + + void + initialize(const Mapping & mapping, + DoFHandler & dof_handler, + const std::set &dirichlet_boundaries, + const unsigned int level = numbers::invalid_unsigned_int) + { + n_calls_vmult = 0; + const QGauss<1> quad(dof_handler.get_fe().degree + 1); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.mg_level = level; + + // extract the constraints due to Dirichlet boundary conditions + AffineConstraints constraints; + Functions::ZeroFunction zero; + std::map *> functions; + for (std::set::const_iterator it = + dirichlet_boundaries.begin(); + it != dirichlet_boundaries.end(); + ++it) + functions[*it] = &zero; + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + DoFRenumbering::matrix_free_data_locality(dof_handler, + constraints, + addit_data); + + constraints.clear(); + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src, true); + for (const unsigned int i : data.get_constrained_dofs()) + dst.local_element(i) = src.local_element(i); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::function + &operation_before_loop, + const std::function + &operation_after_loop) const + { + ++n_calls_vmult; + data.cell_loop(&LaplaceOperator::local_apply, + this, + dst, + src, + operation_before_loop, + operation_after_loop); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + for (const unsigned int i : data.get_constrained_dofs()) + dst.local_element(i) += src.local_element(i); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + AlignedVector> local_diagonal_vector( + phi.dofs_per_cell); + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; + mutable unsigned int n_calls_vmult; +}; + + + +template +void +do_test(DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + const unsigned int fe_degree = dof.get_fe().degree; + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + const std::set dirichlet_boundaries = {0}; + fine_matrix.initialize(mapping, dof, dirichlet_boundaries); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector, except boundary + in = 1.; + { + std::map boundary_values; + VectorTools::interpolate_boundary_values(dof, + 0, + Functions::ZeroFunction(), + boundary_values); + for (const auto it : boundary_values) + if (dof.locally_owned_dofs().is_element(it.first)) + in(it.first) = 0.; + } + + // set up multigrid in analogy to step-37 + using LevelMatrixType = LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level); + } + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + using SMOOTHER = + PreconditionChebyshev>; + mg::SmootherRelaxation> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 4; + smoother_data[level].eig_cg_n_iterations = 10; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + + mg_smoother.initialize(mg_matrices, smoother_data); + MGCoarseGridApplySmoother> + mg_coarse(mg_smoother); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + + // Require a fixed number of iterations rather than a tolerance, in order + // to make output more stable + IterationNumberControl control(6, 1e-15); + + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } + + // Print statistics + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + mg_matrices[level].print_n_calls_special(); + + fine_matrix.print_n_calls_special(); +} + + + +template +void +test(const unsigned int fe_degree) +{ + for (unsigned int i = 6; i < 8; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + test<2, double>(1); + test<2, float>(3); + + test<3, double>(1); + test<3, float>(2); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.with_p4est=true.with_lapack=true.mpirun=2.output b/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.with_p4est=true.with_lapack=true.mpirun=2.output new file mode 100644 index 0000000000..9a4038fbe1 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_interleave_renumber.with_p4est=true.with_lapack=true.mpirun=2.output @@ -0,0 +1,73 @@ + +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 15.0000 +DEAL:cg::Convergence step 6 value 5.63311e-11 +DEAL::Approx. number of calls to special vmult for Operator of size 4: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 9: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 25: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 81: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 289: 50 +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 1089 +DEAL:cg::Starting value 31.0000 +DEAL:cg::Convergence step 6 value 6.08657e-10 +DEAL::Approx. number of calls to special vmult for Operator of size 4: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 9: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 25: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 81: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 289: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 1089: 50 +DEAL::Testing FE_Q<2>(3) +DEAL::Number of degrees of freedom: 2401 +DEAL:cg::Starting value 47.0000 +DEAL:cg::Convergence step 6 value 2.11509e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 16: 30 +DEAL::Approx. number of calls to special vmult for Operator of size 49: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 169: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 625: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 2401: 50 +DEAL::Testing FE_Q<2>(3) +DEAL::Number of degrees of freedom: 9409 +DEAL:cg::Starting value 95.0000 +DEAL:cg::Convergence step 6 value 8.72760e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 16: 30 +DEAL::Approx. number of calls to special vmult for Operator of size 49: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 169: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 625: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 2401: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 9409: 50 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 18.5203 +DEAL:cg::Convergence step 6 value 2.77603e-11 +DEAL::Approx. number of calls to special vmult for Operator of size 8: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 58.0948 +DEAL:cg::Convergence step 6 value 3.05980e-10 +DEAL::Approx. number of calls to special vmult for Operator of size 8: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 40 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 58.0948 +DEAL:cg::Convergence step 6 value 1.26786e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 35937 +DEAL:cg::Starting value 172.601 +DEAL:cg::Convergence step 6 value 4.72892e-09 +DEAL::Approx. number of calls to special vmult for Operator of size 27: 20 +DEAL::Approx. number of calls to special vmult for Operator of size 125: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 729: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 4913: 50 +DEAL::Approx. number of calls to special vmult for Operator of size 35937: 50 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_mf.cc b/tests/multigrid-global-coarsening/parallel_multigrid_mf.cc new file mode 100644 index 0000000000..5907c11fc3 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_mf.cc @@ -0,0 +1,448 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// same test as parallel_multigrid but using matrix-free transfer operations +// (and including single-precision multigrid preconditioning) + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + +template +class LaplaceOperator : public Subscriptor +{ +public: + using value_type = number; + + LaplaceOperator(){}; + + void + initialize(const Mapping & mapping, + const DoFHandler & dof_handler, + const std::set &dirichlet_boundaries, + const unsigned int level = numbers::invalid_unsigned_int) + { + const QGauss<1> quad(n_q_points_1d); + typename MatrixFree::AdditionalData addit_data; + addit_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + addit_data.mg_level = level; + + // extract the constraints due to Dirichlet boundary conditions + AffineConstraints constraints; + Functions::ZeroFunction zero; + std::map *> functions; + for (std::set::const_iterator it = + dirichlet_boundaries.begin(); + it != dirichlet_boundaries.end(); + ++it) + functions[*it] = &zero; + if (level == numbers::invalid_unsigned_int) + VectorTools::interpolate_boundary_values(dof_handler, + functions, + constraints); + else + { + std::vector local_dofs; + typename DoFHandler::cell_iterator cell = dof_handler.begin(level), + endc = dof_handler.end(level); + for (; cell != endc; ++cell) + { + if (dof_handler.get_triangulation().locally_owned_subdomain() != + numbers::invalid_subdomain_id && + cell->level_subdomain_id() == numbers::artificial_subdomain_id) + continue; + const FiniteElement &fe = cell->get_fe(); + local_dofs.resize(fe.dofs_per_face); + + for (const unsigned int face_no : GeometryInfo::face_indices()) + if (cell->at_boundary(face_no) == true) + { + const typename DoFHandler::face_iterator face = + cell->face(face_no); + const types::boundary_id bi = face->boundary_id(); + if (functions.find(bi) != functions.end()) + { + face->get_mg_dof_indices(level, local_dofs); + for (unsigned int i = 0; i < fe.dofs_per_face; ++i) + constraints.add_line(local_dofs[i]); + } + } + } + } + constraints.close(); + + data.reinit(mapping, dof_handler, constraints, quad, addit_data); + + compute_inverse_diagonal(); + } + + void + vmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + dst = 0; + vmult_add(dst, src); + } + + void + Tvmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + vmult_add(dst, src); + } + + void + vmult_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + data.cell_loop(&LaplaceOperator::local_apply, this, dst, src); + + const std::vector &constrained_dofs = + data.get_constrained_dofs(); + for (unsigned int i = 0; i < constrained_dofs.size(); ++i) + dst.local_element(constrained_dofs[i]) += + src.local_element(constrained_dofs[i]); + } + + types::global_dof_index + m() const + { + return data.get_vector_partitioner()->size(); + } + + types::global_dof_index + n() const + { + return data.get_vector_partitioner()->size(); + } + + number + el(const unsigned int row, const unsigned int col) const + { + AssertThrow(false, + ExcMessage("Matrix-free does not allow for entry access")); + return number(); + } + + void + initialize_dof_vector( + LinearAlgebra::distributed::Vector &vector) const + { + if (!vector.partitioners_are_compatible( + *data.get_dof_info(0).vector_partitioner)) + data.initialize_dof_vector(vector); + Assert(vector.partitioners_are_globally_compatible( + *data.get_dof_info(0).vector_partitioner), + ExcInternalError()); + } + + const LinearAlgebra::distributed::Vector & + get_matrix_diagonal_inverse() const + { + Assert(inverse_diagonal_entries.size() > 0, ExcNotInitialized()); + return inverse_diagonal_entries; + } + + const std::shared_ptr & + get_vector_partitioner() const + { + return data.get_vector_partitioner(); + } + + +private: + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + void + compute_inverse_diagonal() + { + data.initialize_dof_vector(inverse_diagonal_entries); + unsigned int dummy = 0; + data.cell_loop(&LaplaceOperator::local_diagonal_cell, + this, + inverse_diagonal_entries, + dummy); + + for (unsigned int i = 0; i < inverse_diagonal_entries.locally_owned_size(); + ++i) + if (std::abs(inverse_diagonal_entries.local_element(i)) > 1e-10) + inverse_diagonal_entries.local_element(i) = + 1. / inverse_diagonal_entries.local_element(i); + else + inverse_diagonal_entries.local_element(i) = 1.; + } + + void + local_diagonal_cell( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + phi.reinit(cell); + + VectorizedArray local_diagonal_vector[phi.tensor_dofs_per_cell]; + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.begin_dof_values()[j] = VectorizedArray(); + phi.begin_dof_values()[i] = 1.; + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + local_diagonal_vector[i] = phi.begin_dof_values()[i]; + } + for (unsigned int i = 0; i < phi.tensor_dofs_per_cell; ++i) + phi.begin_dof_values()[i] = local_diagonal_vector[i]; + phi.distribute_local_to_global(dst); + } + } + + MatrixFree data; + LinearAlgebra::distributed::Vector inverse_diagonal_entries; +}; + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(fe_degree + 1); + LaplaceOperator fine_matrix; + const std::set dirichlet_boundaries = {0}; + fine_matrix.initialize(mapping, dof, dirichlet_boundaries); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + in = 1.; + + // set up multigrid in analogy to step-37 + using LevelMatrixType = + LaplaceOperator; + + MGLevelObject mg_matrices; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + mg_matrices[level].initialize(mapping, dof, dirichlet_boundaries, level); + } + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + std::vector> partitioners; + for (unsigned int level = mg_matrices.min_level(); + level <= mg_matrices.max_level(); + ++level) + partitioners.push_back(mg_matrices[level].get_vector_partitioner()); + + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + auto preconditioner = std::make_shared< + DiagonalMatrix>>(); + preconditioner->reinit(mg_matrices[level].get_matrix_diagonal_inverse()); + smoother_data[level].preconditioner = std::move(preconditioner); + } + + // temporarily disable deallog for the setup of the preconditioner that + // involves a CG solver for eigenvalue estimation + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test() +{ + for (unsigned int i = 5; i < 7; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + test<2, 1, double>(); + test<2, 2, float>(); + + test<3, 1, double>(); + test<3, 2, float>(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_mf.with_p4est=true.with_lapack=true.mpirun=7.output b/tests/multigrid-global-coarsening/parallel_multigrid_mf.with_p4est=true.with_lapack=true.mpirun=7.output new file mode 100644 index 0000000000..cd88f52b6e --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_mf.with_p4est=true.with_lapack=true.mpirun=7.output @@ -0,0 +1,33 @@ + +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 81 +DEAL:cg::Starting value 9.00000 +DEAL:cg::Convergence step 3 value 6.75256e-07 +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 2.62465e-09 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 1.71224e-08 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 1089 +DEAL:cg::Starting value 33.0000 +DEAL:cg::Convergence step 4 value 4.31534e-08 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 125 +DEAL:cg::Starting value 11.1803 +DEAL:cg::Convergence step 3 value 4.38307e-07 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 3 value 1.02520e-06 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 4 value 5.99244e-09 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 70.0928 +DEAL:cg::Convergence step 4 value 5.81100e-08 diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.cc b/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.cc new file mode 100644 index 0000000000..6eea7cabcd --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.cc @@ -0,0 +1,277 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2014 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// same test as parallel_multigrid_mf but using the Laplace operator from +// MatrixFreeOperators::Laplace and handing the vector partitioning of those +// operators to the MG transfer + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +class MGCoarseIterative + : public MGCoarseGridBase> +{ +public: + MGCoarseIterative() + {} + + void + initialize(const MatrixType &matrix) + { + coarse_matrix = &matrix; + } + + virtual void + operator()(const unsigned int level, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + ReductionControl solver_control(1e4, 1e-50, 1e-10); + SolverCG> solver_coarse( + solver_control); + solver_coarse.solve(*coarse_matrix, dst, src, PreconditionIdentity()); + } + + const MatrixType *coarse_matrix; +}; + + + +template +void +do_test(const DoFHandler &dof) +{ + deallog << "Testing " << dof.get_fe().get_name(); + deallog << std::endl; + deallog << "Number of degrees of freedom: " << dof.n_dofs() << std::endl; + + MappingQ mapping(fe_degree + 1); + MatrixFreeOperators::LaplaceOperator< + dim, + fe_degree, + n_q_points_1d, + 1, + LinearAlgebra::distributed::Vector> + fine_matrix; + + // Dirichlet BC + Functions::ZeroFunction zero_function; + std::map *> dirichlet_boundary; + dirichlet_boundary[0] = &zero_function; + + // fine-level constraints + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof, locally_relevant_dofs); + AffineConstraints constraints; + constraints.reinit(locally_relevant_dofs); + VectorTools::interpolate_boundary_values(dof, + dirichlet_boundary, + constraints); + constraints.close(); + + std::shared_ptr> fine_level_data( + new MatrixFree()); + + typename MatrixFree::AdditionalData fine_level_additional_data; + fine_level_data->reinit(mapping, + dof, + constraints, + QGauss<1>(n_q_points_1d), + fine_level_additional_data); + + fine_matrix.initialize(fine_level_data); + + LinearAlgebra::distributed::Vector in, sol; + fine_matrix.initialize_dof_vector(in); + fine_matrix.initialize_dof_vector(sol); + + // set constant rhs vector + in = 1.; + + // set up multigrid in analogy to step-37 + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(dof); + mg_constrained_dofs.make_zero_boundary_constraints(dof, {0}); + + using LevelMatrixType = MatrixFreeOperators::LaplaceOperator< + dim, + fe_degree, + n_q_points_1d, + 1, + LinearAlgebra::distributed::Vector>; + + MGLevelObject mg_matrices; + MGLevelObject>> mg_level_data; + mg_matrices.resize(0, dof.get_triangulation().n_global_levels() - 1); + mg_level_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + typename MatrixFree::AdditionalData mg_additional_data; + mg_additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + mg_additional_data.tasks_block_size = 3; + mg_additional_data.mg_level = level; + + AffineConstraints level_constraints; + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof, level, relevant_dofs); + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + mg_level_data[level].reset(new MatrixFree()); + mg_level_data[level]->reinit(mapping, + dof, + level_constraints, + QGauss<1>(n_q_points_1d), + mg_additional_data); + mg_matrices[level].initialize(mg_level_data[level], + mg_constrained_dofs, + level); + mg_matrices[level].compute_diagonal(); + } + + MGTransferMF mg_transfer; + std::vector> partitioners( + dof.get_triangulation().n_global_levels()); + for (unsigned int level = 0; level < partitioners.size(); ++level) + partitioners[level] = + mg_level_data[level]->get_dof_info().vector_partitioner; + mg_transfer.build(dof, partitioners); + + MGCoarseIterative mg_coarse; + mg_coarse.initialize(mg_matrices[0]); + + using SMOOTHER = + PreconditionChebyshev>; + MGSmootherPrecondition> + mg_smoother; + + MGLevelObject smoother_data; + smoother_data.resize(0, dof.get_triangulation().n_global_levels() - 1); + for (unsigned int level = 0; + level < dof.get_triangulation().n_global_levels(); + ++level) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 5; + smoother_data[level].eig_cg_n_iterations = 15; + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + + // temporarily disable deallog for the setup of the preconditioner that + // involves a CG solver for eigenvalue estimation + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix> mg_matrix(mg_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + PreconditionMG, + MGTransferMF> + preconditioner(dof, mg, mg_transfer); + + { + // avoid output from inner (coarse-level) solver + deallog.depth_file(2); + ReductionControl control(30, 1e-20, 1e-7); + SolverCG> solver(control); + solver.solve(fine_matrix, sol, in, preconditioner); + } +} + + + +template +void +test() +{ + for (unsigned int i = 5; i < 7; ++i) + { + parallel::distributed::Triangulation tria( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tria); + tria.refine_global(i - dim); + + FE_Q fe(fe_degree); + DoFHandler dof(tria); + dof.distribute_dofs(fe); + dof.distribute_mg_dofs(); + + do_test(dof); + } +} + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + + mpi_initlog(); + + { + test<2, 1, double>(); + test<2, 2, float>(); + + test<3, 1, double>(); + test<3, 2, float>(); + } +} diff --git a/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.with_p4est=true.with_lapack=true.mpirun=3.output b/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.with_p4est=true.with_lapack=true.mpirun=3.output new file mode 100644 index 0000000000..604fbf3e47 --- /dev/null +++ b/tests/multigrid-global-coarsening/parallel_multigrid_mf_02.with_p4est=true.with_lapack=true.mpirun=3.output @@ -0,0 +1,33 @@ + +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 81 +DEAL:cg::Starting value 9.00000 +DEAL:cg::Convergence step 4 value 2.07070e-08 +DEAL::Testing FE_Q<2>(1) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 2.77789e-08 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 289 +DEAL:cg::Starting value 17.0000 +DEAL:cg::Convergence step 4 value 3.93059e-08 +DEAL::Testing FE_Q<2>(2) +DEAL::Number of degrees of freedom: 1089 +DEAL:cg::Starting value 33.0000 +DEAL:cg::Convergence step 4 value 8.11904e-08 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 125 +DEAL:cg::Starting value 11.1803 +DEAL:cg::Convergence step 4 value 3.45976e-07 +DEAL::Testing FE_Q<3>(1) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 4 value 1.07425e-07 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 729 +DEAL:cg::Starting value 27.0000 +DEAL:cg::Convergence step 4 value 2.46943e-06 +DEAL::Testing FE_Q<3>(2) +DEAL::Number of degrees of freedom: 4913 +DEAL:cg::Starting value 70.0928 +DEAL:cg::Convergence step 4 value 4.57526e-06 diff --git a/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.cc b/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.cc new file mode 100644 index 0000000000..6aaf0ccf50 --- /dev/null +++ b/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.cc @@ -0,0 +1,656 @@ +/* --------------------------------------------------------------------- + * + * Copyright (C) 2009 - 2022 by the deal.II authors + * + * This file is part of the deal.II library. + * + * The deal.II library is free software; you can use it, redistribute + * it, and/or modify it under the terms of the GNU Lesser General + * Public License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * The full text of the license can be found in the file LICENSE.md at + * the top level directory of deal.II. + * + * --------------------------------------------------------------------- + * + * Authors: Katharina Kormann, Martin Kronbichler, Uppsala University, + * 2009-2012, updated to MPI version with parallel vectors in 2016 + */ + +// This test verifies that the first strategy for enforcing inhomogeneous +// boundary conditions (i.e., using read_dof_values_plain to compute the +// contribution of the constraints to the right hand side in assemble_rhs) +// given in step-37 works. + + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "../tests.h" + +namespace Step37 +{ + const unsigned int degree_finite_element = 2; + + template + class ManufacturedSolution : public Function + { + public: + virtual double + value(const Point &p, + const unsigned int /*component*/ = 0) const override + { + const double pi = numbers::PI; + return std::sin(pi * p[0]) + std::cos(pi * p[1]); + } + }; + + + + template + class ManufacturedForcing : public Function + { + public: + virtual double + value(const Point &p, + const unsigned int /*compononent*/ = 0) const override + { + return value(p); + } + + template + number + value(const Point &p) const + { + const double pi = numbers::PI; + const number d = 40.0 * p.square() + 1.0; + return 20 * pi * pi * std::cos(pi * p[1]) / d + + 20 * pi * pi * std::sin(pi * p[0]) / d + + 1600 * pi * p[0] * std::cos(pi * p[0]) / (d * d) - + 1600 * pi * p[1] * std::sin(pi * p[1]) / (d * d); + } + }; + + + template + class Coefficient : public Function + { + public: + Coefficient() + : Function() + {} + + virtual double + value(const Point &p, const unsigned int component = 0) const override; + + template + number + value(const Point &p, const unsigned int component = 0) const; + }; + + + + template + template + number + Coefficient::value(const Point &p, + const unsigned int /*component*/) const + { + return 1. / (0.05 + 2. * p.square()); + } + + + + template + double + Coefficient::value(const Point & p, + const unsigned int component) const + { + return value(p, component); + } + + + template + class LaplaceOperator + : public MatrixFreeOperators:: + Base> + { + public: + using value_type = number; + + LaplaceOperator(); + + void + clear() override; + + void + evaluate_coefficient(const Coefficient &coefficient_function); + + virtual void + compute_diagonal() override; + + const Table<2, VectorizedArray> & + get_coefficient() const + { + return coefficient; + } + + private: + virtual void + apply_add( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const override; + + void + local_apply(const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const; + + void + local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const unsigned int & dummy, + const std::pair &cell_range) const; + + Table<2, VectorizedArray> coefficient; + }; + + + + template + LaplaceOperator::LaplaceOperator() + : MatrixFreeOperators::Base>() + {} + + + + template + void + LaplaceOperator::clear() + { + coefficient.reinit(0, 0); + MatrixFreeOperators::Base>:: + clear(); + } + + + + template + void + LaplaceOperator::evaluate_coefficient( + const Coefficient &coefficient_function) + { + const unsigned int n_cells = this->data->n_cell_batches(); + FEEvaluation phi(*this->data); + + coefficient.reinit(n_cells, phi.n_q_points); + for (unsigned int cell = 0; cell < n_cells; ++cell) + { + phi.reinit(cell); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + coefficient(cell, q) = + coefficient_function.value(phi.quadrature_point(q)); + } + } + + + + template + void + LaplaceOperator::local_apply( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & cell_range) const + { + FEEvaluation phi(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + AssertDimension(coefficient.size(0), data.n_cell_batches()); + AssertDimension(coefficient.size(1), phi.n_q_points); + + phi.reinit(cell); + phi.read_dof_values(src); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), q); + phi.integrate(EvaluationFlags::gradients); + phi.distribute_local_to_global(dst); + } + } + + + + template + void + LaplaceOperator::apply_add( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + this->data->cell_loop(&LaplaceOperator::local_apply, this, dst, src); + } + + + + template + void + LaplaceOperator::compute_diagonal() + { + this->inverse_diagonal_entries.reset( + new DiagonalMatrix>()); + LinearAlgebra::distributed::Vector &inverse_diagonal = + this->inverse_diagonal_entries->get_vector(); + this->data->initialize_dof_vector(inverse_diagonal); + unsigned int dummy = 0; + this->data->cell_loop(&LaplaceOperator::local_compute_diagonal, + this, + inverse_diagonal, + dummy); + + this->set_constrained_entries_to_one(inverse_diagonal); + + for (unsigned int i = 0; i < inverse_diagonal.locally_owned_size(); ++i) + { + Assert(inverse_diagonal.local_element(i) > 0., + ExcMessage("No diagonal entry in a positive definite operator " + "should be zero")); + inverse_diagonal.local_element(i) = + 1. / inverse_diagonal.local_element(i); + } + } + + + + template + void + LaplaceOperator::local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation phi(data); + + AlignedVector> diagonal(phi.dofs_per_cell); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + AssertDimension(coefficient.size(0), data.n_cell_batches()); + AssertDimension(coefficient.size(1), phi.n_q_points); + + phi.reinit(cell); + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < phi.dofs_per_cell; ++j) + phi.submit_dof_value(VectorizedArray(), j); + phi.submit_dof_value(make_vectorized_array(1.), i); + + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + phi.submit_gradient(coefficient(cell, q) * phi.get_gradient(q), + q); + phi.integrate(EvaluationFlags::gradients); + diagonal[i] = phi.get_dof_value(i); + } + for (unsigned int i = 0; i < phi.dofs_per_cell; ++i) + phi.submit_dof_value(diagonal[i], i); + phi.distribute_local_to_global(dst); + } + } + + + + template + class LaplaceProblem + { + public: + LaplaceProblem(); + void + run(); + + private: + void + setup_system(); + void + assemble_rhs(); + void + solve(); + void + output_results(const unsigned int cycle) const; + + parallel::distributed::Triangulation triangulation; + + FE_Q fe; + DoFHandler dof_handler; + + AffineConstraints constraints; + using SystemMatrixType = + LaplaceOperator; + SystemMatrixType system_matrix; + + MGConstrainedDoFs mg_constrained_dofs; + using LevelMatrixType = LaplaceOperator; + MGLevelObject mg_matrices; + + LinearAlgebra::distributed::Vector solution; + LinearAlgebra::distributed::Vector system_rhs; + + ConditionalOStream pcout; + }; + + + + template + LaplaceProblem::LaplaceProblem() + : triangulation(MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy) + , fe(degree_finite_element) + , dof_handler(triangulation) + , pcout(deallog.get_file_stream(), + Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) + {} + + + + template + void + LaplaceProblem::setup_system() + { + system_matrix.clear(); + mg_matrices.clear_elements(); + + dof_handler.distribute_dofs(fe); + dof_handler.distribute_mg_dofs(); + + pcout << "Number of degrees of freedom: " << dof_handler.n_dofs() + << std::endl; + + IndexSet locally_relevant_dofs; + DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs); + + constraints.clear(); + constraints.reinit(locally_relevant_dofs); + DoFTools::make_hanging_node_constraints(dof_handler, constraints); + VectorTools::interpolate_boundary_values(dof_handler, + 0, + ManufacturedSolution(), + constraints); + constraints.close(); + + { + typename MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + std::shared_ptr> system_mf_storage( + new MatrixFree()); + system_mf_storage->reinit(MappingQ1{}, + dof_handler, + constraints, + QGauss<1>(fe.degree + 1), + additional_data); + system_matrix.initialize(system_mf_storage); + } + + system_matrix.evaluate_coefficient(Coefficient()); + + system_matrix.initialize_dof_vector(solution); + system_matrix.initialize_dof_vector(system_rhs); + + const unsigned int nlevels = triangulation.n_global_levels(); + mg_matrices.resize(0, nlevels - 1); + + const std::set dirichlet_boundary = {0}; + mg_constrained_dofs.initialize(dof_handler); + mg_constrained_dofs.make_zero_boundary_constraints(dof_handler, + dirichlet_boundary); + + for (unsigned int level = 0; level < nlevels; ++level) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof_handler, + level, + relevant_dofs); + AffineConstraints level_constraints; + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + typename MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + additional_data.mg_level = level; + std::shared_ptr> mg_mf_storage_level( + new MatrixFree()); + mg_mf_storage_level->reinit(MappingQ1{}, + dof_handler, + level_constraints, + QGauss<1>(fe.degree + 1), + additional_data); + + mg_matrices[level].initialize(mg_mf_storage_level, + mg_constrained_dofs, + level); + mg_matrices[level].evaluate_coefficient(Coefficient()); + } + } + + + + template + void + LaplaceProblem::assemble_rhs() + { + solution = 0.0; + constraints.distribute(solution); + solution.update_ghost_values(); + system_rhs = 0.0; + + const Table<2, VectorizedArray> &coefficient = + system_matrix.get_coefficient(); + ManufacturedForcing forcing; + + FEEvaluation phi( + *system_matrix.get_matrix_free()); + for (unsigned int cell = 0; + cell < system_matrix.get_matrix_free()->n_cell_batches(); + ++cell) + { + phi.reinit(cell); + phi.read_dof_values_plain(solution); + phi.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < phi.n_q_points; ++q) + { + phi.submit_gradient(-coefficient(cell, q) * phi.get_gradient(q), q); + phi.submit_value(forcing.value(phi.quadrature_point(q)), q); + } + phi.integrate(EvaluationFlags::values | EvaluationFlags::gradients); + phi.distribute_local_to_global(system_rhs); + } + system_rhs.compress(VectorOperation::add); + } + + + + template + void + LaplaceProblem::solve() + { + MGTransferMF mg_transfer(mg_constrained_dofs); + mg_transfer.build(dof_handler); + + using SmootherType = + PreconditionChebyshev>; + mg::SmootherRelaxation> + mg_smoother; + MGLevelObject smoother_data; + smoother_data.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + { + if (level > 0) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 4; + smoother_data[level].eig_cg_n_iterations = 10; + } + else + { + smoother_data[0].smoothing_range = 1e-3; + smoother_data[0].degree = numbers::invalid_unsigned_int; + smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m(); + } + mg_matrices[level].compute_diagonal(); + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + MGCoarseGridApplySmoother> + mg_coarse; + mg_coarse.initialize(mg_smoother); + + mg::Matrix> mg_matrix( + mg_matrices); + + MGLevelObject> + mg_interface_matrices; + mg_interface_matrices.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + mg::Matrix> mg_interface( + mg_interface_matrices); + + Multigrid> mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother); + mg.set_edge_matrices(mg_interface, mg_interface); + + PreconditionMG, + MGTransferMF> + preconditioner(dof_handler, mg, mg_transfer); + + SolverControl solver_control(100, 1e-12 * system_rhs.l2_norm()); + SolverCG> cg(solver_control); + + constraints.set_zero(solution); + cg.solve(system_matrix, solution, system_rhs, preconditioner); + + constraints.distribute(solution); + } + + + + template + void + LaplaceProblem::output_results(const unsigned int cycle) const + { + if (triangulation.n_global_active_cells() > 1000000) + return; + + Vector errors; + errors.reinit(triangulation.n_active_cells()); + solution.update_ghost_values(); + VectorTools::integrate_difference(dof_handler, + solution, + ManufacturedSolution(), + errors, + QIterated(QTrapezoid<1>(), 4), + VectorTools::NormType::Linfty_norm); + double max_cell_error = 1.0; + if (errors.begin() != errors.end()) + max_cell_error = *std::max_element(errors.begin(), errors.end()); + max_cell_error = Utilities::MPI::max(max_cell_error, MPI_COMM_WORLD); + Assert(max_cell_error != 0.0, ExcInternalError()); + pcout << "max error: " << max_cell_error << '\n'; + static double error = max_cell_error; + pcout << "error ratio: " + << Utilities::MPI::max(error, MPI_COMM_WORLD) / max_cell_error + << '\n'; + error = max_cell_error; + } + + + + template + void + LaplaceProblem::run() + { + for (unsigned int cycle = 0; cycle < 8 - dim; ++cycle) + { + pcout << "Cycle " << cycle << std::endl; + + if (cycle == 0) + { + GridGenerator::hyper_cube(triangulation, 0., 1.); + triangulation.refine_global(3 - dim); + } + triangulation.refine_global(1); + setup_system(); + assemble_rhs(); + solve(); + output_results(cycle); + pcout << std::endl; + } + } +} // namespace Step37 + + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi_init(argc, argv, 1); + MPILogInitAll mpi_log; + + { + Step37::LaplaceProblem<2> laplace_problem; + laplace_problem.run(); + } + + { + Step37::LaplaceProblem<3> laplace_problem; + laplace_problem.run(); + } +} diff --git a/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.with_lapack=true.mpirun=4.with_p4est=true.output b/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.with_lapack=true.mpirun=4.with_p4est=true.output new file mode 100644 index 0000000000..59dbf7d1ff --- /dev/null +++ b/tests/multigrid-global-coarsening/step-37-inhomogeneous-1.with_lapack=true.mpirun=4.with_p4est=true.output @@ -0,0 +1,150 @@ + +Cycle 0 +Number of degrees of freedom: 81 +DEAL:0:cg::Starting value 45.0807 +DEAL:0:cg::Convergence step 7 value 2.65304e-12 +max error: 0.00772526 +error ratio: 1.00000 + +Cycle 1 +Number of degrees of freedom: 289 +DEAL:0:cg::Starting value 68.5863 +DEAL:0:cg::Convergence step 7 value 3.81082e-12 +max error: 0.000971239 +error ratio: 7.95402 + +Cycle 2 +Number of degrees of freedom: 1089 +DEAL:0:cg::Starting value 95.4381 +DEAL:0:cg::Convergence step 7 value 7.14371e-12 +max error: 0.000120278 +error ratio: 8.07497 + +Cycle 3 +Number of degrees of freedom: 4225 +DEAL:0:cg::Starting value 131.732 +DEAL:0:cg::Convergence step 7 value 1.44204e-11 +max error: 1.49228e-05 +error ratio: 8.05998 + +Cycle 4 +Number of degrees of freedom: 16641 +DEAL:0:cg::Starting value 183.473 +DEAL:0:cg::Convergence step 7 value 2.54095e-11 +max error: 1.85713e-06 +error ratio: 8.03544 + +Cycle 5 +Number of degrees of freedom: 66049 +DEAL:0:cg::Starting value 257.379 +DEAL:0:cg::Convergence step 7 value 3.94318e-11 +max error: 2.31590e-07 +error ratio: 8.01904 + +Cycle 0 +Number of degrees of freedom: 125 +DEAL:0:cg::Starting value 6.44073 +DEAL:0:cg::Convergence step 7 value 4.64523e-13 +max error: 0.0499110 +error ratio: 1.00000 + +Cycle 1 +Number of degrees of freedom: 729 +DEAL:0:cg::Starting value 8.68642 +DEAL:0:cg::Convergence step 7 value 5.79753e-13 +max error: 0.00756448 +error ratio: 6.59807 + +Cycle 2 +Number of degrees of freedom: 4913 +DEAL:0:cg::Starting value 9.47362 +DEAL:0:cg::Convergence step 7 value 6.67651e-13 +max error: 0.000965192 +error ratio: 7.83728 + +Cycle 3 +Number of degrees of freedom: 35937 +DEAL:0:cg::Starting value 9.30402 +DEAL:0:cg::Convergence step 7 value 9.36336e-13 +max error: 0.000120048 +error ratio: 8.04008 + +Cycle 4 +Number of degrees of freedom: 274625 +DEAL:0:cg::Starting value 8.99023 +DEAL:0:cg::Convergence step 7 value 1.22268e-12 +max error: 1.49140e-05 +error ratio: 8.04933 + + +DEAL:1:cg::Starting value 45.0807 +DEAL:1:cg::Convergence step 7 value 2.65304e-12 +DEAL:1:cg::Starting value 68.5863 +DEAL:1:cg::Convergence step 7 value 3.81082e-12 +DEAL:1:cg::Starting value 95.4381 +DEAL:1:cg::Convergence step 7 value 7.14371e-12 +DEAL:1:cg::Starting value 131.732 +DEAL:1:cg::Convergence step 7 value 1.44204e-11 +DEAL:1:cg::Starting value 183.473 +DEAL:1:cg::Convergence step 7 value 2.54095e-11 +DEAL:1:cg::Starting value 257.379 +DEAL:1:cg::Convergence step 7 value 3.94318e-11 +DEAL:1:cg::Starting value 6.44073 +DEAL:1:cg::Convergence step 7 value 4.64523e-13 +DEAL:1:cg::Starting value 8.68642 +DEAL:1:cg::Convergence step 7 value 5.79753e-13 +DEAL:1:cg::Starting value 9.47362 +DEAL:1:cg::Convergence step 7 value 6.67651e-13 +DEAL:1:cg::Starting value 9.30402 +DEAL:1:cg::Convergence step 7 value 9.36336e-13 +DEAL:1:cg::Starting value 8.99023 +DEAL:1:cg::Convergence step 7 value 1.22268e-12 + + +DEAL:2:cg::Starting value 45.0807 +DEAL:2:cg::Convergence step 7 value 2.65304e-12 +DEAL:2:cg::Starting value 68.5863 +DEAL:2:cg::Convergence step 7 value 3.81082e-12 +DEAL:2:cg::Starting value 95.4381 +DEAL:2:cg::Convergence step 7 value 7.14371e-12 +DEAL:2:cg::Starting value 131.732 +DEAL:2:cg::Convergence step 7 value 1.44204e-11 +DEAL:2:cg::Starting value 183.473 +DEAL:2:cg::Convergence step 7 value 2.54095e-11 +DEAL:2:cg::Starting value 257.379 +DEAL:2:cg::Convergence step 7 value 3.94318e-11 +DEAL:2:cg::Starting value 6.44073 +DEAL:2:cg::Convergence step 7 value 4.64523e-13 +DEAL:2:cg::Starting value 8.68642 +DEAL:2:cg::Convergence step 7 value 5.79753e-13 +DEAL:2:cg::Starting value 9.47362 +DEAL:2:cg::Convergence step 7 value 6.67651e-13 +DEAL:2:cg::Starting value 9.30402 +DEAL:2:cg::Convergence step 7 value 9.36336e-13 +DEAL:2:cg::Starting value 8.99023 +DEAL:2:cg::Convergence step 7 value 1.22268e-12 + + +DEAL:3:cg::Starting value 45.0807 +DEAL:3:cg::Convergence step 7 value 2.65304e-12 +DEAL:3:cg::Starting value 68.5863 +DEAL:3:cg::Convergence step 7 value 3.81082e-12 +DEAL:3:cg::Starting value 95.4381 +DEAL:3:cg::Convergence step 7 value 7.14371e-12 +DEAL:3:cg::Starting value 131.732 +DEAL:3:cg::Convergence step 7 value 1.44204e-11 +DEAL:3:cg::Starting value 183.473 +DEAL:3:cg::Convergence step 7 value 2.54095e-11 +DEAL:3:cg::Starting value 257.379 +DEAL:3:cg::Convergence step 7 value 3.94318e-11 +DEAL:3:cg::Starting value 6.44073 +DEAL:3:cg::Convergence step 7 value 4.64523e-13 +DEAL:3:cg::Starting value 8.68642 +DEAL:3:cg::Convergence step 7 value 5.79753e-13 +DEAL:3:cg::Starting value 9.47362 +DEAL:3:cg::Convergence step 7 value 6.67651e-13 +DEAL:3:cg::Starting value 9.30402 +DEAL:3:cg::Convergence step 7 value 9.36336e-13 +DEAL:3:cg::Starting value 8.99023 +DEAL:3:cg::Convergence step 7 value 1.22268e-12 + diff --git a/tests/multigrid-global-coarsening/stokes_computation.cc b/tests/multigrid-global-coarsening/stokes_computation.cc new file mode 100644 index 0000000000..743a8ecf3e --- /dev/null +++ b/tests/multigrid-global-coarsening/stokes_computation.cc @@ -0,0 +1,1497 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2012 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test for correctness of matrix free implementation for multigrid stokes + + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "../tests.h" + + +unsigned int minlevel = 0; +const unsigned int velocity_degree = 2; + +double pressure_scaling = 1.0; + +namespace StokesClass +{ + class QuietException + {}; + + namespace StokesSolver + { + /** + * Implement the block Schur preconditioner for the Stokes system. + */ + template + class BlockSchurPreconditioner : public Subscriptor + { + public: + /** + * brief Constructor + * + * S The entire Stokes matrix + * Spre The matrix whose blocks are used in the definition of + * the preconditioning of the Stokes matrix, i.e. containing + *approximations of the A and S blocks. Mppreconditioner Preconditioner + *object for the Schur complement, typically chosen as the mass matrix. + * Apreconditioner Preconditioner object for the matrix A. + * do_solve_A A flag indicating whether we should actually solve with + * the matrix $A$, or only apply one preconditioner step with it. + * A_block_tolerance The tolerance for the CG solver which computes + * the inverse of the A block. + * S_block_tolerance The tolerance for the CG solver which computes + * the inverse of the S block (Schur complement matrix). + **/ + BlockSchurPreconditioner(const StokesMatrixType &S, + const MassMatrixType & Mass, + const PreconditionerMp &Mppreconditioner, + const PreconditionerA & Apreconditioner, + const bool do_solve_A, + const double A_block_tolerance, + const double S_block_tolerance); + + /** + * Matrix vector product with this preconditioner object. + */ + void + vmult(LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const; + + unsigned int + n_iterations_A() const; + unsigned int + n_iterations_S() const; + + private: + /** + * References to the various matrix object this preconditioner works on. + */ + const StokesMatrixType &stokes_matrix; + const MassMatrixType & mass_matrix; + const PreconditionerMp &mp_preconditioner; + const PreconditionerA & a_preconditioner; + + /** + * Whether to actually invert the $\tilde A$ part of the preconditioner + *matrix or to just apply a single preconditioner step with it. + **/ + const bool do_solve_A; + mutable unsigned int n_iterations_A_; + mutable unsigned int n_iterations_S_; + const double A_block_tolerance; + const double S_block_tolerance; + }; + + + template + BlockSchurPreconditioner:: + BlockSchurPreconditioner(const StokesMatrixType &S, + const MassMatrixType & Mass, + const PreconditionerMp &Mppreconditioner, + const PreconditionerA & Apreconditioner, + const bool do_solve_A, + const double A_block_tolerance, + const double S_block_tolerance) + : stokes_matrix(S) + , mass_matrix(Mass) + , mp_preconditioner(Mppreconditioner) + , a_preconditioner(Apreconditioner) + , do_solve_A(do_solve_A) + , n_iterations_A_(0) + , n_iterations_S_(0) + , A_block_tolerance(A_block_tolerance) + , S_block_tolerance(S_block_tolerance) + {} + + template + unsigned int + BlockSchurPreconditioner::n_iterations_A() const + { + return n_iterations_A_; + } + + template + unsigned int + BlockSchurPreconditioner::n_iterations_S() const + { + return n_iterations_S_; + } + + template + void + BlockSchurPreconditioner:: + vmult(LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const + { + LinearAlgebra::distributed::BlockVector utmp(src); + + // first solve with the bottom left block, which we have built + // as a mass matrix with the inverse of the viscosity + { + SolverControl solver_control(1000, + src.block(1).l2_norm() * S_block_tolerance, + false, + false); + + SolverCG> solver( + solver_control); + try + { + dst.block(1) = 0.0; + solver.solve(mass_matrix, + dst.block(1), + src.block(1), + mp_preconditioner); + n_iterations_S_ += solver_control.last_step(); + } + // if the solver fails, report the error from processor 0 with some + // additional information about its location, and throw a quiet + // exception on all other processors + catch (const std::exception &exc) + { + if (Utilities::MPI::this_mpi_process( + src.block(0).get_mpi_communicator()) == 0) + AssertThrow( + false, + ExcMessage( + std::string( + "The iterative (bottom right) solver in BlockSchurPreconditioner::vmult " + "did not converge to a tolerance of " + + Utilities::to_string(solver_control.tolerance()) + + ". It reported the following error:\n\n") + + exc.what())) else throw QuietException(); + } + dst.block(1) *= -1.0; + } + + // apply the top right block + { + LinearAlgebra::distributed::BlockVector dst_tmp(dst); + dst_tmp.block(0) = 0.0; + stokes_matrix.vmult(utmp, dst_tmp); // B^T + utmp.block(0) *= -1.0; + utmp.block(0) += src.block(0); + } + + // now either solve with the top left block (if do_solve_A==true) + // or just apply one preconditioner sweep (for the first few + // iterations of our two-stage outer GMRES iteration) + if (do_solve_A == true) + { + Assert(false, ExcNotImplemented()); + } + else + { + a_preconditioner.vmult(dst.block(0), utmp.block(0)); + n_iterations_A_ += 1; + } + } + } // namespace StokesSolver + + + // Parameters for Sinker example + double beta = 10.0; + double delta = 200.0; + double omega = 0.1; + + template + struct Sinker + { + unsigned int problem_dim; + unsigned int n_sinkers; + std::vector> centers; + double DR_mu; + double mu_min; + double mu_max; + }; + + template + class Viscosity + { + public: + Viscosity(const Sinker &sink); + virtual double + value(const Point &p, const unsigned int component = 0) const; + virtual void + value_list(const std::vector> &points, + std::vector & values, + const unsigned int component = 0) const; + + Sinker sinker; + }; + template + Viscosity::Viscosity(const Sinker &sink) + { + sinker = sink; + } + template + double + Viscosity::value(const Point &p, + const unsigned int /*component*/) const + { + double Chi = 1.0; + for (unsigned int s = 0; s < sinker.n_sinkers; ++s) + { + double dist = p.distance(sinker.centers[s]); + double temp = + 1 - std::exp(-delta * std::pow(std::max(0.0, dist - omega / 2.0), 2)); + Chi *= temp; + } + return (sinker.mu_max - sinker.mu_min) * (1 - Chi) + sinker.mu_min; + } + template + void + Viscosity::value_list(const std::vector> &points, + std::vector & values, + const unsigned int component) const + { + Assert(values.size() == points.size(), + ExcDimensionMismatch(values.size(), points.size())); + Assert(component == 0, ExcIndexRange(component, 0, 1)); + const unsigned int n_points = points.size(); + for (unsigned int i = 0; i < n_points; ++i) + values[i] = value(points[i], component); + } + + template + class RightHandSide + { + public: + RightHandSide(const Sinker &sink); + Sinker sinker; + virtual void + vector_value(const Point &p, Vector &value) const; + }; + template + RightHandSide::RightHandSide(const Sinker &sink) + { + sinker = sink; + } + template + void + RightHandSide::vector_value(const Point &p, + Vector & values) const + { + double Chi = 1.0; + for (unsigned int s = 0; s < sinker.n_sinkers; ++s) + { + double dist = p.distance(sinker.centers[s]); + double temp = + 1 - std::exp(-delta * std::pow(std::max(0.0, dist - omega / 2.0), 2)); + Chi *= temp; + } + + if (sinker.problem_dim == 2) + { + values[0] = 0; + values[1] = beta * (Chi - 1.0); + values[2] = 0; + } + else if (sinker.problem_dim == 3) + { + values[0] = 0; + values[1] = 0; + values[2] = beta * (Chi - 1.0); + values[3] = 0; + } + return; + } + + template + class ExactSolution_BoundaryValues : public Function + { + public: + ExactSolution_BoundaryValues() + : Function(dim + 1) + {} + virtual void + vector_value(const Point &p, Vector &value) const; + }; + template + void + ExactSolution_BoundaryValues::vector_value(const Point &p, + Vector &values) const + { + (void)p; + for (unsigned int i = 0; i < values.size(); ++i) + values(i) = 0.0; + return; + } + + template + class ExactSolution_BoundaryValues_u : public Function + { + public: + ExactSolution_BoundaryValues_u() + : Function(dim) + {} + virtual void + vector_value(const Point &p, Vector &value) const; + }; + template + void + ExactSolution_BoundaryValues_u::vector_value( + const Point &p, + Vector & values) const + { + (void)p; + for (unsigned int i = 0; i < values.size(); ++i) + values(i) = 0.0; + return; + } + + + + template + class StokesOperator + : public MatrixFreeOperators:: + Base> + { + public: + StokesOperator() + : MatrixFreeOperators:: + Base>() + {} + void + clear(); + void + evaluate_2_x_viscosity(const Viscosity &viscosity_function); + virtual void + compute_diagonal(); + + private: + virtual void + apply_add(LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const; + + void + local_apply(const dealii::MatrixFree & data, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src, + const std::pair &cell_range) const; + + Table<2, VectorizedArray> viscosity_x_2; + }; + template + void + StokesOperator::clear() + { + viscosity_x_2.reinit(0, 0); + MatrixFreeOperators:: + Base>::clear(); + } + template + void + StokesOperator::evaluate_2_x_viscosity( + const Viscosity &viscosity_function) + { + const unsigned int n_cells = this->data->n_cell_batches(); + FEEvaluation velocity(*this->data, + 0); + viscosity_x_2.reinit(n_cells, velocity.n_q_points); + for (unsigned int cell = 0; cell < n_cells; ++cell) + { + velocity.reinit(cell); + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + VectorizedArray return_value = + make_vectorized_array(1.); + for (unsigned int i = 0; i < VectorizedArray::size(); ++i) + { + Point p; + for (unsigned int d = 0; d < dim; ++d) + { + p(d) = velocity.quadrature_point(q)(d)[i]; + } + return_value[i] = 2.0 * viscosity_function.value(p); + } + viscosity_x_2(cell, q) = return_value; + } + } + } + template + void + StokesOperator::local_apply( + const dealii::MatrixFree & data, + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src, + const std::pair & cell_range) const + { + using vector_t = VectorizedArray; + FEEvaluation velocity(data, 0); + FEEvaluation pressure(data, 1); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + velocity.reinit(cell); + velocity.read_dof_values(src.block(0)); + velocity.evaluate(EvaluationFlags::gradients); + pressure.reinit(cell); + pressure.read_dof_values(src.block(1)); + pressure.evaluate(EvaluationFlags::values); + + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + SymmetricTensor<2, dim, vector_t> sym_grad_u = + velocity.get_symmetric_gradient(q); + vector_t pres = pressure.get_value(q); + vector_t div = -trace(sym_grad_u); + pressure.submit_value(div, q); + + sym_grad_u *= viscosity_x_2(cell, q); + // subtract p * I + for (unsigned int d = 0; d < dim; ++d) + sym_grad_u[d][d] -= pres; + + velocity.submit_symmetric_gradient(sym_grad_u, q); + } + + velocity.integrate(EvaluationFlags::gradients); + velocity.distribute_local_to_global(dst.block(0)); + pressure.integrate(EvaluationFlags::values); + pressure.distribute_local_to_global(dst.block(1)); + } + } + template + void + StokesOperator::apply_add( + LinearAlgebra::distributed::BlockVector & dst, + const LinearAlgebra::distributed::BlockVector &src) const + { + MatrixFreeOperators:: + Base>::data + ->cell_loop(&StokesOperator::local_apply, this, dst, src); + } + template + void + StokesOperator::compute_diagonal() + { + Assert(false, ExcNotImplemented()); + } + + + template + class MassMatrixOperator + : public MatrixFreeOperators:: + Base> + { + public: + MassMatrixOperator() + : MatrixFreeOperators::Base>() + {} + void + clear(); + void + evaluate_1_over_viscosity(const Viscosity &viscosity_function); + virtual void + compute_diagonal(); + + private: + virtual void + apply_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const; + + void + local_apply(const dealii::MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const; + + void + local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const unsigned int & dummy, + const std::pair &cell_range) const; + + Table<2, VectorizedArray> one_over_viscosity; + }; + template + void + MassMatrixOperator::clear() + { + one_over_viscosity.reinit(0, 0); + MatrixFreeOperators::Base>:: + clear(); + } + template + void + MassMatrixOperator::evaluate_1_over_viscosity( + const Viscosity &viscosity_function) + { + const unsigned int n_cells = this->data->n_cell_batches(); + FEEvaluation pressure(*this->data, + 0); + one_over_viscosity.reinit(n_cells, pressure.n_q_points); + for (unsigned int cell = 0; cell < n_cells; ++cell) + { + pressure.reinit(cell); + for (unsigned int q = 0; q < pressure.n_q_points; ++q) + { + VectorizedArray return_value = + make_vectorized_array(1.); + for (unsigned int i = 0; i < VectorizedArray::size(); ++i) + { + Point p; + for (unsigned int d = 0; d < dim; ++d) + p(d) = pressure.quadrature_point(q)(d)[i]; + return_value[i] = 1.0 / viscosity_function.value(p); + } + one_over_viscosity(cell, q) = return_value; + } + } + } + template + void + MassMatrixOperator::local_apply( + const dealii::MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & cell_range) const + { + FEEvaluation pressure(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + AssertDimension(one_over_viscosity.size(0), data.n_cell_batches()); + AssertDimension(one_over_viscosity.size(1), pressure.n_q_points); + + pressure.reinit(cell); + pressure.read_dof_values(src); + pressure.evaluate(EvaluationFlags::values); + for (unsigned int q = 0; q < pressure.n_q_points; ++q) + pressure.submit_value(one_over_viscosity(cell, q) * + pressure.get_value(q), + q); + pressure.integrate(EvaluationFlags::values); + pressure.distribute_local_to_global(dst); + } + } + template + void + MassMatrixOperator::apply_add( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + MatrixFreeOperators::Base>::data + ->cell_loop(&MassMatrixOperator::local_apply, this, dst, src); + } + template + void + MassMatrixOperator::compute_diagonal() + { + this->inverse_diagonal_entries.reset( + new DiagonalMatrix>()); + this->diagonal_entries.reset( + new DiagonalMatrix>()); + + LinearAlgebra::distributed::Vector &inverse_diagonal = + this->inverse_diagonal_entries->get_vector(); + LinearAlgebra::distributed::Vector &diagonal = + this->diagonal_entries->get_vector(); + + unsigned int dummy = 0; + this->data->initialize_dof_vector(inverse_diagonal); + this->data->initialize_dof_vector(diagonal); + + this->data->cell_loop(&MassMatrixOperator::local_compute_diagonal, + this, + diagonal, + dummy); + + this->set_constrained_entries_to_one(diagonal); + inverse_diagonal = diagonal; + const unsigned int local_size = inverse_diagonal.locally_owned_size(); + for (unsigned int i = 0; i < local_size; ++i) + { + Assert(inverse_diagonal.local_element(i) > 0., + ExcMessage("No diagonal entry in a positive definite operator " + "should be zero")); + inverse_diagonal.local_element(i) = + 1. / inverse_diagonal.local_element(i); + } + } + template + void + MassMatrixOperator::local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation pressure(data, 0); + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + pressure.reinit(cell); + AlignedVector> diagonal(pressure.dofs_per_cell); + for (unsigned int i = 0; i < pressure.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < pressure.dofs_per_cell; ++j) + pressure.begin_dof_values()[j] = VectorizedArray(); + pressure.begin_dof_values()[i] = make_vectorized_array(1.); + + pressure.evaluate(EvaluationFlags::values); + for (unsigned int q = 0; q < pressure.n_q_points; ++q) + pressure.submit_value(one_over_viscosity(cell, q) * + pressure.get_value(q), + q); + pressure.integrate(EvaluationFlags::values); + + diagonal[i] = pressure.begin_dof_values()[i]; + } + + for (unsigned int i = 0; i < pressure.dofs_per_cell; ++i) + pressure.begin_dof_values()[i] = diagonal[i]; + pressure.distribute_local_to_global(dst); + } + } + + + template + class ABlockOperator : public MatrixFreeOperators:: + Base> + { + public: + ABlockOperator() + : MatrixFreeOperators::Base>() + {} + void + clear(); + void + evaluate_2_x_viscosity(const Viscosity &viscosity_function); + virtual void + compute_diagonal(); + + private: + virtual void + apply_add(LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const; + + void + local_apply(const dealii::MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair &cell_range) const; + + void + local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const unsigned int & dummy, + const std::pair &cell_range) const; + + Table<2, VectorizedArray> viscosity_x_2; + }; + template + void + ABlockOperator::clear() + { + viscosity_x_2.reinit(0, 0); + MatrixFreeOperators::Base>:: + clear(); + } + template + void + ABlockOperator::evaluate_2_x_viscosity( + const Viscosity &viscosity_function) + { + const unsigned int n_cells = this->data->n_cell_batches(); + FEEvaluation velocity(*this->data, + 0); + viscosity_x_2.reinit(n_cells, velocity.n_q_points); + for (unsigned int cell = 0; cell < n_cells; ++cell) + { + velocity.reinit(cell); + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + VectorizedArray return_value = + make_vectorized_array(1.); + for (unsigned int i = 0; i < VectorizedArray::size(); ++i) + { + Point p; + for (unsigned int d = 0; d < dim; ++d) + { + p(d) = velocity.quadrature_point(q)(d)[i]; + } + return_value[i] = 2.0 * viscosity_function.value(p); + } + viscosity_x_2(cell, q) = return_value; + } + } + } + template + void + ABlockOperator::local_apply( + const dealii::MatrixFree & data, + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src, + const std::pair & cell_range) const + { + FEEvaluation velocity(data); + + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + AssertDimension(viscosity_x_2.size(0), data.n_cell_batches()); + AssertDimension(viscosity_x_2.size(1), velocity.n_q_points); + + velocity.reinit(cell); + velocity.read_dof_values(src); + velocity.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + velocity.submit_symmetric_gradient( + viscosity_x_2(cell, q) * velocity.get_symmetric_gradient(q), q); + } + velocity.integrate(EvaluationFlags::gradients); + velocity.distribute_local_to_global(dst); + } + } + template + void + ABlockOperator::apply_add( + LinearAlgebra::distributed::Vector & dst, + const LinearAlgebra::distributed::Vector &src) const + { + MatrixFreeOperators::Base>::data + ->cell_loop(&ABlockOperator::local_apply, this, dst, src); + } + template + void + ABlockOperator::compute_diagonal() + { + this->inverse_diagonal_entries.reset( + new DiagonalMatrix>()); + LinearAlgebra::distributed::Vector &inverse_diagonal = + this->inverse_diagonal_entries->get_vector(); + this->data->initialize_dof_vector(inverse_diagonal); + unsigned int dummy = 0; + this->data->cell_loop(&ABlockOperator::local_compute_diagonal, + this, + inverse_diagonal, + dummy); + + this->set_constrained_entries_to_one(inverse_diagonal); + + for (unsigned int i = 0; i < inverse_diagonal.locally_owned_size(); ++i) + { + Assert(inverse_diagonal.local_element(i) > 0., + ExcMessage("No diagonal entry in a positive definite operator " + "should be zero")); + inverse_diagonal.local_element(i) = + 1. / inverse_diagonal.local_element(i); + } + } + template + void + ABlockOperator::local_compute_diagonal( + const MatrixFree & data, + LinearAlgebra::distributed::Vector &dst, + const unsigned int &, + const std::pair &cell_range) const + { + FEEvaluation velocity(data, 0); + for (unsigned int cell = cell_range.first; cell < cell_range.second; ++cell) + { + velocity.reinit(cell); + AlignedVector> diagonal(velocity.dofs_per_cell); + for (unsigned int i = 0; i < velocity.dofs_per_cell; ++i) + { + for (unsigned int j = 0; j < velocity.dofs_per_cell; ++j) + velocity.begin_dof_values()[j] = VectorizedArray(); + velocity.begin_dof_values()[i] = make_vectorized_array(1.); + + velocity.evaluate(EvaluationFlags::gradients); + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + velocity.submit_symmetric_gradient( + viscosity_x_2(cell, q) * velocity.get_symmetric_gradient(q), + q); + } + velocity.integrate(EvaluationFlags::gradients); + + diagonal[i] = velocity.begin_dof_values()[i]; + } + + for (unsigned int i = 0; i < velocity.dofs_per_cell; ++i) + velocity.begin_dof_values()[i] = diagonal[i]; + velocity.distribute_local_to_global(dst); + } + } + + + + template + class StokesProblem + { + public: + StokesProblem(); + + void + run(); + + private: + void + make_grid(const unsigned int ref = 4); + void + create_sinker(const unsigned int n_sinkers, const double visc_jump); + void + setup_system(); + void + assemble_rhs(); + void + solve(); + + using vector_t = LinearAlgebra::distributed::Vector; + using block_vector_t = LinearAlgebra::distributed::BlockVector; + + using StokesMatrixType = StokesOperator; + using MassMatrixType = MassMatrixOperator; + using LevelMatrixType = ABlockOperator; + + unsigned int degree_u; + + FESystem fe_u; + FE_Q fe_p; + + parallel::distributed::Triangulation triangulation; + DoFHandler dof_handler_u; + DoFHandler dof_handler_p; + + std::vector owned_partitioning; + std::vector relevant_partitioning; + + AffineConstraints constraints_u; + AffineConstraints constraints_p; + + block_vector_t solution; + block_vector_t system_rhs; + + StokesMatrixType stokes_matrix; + MassMatrixType mass_matrix; + + MGLevelObject mg_matrices; + MGConstrainedDoFs mg_constrained_dofs; + + Sinker sinker; + }; + + + + template + StokesProblem::StokesProblem() + : degree_u(velocity_degree) + , fe_u(FE_Q(degree_u), dim) + , fe_p(FE_Q(degree_u - 1)) + , triangulation(MPI_COMM_WORLD, + typename Triangulation::MeshSmoothing( + Triangulation::limit_level_difference_at_vertices | + Triangulation::smoothing_on_refinement | + Triangulation::smoothing_on_coarsening), + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy) + , dof_handler_u(triangulation) + , dof_handler_p(triangulation) + {} + + template + void + StokesProblem::create_sinker(const unsigned int n_sinkers, + const double visc_jump) + { + sinker.problem_dim = dim; + sinker.n_sinkers = n_sinkers; + std::srand(171); + for (unsigned int s = 0; s < sinker.n_sinkers; ++s) + { + std::vector coords(dim); + if (Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0) + for (unsigned int i = 0; i < dim; ++i) + coords[i] = std::rand() / (double)RAND_MAX; + + MPI_Bcast(&(coords[0]), dim, MPI_DOUBLE, 0, MPI_COMM_WORLD); + + Tensor<1, dim, double> coords_tens; + for (unsigned int i = 0; i < dim; ++i) + coords_tens[i] = coords[i]; + sinker.centers.push_back(Point(coords_tens)); + } + + sinker.DR_mu = visc_jump; + sinker.mu_max = std::sqrt(sinker.DR_mu); + sinker.mu_min = 1.0 / std::sqrt(sinker.DR_mu); + } + + + template + void + StokesProblem::make_grid(const unsigned int ref) + { + GridGenerator::hyper_cube(triangulation, 0, 1); + triangulation.refine_global(ref); + } + + + template + void + StokesProblem::setup_system() + { + dof_handler_u.clear(); + dof_handler_u.distribute_dofs(fe_u); + dof_handler_u.distribute_mg_dofs(); + + dof_handler_p.clear(); + dof_handler_p.distribute_dofs(fe_p); + + IndexSet locally_relevant_dofs_u; + DoFTools::extract_locally_relevant_dofs(dof_handler_u, + locally_relevant_dofs_u); + constraints_u.reinit(locally_relevant_dofs_u); + DoFTools::make_hanging_node_constraints(dof_handler_u, constraints_u); + + VectorTools::interpolate_boundary_values( + dof_handler_u, 0, ExactSolution_BoundaryValues_u(), constraints_u); + constraints_u.close(); + + IndexSet locally_relevant_dofs_p; + DoFTools::extract_locally_relevant_dofs(dof_handler_p, + locally_relevant_dofs_p); + constraints_p.reinit(locally_relevant_dofs_p); + DoFTools::make_hanging_node_constraints(dof_handler_p, constraints_p); + constraints_p.close(); + + + // Stokes matrix stuff... + typename MatrixFree::AdditionalData additional_data_stokes; + additional_data_stokes.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data_stokes.mapping_update_flags = + (update_values | update_gradients | update_JxW_values | + update_quadrature_points); + + std::vector *> stokes_dofs; + stokes_dofs.push_back(&dof_handler_u); + stokes_dofs.push_back(&dof_handler_p); + std::vector *> stokes_constraints; + stokes_constraints.push_back(&constraints_u); + stokes_constraints.push_back(&constraints_p); + + std::shared_ptr> stokes_mf_storage( + new MatrixFree()); + stokes_mf_storage->reinit(MappingQ1{}, + stokes_dofs, + stokes_constraints, + QGauss<1>(degree_u + 1), + additional_data_stokes); + + stokes_matrix.initialize(stokes_mf_storage); + stokes_matrix.evaluate_2_x_viscosity(Viscosity(sinker)); + + // Mass matrix stuff... + typename MatrixFree::AdditionalData additional_data_mass; + additional_data_mass.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data_mass.mapping_update_flags = + (update_values | update_JxW_values | update_quadrature_points); + std::shared_ptr> mass_mf_storage( + new MatrixFree()); + mass_mf_storage->reinit(MappingQ1{}, + dof_handler_p, + constraints_p, + QGauss<1>(degree_u + 1), + additional_data_mass); + + mass_matrix.initialize(mass_mf_storage); + mass_matrix.evaluate_1_over_viscosity(Viscosity(sinker)); + mass_matrix.compute_diagonal(); + + // GMG stuff... + const unsigned int n_levels = triangulation.n_global_levels(); + mg_matrices.clear_elements(); + + mg_matrices.resize(0, n_levels - 1); + + mg_constrained_dofs.clear(); + const std::set dirichlet_boundary = {0}; + mg_constrained_dofs.initialize(dof_handler_u); + mg_constrained_dofs.make_zero_boundary_constraints(dof_handler_u, + dirichlet_boundary); + + + for (unsigned int level = 0; level < n_levels; ++level) + { + IndexSet relevant_dofs; + DoFTools::extract_locally_relevant_level_dofs(dof_handler_u, + level, + relevant_dofs); + AffineConstraints level_constraints; + level_constraints.reinit(relevant_dofs); + level_constraints.add_lines( + mg_constrained_dofs.get_boundary_indices(level)); + level_constraints.close(); + + typename MatrixFree::AdditionalData additional_data; + additional_data.tasks_parallel_scheme = + MatrixFree::AdditionalData::none; + additional_data.mapping_update_flags = + (update_gradients | update_JxW_values | update_quadrature_points); + additional_data.mg_level = level; + std::shared_ptr> mg_mf_storage_level( + new MatrixFree()); + mg_mf_storage_level->reinit(MappingQ1{}, + dof_handler_u, + level_constraints, + QGauss<1>(degree_u + 1), + additional_data); + + mg_matrices[level].initialize(mg_mf_storage_level, + mg_constrained_dofs, + level); + mg_matrices[level].evaluate_2_x_viscosity(Viscosity(sinker)); + mg_matrices[level].compute_diagonal(); + } + + solution.reinit(2); + system_rhs.reinit(2); + + stokes_matrix.initialize_dof_vector(solution); + stokes_matrix.initialize_dof_vector(system_rhs); + + solution.update_ghost_values(); + solution.collect_sizes(); + + system_rhs.update_ghost_values(); + system_rhs.collect_sizes(); + } + + + + template + void + StokesProblem::assemble_rhs() + { + system_rhs = 0.0; + + // Create operator with no Dirchlet info + StokesMatrixType operator_homogeneous; + typename MatrixFree::AdditionalData data; + data.tasks_parallel_scheme = MatrixFree::AdditionalData::none; + data.mapping_update_flags = (update_values | update_gradients | + update_JxW_values | update_quadrature_points); + + // Create constraints with no Dirchlet info + AffineConstraints constraints_u_no_dirchlet; + IndexSet locally_relevant_dofs_u; + DoFTools::extract_locally_relevant_dofs(dof_handler_u, + locally_relevant_dofs_u); + constraints_u_no_dirchlet.reinit(locally_relevant_dofs_u); + DoFTools::make_hanging_node_constraints(dof_handler_u, + constraints_u_no_dirchlet); + constraints_u_no_dirchlet.close(); + + std::vector *> constraints_no_dirchlet; + constraints_no_dirchlet.push_back(&constraints_u_no_dirchlet); + constraints_no_dirchlet.push_back(&constraints_p); + std::vector *> dofs; + dofs.push_back(&dof_handler_u); + dofs.push_back(&dof_handler_p); + + std::shared_ptr> matrix_free_homogeneous( + new MatrixFree()); + matrix_free_homogeneous->reinit(MappingQ1{}, + dofs, + constraints_no_dirchlet, + QGauss<1>(degree_u + 1), + data); + + operator_homogeneous.initialize(matrix_free_homogeneous); + operator_homogeneous.evaluate_2_x_viscosity(Viscosity(sinker)); + LinearAlgebra::distributed::BlockVector inhomogeneity(2); + operator_homogeneous.initialize_dof_vector(inhomogeneity); + constraints_u.distribute(inhomogeneity.block(0)); + operator_homogeneous.vmult(system_rhs, inhomogeneity); + system_rhs *= -1.; + + // Normal apply boundary + RightHandSide right_hand_side(sinker); + + FEEvaluation + velocity(*stokes_matrix.get_matrix_free(), 0); + FEEvaluation + pressure(*stokes_matrix.get_matrix_free(), 1); + + for (unsigned int cell = 0; + cell < stokes_matrix.get_matrix_free()->n_cell_batches(); + ++cell) + { + velocity.reinit(cell); + pressure.reinit(cell); + for (unsigned int q = 0; q < velocity.n_q_points; ++q) + { + Tensor<1, dim, VectorizedArray> rhs_u; + for (unsigned int d = 0; d < dim; ++d) + rhs_u[d] = make_vectorized_array(1.0); + VectorizedArray rhs_p = make_vectorized_array(1.0); + for (unsigned int i = 0; i < VectorizedArray::size(); ++i) + { + Point p; + for (unsigned int d = 0; d < dim; ++d) + p(d) = velocity.quadrature_point(q)(d)[i]; + + Vector rhs_temp(dim + 1); + right_hand_side.vector_value(p, rhs_temp); + + for (unsigned int d = 0; d < dim; ++d) + rhs_u[d][i] = rhs_temp(d); + rhs_p[i] = rhs_temp(dim); + } + velocity.submit_value(rhs_u, q); + pressure.submit_value(rhs_p, q); + } + velocity.integrate(EvaluationFlags::values); + velocity.distribute_local_to_global(system_rhs.block(0)); + pressure.integrate(EvaluationFlags::values); + pressure.distribute_local_to_global(system_rhs.block(1)); + } + system_rhs.compress(VectorOperation::add); + } + + template + void + StokesProblem::solve() + { + const double solver_tolerance = 1e-6 * system_rhs.l2_norm(); + const unsigned int n_cheap_stokes_solver_steps = 1000; + const double linear_solver_A_block_tolerance = 1e-2; + const double linear_solver_S_block_tolerance = 1e-6; + + // extract Stokes parts of solution vector, without any ghost elements + block_vector_t distributed_stokes_solution(solution); + + const unsigned int block_vel = 0; + const unsigned int block_p = 1; + + // extract Stokes parts of rhs vector + block_vector_t distributed_stokes_rhs(system_rhs); + + PrimitiveVectorMemory mem; + + SolverControl solver_control_cheap(n_cheap_stokes_solver_steps, + solver_tolerance, + false, + false); + + using Transfer = MGTransferMF; + + Transfer mg_transfer(mg_constrained_dofs); + mg_transfer.initialize_constraints(mg_constrained_dofs); + mg_transfer.build(dof_handler_u); + + LevelMatrixType & coarse_matrix = mg_matrices[0]; + SolverControl coarse_solver_control(1000, 1e-12, false, false); + SolverCG coarse_solver(coarse_solver_control); + + PreconditionIdentity coarse_prec_identity; + MGCoarseGridIterativeSolver, + LevelMatrixType, + PreconditionIdentity> + mg_coarse; + mg_coarse.initialize(coarse_solver, coarse_matrix, coarse_prec_identity); + + using SmootherType = PreconditionChebyshev; + mg::SmootherRelaxation mg_smoother; + MGLevelObject smoother_data; + smoother_data.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + { + if (level > 0) + { + smoother_data[level].smoothing_range = 15.; + smoother_data[level].degree = 4; + smoother_data[level].eig_cg_n_iterations = 10; + } + else + { + smoother_data[0].smoothing_range = 1e-3; + smoother_data[0].degree = numbers::invalid_unsigned_int; + smoother_data[0].eig_cg_n_iterations = mg_matrices[0].m(); + } + smoother_data[level].preconditioner = + mg_matrices[level].get_matrix_diagonal_inverse(); + } + mg_smoother.initialize(mg_matrices, smoother_data); + + mg::Matrix mg_matrix(mg_matrices); + + MGLevelObject> + mg_interface_matrices; + mg_interface_matrices.resize(0, triangulation.n_global_levels() - 1); + for (unsigned int level = 0; level < triangulation.n_global_levels(); + ++level) + mg_interface_matrices[level].initialize(mg_matrices[level]); + mg::Matrix mg_interface(mg_interface_matrices); + + Multigrid mg( + mg_matrix, mg_coarse, mg_transfer, mg_smoother, mg_smoother, 0); + mg.set_edge_matrices(mg_interface, mg_interface); + + + PreconditionMG prec_A(dof_handler_u, + mg, + mg_transfer); + + using MassPrec = PreconditionChebyshev; + MassPrec prec_S; + typename MassPrec::AdditionalData prec_S_data; + prec_S_data.smoothing_range = 1e-3; + prec_S_data.degree = numbers::invalid_unsigned_int; + prec_S_data.eig_cg_n_iterations = mass_matrix.m(); + prec_S_data.preconditioner = mass_matrix.get_matrix_diagonal_inverse(); + prec_S.initialize(mass_matrix, prec_S_data); + + using A_prec_type = PreconditionMG; + + // create a cheap preconditioner that consists of only a single V-cycle + const StokesSolver::BlockSchurPreconditioner + preconditioner_cheap(stokes_matrix, + mass_matrix, + prec_S, + prec_A, + false, + linear_solver_A_block_tolerance, + linear_solver_S_block_tolerance); + try + { + SolverFGMRES solver( + solver_control_cheap, + mem, + SolverFGMRES::AdditionalData(50)); + + solver.solve(stokes_matrix, + distributed_stokes_solution, + distributed_stokes_rhs, + preconditioner_cheap); + } + catch (const SolverControl::NoConvergence &) + { + deallog + << "********************************************************************" + << std::endl + << "SOLVER DID NOT CONVERGE AFTER " << n_cheap_stokes_solver_steps + << " ITERATIONS. res=" << solver_control_cheap.last_value() + << std::endl + << "********************************************************************" + << std::endl; + } + + constraints_u.distribute(distributed_stokes_solution.block(0)); + + distributed_stokes_solution.block(block_p) *= pressure_scaling; + + solution.block(block_vel) = distributed_stokes_solution.block(block_vel); + solution.block(block_p) = distributed_stokes_solution.block(block_p); + + deallog << "Solved-in " + << (solver_control_cheap.last_step() != + numbers::invalid_unsigned_int ? + solver_control_cheap.last_step() : + 0) + << " iterations, final residual: " + << solver_control_cheap.last_value() << std::endl; + } + + + template + void + StokesProblem::run() + { + deallog << "Sinker problem in " << dim << "D." << std::endl; + + create_sinker(4, 1000); + deallog << "n_sinker: " << sinker.n_sinkers + << " max/min viscosity ratio: " << sinker.DR_mu << std::endl + << std::endl; + + unsigned int initial_ref; + if (dim == 2) + { + initial_ref = 5; + } + else if (dim == 3) + { + initial_ref = 3; + } + + unsigned int n_cycles = 1; + if (dim == 2) + n_cycles = 2; + for (unsigned int cycle = 0; cycle < n_cycles; ++cycle) + { + if (cycle == 0) + make_grid(initial_ref); + else + triangulation.refine_global(); + + setup_system(); + deallog << "Number of active cells: " + << triangulation.n_global_active_cells() << " (on " + << triangulation.n_global_levels() << " levels)" << std::endl; + deallog << "Number of degrees of freedom: " + << dof_handler_u.n_dofs() + dof_handler_p.n_dofs() << " (" + << dof_handler_u.n_dofs() << '+' << dof_handler_p.n_dofs() + << ')' << std::endl; + + assemble_rhs(); + solve(); + + deallog << std::endl; + } + } +} // namespace StokesClass + + +int +main(int argc, char *argv[]) +{ + dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1); + mpi_initlog(); + try + { + { + deallog.push("2d"); + StokesClass::StokesProblem<2> problem; + problem.run(); + deallog.pop(); + } + { + deallog.push("3d"); + StokesClass::StokesProblem<3> problem; + problem.run(); + deallog.pop(); + } + } + catch (const std::exception &exc) + { + std::cerr << std::endl + << std::endl + << "----------------------------------------------------" + << std::endl; + std::cerr << "Exception on processing: " << std::endl + << exc.what() << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + throw; + } + catch (...) + { + std::cerr << std::endl + << std::endl + << "----------------------------------------------------" + << std::endl; + std::cerr << "Unknown exception!" << std::endl + << "Aborting!" << std::endl + << "----------------------------------------------------" + << std::endl; + throw; + } + + return 0; +} diff --git a/tests/multigrid-global-coarsening/stokes_computation.with_lapack=true.with_p4est=true.mpirun=4.output b/tests/multigrid-global-coarsening/stokes_computation.with_lapack=true.with_p4est=true.mpirun=4.output new file mode 100644 index 0000000000..1f2687b42c --- /dev/null +++ b/tests/multigrid-global-coarsening/stokes_computation.with_lapack=true.with_p4est=true.mpirun=4.output @@ -0,0 +1,19 @@ + +DEAL:2d::Sinker problem in 2D. +DEAL:2d::n_sinker: 4 max/min viscosity ratio: 1000.00 +DEAL:2d:: +DEAL:2d::Number of active cells: 1024 (on 6 levels) +DEAL:2d::Number of degrees of freedom: 9539 (8450+1089) +DEAL:2d::Solved-in 69 iterations, final residual: 5.58979e-08 +DEAL:2d:: +DEAL:2d::Number of active cells: 4096 (on 7 levels) +DEAL:2d::Number of degrees of freedom: 37507 (33282+4225) +DEAL:2d::Solved-in 69 iterations, final residual: 2.58019e-08 +DEAL:2d:: +DEAL:3d::Sinker problem in 3D. +DEAL:3d::n_sinker: 4 max/min viscosity ratio: 1000.00 +DEAL:3d:: +DEAL:3d::Number of active cells: 512 (on 4 levels) +DEAL:3d::Number of degrees of freedom: 15468 (14739+729) +DEAL:3d::Solved-in 62 iterations, final residual: 1.99453e-08 +DEAL:3d:: diff --git a/tests/multigrid-global-coarsening/transfer_05.cc b/tests/multigrid-global-coarsening/transfer_05.cc new file mode 100644 index 0000000000..75b49c7006 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_05.cc @@ -0,0 +1,220 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2006 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// check MGTransferBlockMatrixFree::copy_[from|to]_mg by comparison to non-block +// MGTransferMatrixFree + +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference non-block + MGTransferMF transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free block transfer + MGTransferBlockMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + const unsigned int nb = 3; + + MGLevelObject> lbv( + 0, tr.n_global_levels() - 1); + LinearAlgebra::distributed::BlockVector bv(nb); + + MGLevelObject> lv( + 0, tr.n_global_levels() - 1); + LinearAlgebra::distributed::Vector v(nb); + + // initialize + v.reinit(mgdof.locally_owned_dofs(), MPI_COMM_WORLD); + for (unsigned int b = 0; b < nb; ++b) + bv.block(b).reinit(mgdof.locally_owned_dofs(), MPI_COMM_WORLD); + + for (unsigned int l = lbv.min_level(); l <= lbv.max_level(); ++l) + { + lv[l].reinit(mgdof.locally_owned_mg_dofs(l), MPI_COMM_WORLD); + + lbv[l].reinit(nb); + for (unsigned int b = 0; b < nb; ++b) + lbv[l].block(b).reinit(mgdof.locally_owned_mg_dofs(l), + MPI_COMM_WORLD); + + lbv[l].collect_sizes(); + + // set values: + for (unsigned int b = 0; b < nb; ++b) + for (unsigned int i = 0; i < lbv[l].block(b).locally_owned_size(); + ++i) + lbv[l].block(b).local_element(i) = random_value(); + + lbv[l].compress(VectorOperation::insert); + } + + // check copy_from_mg + transfer.copy_from_mg(mgdof, bv, lbv); + for (unsigned int b = 0; b < nb; ++b) + { + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + lv[l] = lbv[l].block(b); + + transfer_ref.copy_from_mg(mgdof, v, lv); + v -= bv.block(b); + deallog << "Diff copy_from_mg b" << b << ": " << v.l2_norm() + << std::endl; + } + + // check copy_to_mg + // use un-initialized level-block vector to make sure that it will be + // set correctly in copy_to_mg(). + MGLevelObject> lbv2( + 0, tr.n_global_levels() - 1); + for (unsigned int b = 0; b < nb; ++b) + for (unsigned int i = 0; i < bv.block(b).locally_owned_size(); ++i) + bv.block(b).local_element(i) = random_value(); + + transfer.copy_to_mg(mgdof, lbv2, bv); + // Also check that the block vector has its (global) size set on each + // level: + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + { + unsigned int total_size = 0; + for (unsigned int b = 0; b < nb; ++b) + total_size += lbv2[l].block(b).size(); + + AssertThrow(total_size == lbv2[l].size(), + ExcDimensionMismatch(total_size, lbv2[l].size())); + } + + // Finally check the difference: + for (unsigned int b = 0; b < nb; ++b) + { + v = bv.block(b); + transfer_ref.copy_to_mg(mgdof, lv, v); + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + { + lv[l] -= lbv2[l].block(b); + deallog << "Diff copy_to_mg l" << l << ": " << lv[l].l2_norm() + << std::endl; + } + } + + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_05.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/transfer_05.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..bace0b42d8 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_05.with_p4est=true.mpirun=3.output @@ -0,0 +1,367 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_from_mg b2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_06.cc b/tests/multigrid-global-coarsening/transfer_06.cc new file mode 100644 index 0000000000..b209ca749f --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_06.cc @@ -0,0 +1,244 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2006 - 2023 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// check MGTransferBlockMatrixFree::copy_[from|to]_mg by comparison to non-block +// MGTransferMatrixFree. This is similar to transfer_05 but using +// a separate DoFHandler for each block + +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "../tests.h" + + + +template +void +check(const unsigned int fe_degree) +{ + const unsigned int nb = 2; + + FE_Q fe_1(fe_degree + 1); + FE_Q fe_2(fe_degree); + + deallog << "FE: " << fe_1.get_name() << std::endl; + deallog << "FE: " << fe_2.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof_1(tr); + mgdof_1.distribute_dofs(fe_1); + mgdof_1.distribute_mg_dofs(); + + DoFHandler mgdof_2(tr); + mgdof_2.distribute_dofs(fe_2); + mgdof_2.distribute_mg_dofs(); + + const std::vector *> mgdof_ptr{&mgdof_1, &mgdof_2}; + + std::vector mg_constrained_dofs_vector(2); + for (unsigned int i = 0; i < mgdof_ptr.size(); ++i) + { + mg_constrained_dofs_vector[i].initialize(*mgdof_ptr[i]); + mg_constrained_dofs_vector[i].make_zero_boundary_constraints( + *mgdof_ptr[i], {0}); + } + + // build reference non-block + std::vector> transfer_ref; + for (unsigned int b = 0; b < nb; ++b) + { + transfer_ref.emplace_back(mg_constrained_dofs_vector[b]); + transfer_ref[b].build(*mgdof_ptr[b]); + } + + // build matrix-free block transfer + MGTransferBlockMF transfer(mg_constrained_dofs_vector); + transfer.build(mgdof_ptr); + + MGLevelObject> lbv( + 0, tr.n_global_levels() - 1); + LinearAlgebra::distributed::BlockVector bv(nb); + + MGLevelObject> lv( + 0, tr.n_global_levels() - 1); + LinearAlgebra::distributed::Vector v(nb); + + // initialize + for (unsigned int b = 0; b < nb; ++b) + bv.block(b).reinit(mgdof_ptr[b]->locally_owned_dofs(), MPI_COMM_WORLD); + + for (unsigned int l = lbv.min_level(); l <= lbv.max_level(); ++l) + { + lbv[l].reinit(nb); + for (unsigned int b = 0; b < nb; ++b) + lbv[l].block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(l), + MPI_COMM_WORLD); + + lbv[l].collect_sizes(); + + // set values: + for (unsigned int b = 0; b < nb; ++b) + for (unsigned int i = 0; i < lbv[l].block(b).locally_owned_size(); + ++i) + lbv[l].block(b).local_element(i) = random_value(); + + lbv[l].compress(VectorOperation::insert); + } + + // check copy_from_mg + transfer.copy_from_mg(mgdof_ptr, bv, lbv); + for (unsigned int b = 0; b < nb; ++b) + { + v.reinit(mgdof_ptr[b]->locally_owned_dofs(), MPI_COMM_WORLD); + + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + { + lv[l].reinit(mgdof_ptr[b]->locally_owned_mg_dofs(l), + MPI_COMM_WORLD); + lv[l] = lbv[l].block(b); + } + + transfer_ref[b].copy_from_mg(*mgdof_ptr[b], v, lv); + v -= bv.block(b); + deallog << "Diff copy_from_mg b" << b << ": " << v.l2_norm() + << std::endl; + } + + // check copy_to_mg + // use un-initialized level-block vector to make sure that it will be + // set correctly in copy_to_mg(). + MGLevelObject> lbv2( + 0, tr.n_global_levels() - 1); + for (unsigned int b = 0; b < nb; ++b) + for (unsigned int i = 0; i < bv.block(b).locally_owned_size(); ++i) + bv.block(b).local_element(i) = random_value(); + + transfer.copy_to_mg(mgdof_ptr, lbv2, bv); + // Also check that the block vector has its (global) size set on each + // level: + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + { + unsigned int total_size = 0; + for (unsigned int b = 0; b < nb; ++b) + total_size += lbv2[l].block(b).size(); + + AssertThrow(total_size == lbv2[l].size(), + ExcDimensionMismatch(total_size, lbv2[l].size())); + } + + // Finally check the difference: + for (unsigned int b = 0; b < nb; ++b) + { + v.reinit(mgdof_ptr[b]->locally_owned_dofs(), MPI_COMM_WORLD); + + v = bv.block(b); + transfer_ref[b].copy_to_mg(*mgdof_ptr[b], lv, v); + for (unsigned int l = lv.min_level(); l <= lv.max_level(); ++l) + { + lv[l] -= lbv2[l].block(b); + deallog << "Diff copy_to_mg l" << l << ": " << lv[l].l2_norm() + << std::endl; + } + } + + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_06.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/transfer_06.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..0a70122af5 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_06.with_p4est=true.mpirun=3.output @@ -0,0 +1,265 @@ + +DEAL::FE: FE_Q<2>(2) +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(4) +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(4) +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff copy_from_mg b0: 0.00000 +DEAL::Diff copy_from_mg b1: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL::Diff copy_to_mg l0: 0.00000 +DEAL::Diff copy_to_mg l1: 0.00000 +DEAL::Diff copy_to_mg l2: 0.00000 +DEAL::Diff copy_to_mg l3: 0.00000 +DEAL::Diff copy_to_mg l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_01.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_01.cc new file mode 100644 index 0000000000..7932704810 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_01.cc @@ -0,0 +1,151 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with uniform meshes for FE_Q + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3, 4, 5, 6, 8}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference + MGTransferPrebuilt> + transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=1.output new file mode 100644 index 0000000000..17444f6a0f --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=1.output @@ -0,0 +1,364 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 2.22045e-16 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.57009e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 5.43896e-16 +DEAL::Diff restrict add l3: 4.44089e-16 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 1.11022e-16 +DEAL::Diff prolongate l2: 1.66533e-16 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 9.93014e-16 +DEAL::Diff restrict add l2: 1.17495e-15 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.11022e-16 +DEAL::Diff prolongate l4: 2.77556e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 8.30815e-16 +DEAL::Diff restrict add l3: 7.69185e-16 +DEAL::Diff restrict l4: 2.09476e-15 +DEAL::Diff restrict add l4: 2.22045e-15 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 1.57009e-16 +DEAL::Diff prolongate l2: 3.05311e-16 +DEAL::Diff restrict l1: 1.29473e-15 +DEAL::Diff restrict add l1: 1.40433e-15 +DEAL::Diff restrict l2: 2.14132e-15 +DEAL::Diff restrict add l2: 2.43238e-15 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 1.11022e-16 +DEAL::Diff prolongate l2: 2.54384e-16 +DEAL::Diff prolongate l3: 4.75099e-16 +DEAL::Diff restrict l1: 4.96507e-16 +DEAL::Diff restrict add l1: 4.44089e-16 +DEAL::Diff restrict l2: 1.15378e-15 +DEAL::Diff restrict add l2: 1.25607e-15 +DEAL::Diff restrict l3: 3.16560e-15 +DEAL::Diff restrict add l3: 3.35280e-15 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.11022e-16 +DEAL::Diff prolongate l4: 1.57009e-16 +DEAL::Diff prolongate l5: 6.52699e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 9.67870e-16 +DEAL::Diff restrict add l3: 9.93014e-16 +DEAL::Diff restrict l4: 1.55431e-15 +DEAL::Diff restrict add l4: 1.67640e-15 +DEAL::Diff restrict l5: 4.09129e-15 +DEAL::Diff restrict add l5: 4.49606e-15 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 4.80741e-16 +DEAL::Diff restrict l1: 9.15513e-16 +DEAL::Diff restrict add l1: 9.93014e-16 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 1.86190e-16 +DEAL::Diff prolongate l2: 8.36002e-16 +DEAL::Diff restrict l1: 1.88411e-15 +DEAL::Diff restrict add l1: 1.77636e-15 +DEAL::Diff restrict l2: 1.75542e-15 +DEAL::Diff restrict add l2: 2.23152e-15 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 1.43538e-15 +DEAL::Diff restrict l1: 3.89726e-15 +DEAL::Diff restrict add l1: 4.47958e-15 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 2.92423e-16 +DEAL::Diff prolongate l2: 8.77050e-16 +DEAL::Diff prolongate l3: 1.86878e-15 +DEAL::Diff restrict l1: 7.69185e-16 +DEAL::Diff restrict add l1: 7.69185e-16 +DEAL::Diff restrict l2: 1.77982e-15 +DEAL::Diff restrict add l2: 1.71995e-15 +DEAL::Diff restrict l3: 5.40828e-15 +DEAL::Diff restrict add l3: 5.59094e-15 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 2.17853e-15 +DEAL::Diff restrict l1: 6.14936e-15 +DEAL::Diff restrict add l1: 6.60186e-15 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 1.47799e-15 +DEAL::Diff prolongate l2: 2.65352e-15 +DEAL::Diff restrict l1: 3.82826e-15 +DEAL::Diff restrict add l1: 3.82665e-15 +DEAL::Diff restrict l2: 7.88395e-15 +DEAL::Diff restrict add l2: 8.71649e-15 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 2.74525e-16 +DEAL::Diff prolongate l2: 7.76201e-16 +DEAL::Diff prolongate l3: 1.72781e-15 +DEAL::Diff prolongate l4: 3.59470e-15 +DEAL::Diff restrict l1: 3.14018e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 2.57035e-15 +DEAL::Diff restrict add l2: 2.62727e-15 +DEAL::Diff restrict l3: 5.33312e-15 +DEAL::Diff restrict add l3: 5.73030e-15 +DEAL::Diff restrict l4: 1.11508e-14 +DEAL::Diff restrict add l4: 1.20581e-14 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 8.88178e-16 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 2.83052e-16 +DEAL::Diff restrict l1: 2.51215e-15 +DEAL::Diff restrict add l1: 2.51215e-15 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.11022e-16 +DEAL::Diff prolongate l3: 4.87516e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 2.62727e-15 +DEAL::Diff restrict add l3: 3.07674e-15 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 7.53533e-16 +DEAL::Diff restrict l1: 5.10220e-15 +DEAL::Diff restrict add l1: 5.61733e-15 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 2.23773e-16 +DEAL::Diff prolongate l2: 1.17095e-15 +DEAL::Diff restrict l1: 1.40433e-15 +DEAL::Diff restrict add l1: 1.53837e-15 +DEAL::Diff restrict l2: 8.10387e-15 +DEAL::Diff restrict add l2: 8.54223e-15 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 3.76063e-16 +DEAL::Diff prolongate l4: 1.91920e-15 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 4.84444e-15 +DEAL::Diff restrict add l3: 4.94517e-15 +DEAL::Diff restrict l4: 1.43214e-14 +DEAL::Diff restrict add l4: 1.52161e-14 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 5.85228e-16 +DEAL::Diff restrict l1: 4.16593e-15 +DEAL::Diff restrict add l1: 4.78299e-15 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 1.18099e-15 +DEAL::Diff prolongate l2: 3.22757e-15 +DEAL::Diff restrict l1: 4.86475e-15 +DEAL::Diff restrict add l1: 5.10220e-15 +DEAL::Diff restrict l2: 2.45879e-14 +DEAL::Diff restrict add l2: 2.53986e-14 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 6.65254e-15 +DEAL::Diff restrict l1: 4.35629e-14 +DEAL::Diff restrict add l1: 4.43806e-14 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 5.45722e-16 +DEAL::Diff prolongate l2: 3.47491e-15 +DEAL::Diff prolongate l3: 1.08273e-14 +DEAL::Diff restrict l1: 9.18739e-15 +DEAL::Diff restrict add l1: 1.02044e-14 +DEAL::Diff restrict l2: 2.49877e-14 +DEAL::Diff restrict add l2: 2.48888e-14 +DEAL::Diff restrict l3: 7.50329e-14 +DEAL::Diff restrict add l3: 7.66746e-14 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 3.72529e-08 +DEAL::Diff prolongate l2: 1.31933e-07 +DEAL::Diff restrict l1: 1.67638e-08 +DEAL::Diff restrict add l1: 1.67638e-08 +DEAL::Diff restrict l2: 2.42676e-07 +DEAL::Diff restrict add l2: 4.47664e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 1.49012e-08 +DEAL::Diff prolongate l2: 1.44994e-07 +DEAL::Diff prolongate l3: 3.16323e-07 +DEAL::Diff restrict l1: 9.87202e-08 +DEAL::Diff restrict add l1: 9.87202e-08 +DEAL::Diff restrict l2: 2.15219e-07 +DEAL::Diff restrict add l2: 2.62683e-07 +DEAL::Diff restrict l3: 8.19761e-07 +DEAL::Diff restrict add l3: 8.79582e-07 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 2.98754e-07 +DEAL::Diff prolongate l2: 4.70776e-07 +DEAL::Diff restrict l1: 4.57351e-07 +DEAL::Diff restrict add l1: 8.03906e-07 +DEAL::Diff restrict l2: 1.05171e-06 +DEAL::Diff restrict add l2: 1.45557e-06 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 4.77070e-08 +DEAL::Diff prolongate l2: 8.87839e-08 +DEAL::Diff prolongate l3: 3.12393e-07 +DEAL::Diff prolongate l4: 6.85456e-07 +DEAL::Diff restrict l1: 2.84053e-08 +DEAL::Diff restrict add l1: 2.84053e-08 +DEAL::Diff restrict l2: 3.84794e-07 +DEAL::Diff restrict add l2: 4.83101e-07 +DEAL::Diff restrict l3: 7.28061e-07 +DEAL::Diff restrict add l3: 9.02211e-07 +DEAL::Diff restrict l4: 1.41847e-06 +DEAL::Diff restrict add l4: 1.74159e-06 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 4.30708e-07 +DEAL::Diff prolongate l2: 9.62514e-07 +DEAL::Diff restrict l1: 1.03503e-06 +DEAL::Diff restrict add l1: 1.12037e-06 +DEAL::Diff restrict l2: 1.90372e-06 +DEAL::Diff restrict add l2: 2.24836e-06 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 2.37561e-07 +DEAL::Diff prolongate l2: 4.85227e-07 +DEAL::Diff prolongate l3: 9.86324e-07 +DEAL::Diff restrict l1: 4.79749e-07 +DEAL::Diff restrict add l1: 7.42761e-07 +DEAL::Diff restrict l2: 1.10715e-06 +DEAL::Diff restrict add l2: 1.46215e-06 +DEAL::Diff restrict l3: 2.22257e-06 +DEAL::Diff restrict add l3: 2.53551e-06 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 1.49012e-08 +DEAL::Diff prolongate l2: 1.16789e-07 +DEAL::Diff prolongate l3: 3.15373e-07 +DEAL::Diff prolongate l4: 7.29600e-07 +DEAL::Diff prolongate l5: 1.41394e-06 +DEAL::Diff restrict l1: 2.45869e-07 +DEAL::Diff restrict add l1: 2.45869e-07 +DEAL::Diff restrict l2: 4.01137e-07 +DEAL::Diff restrict add l2: 4.01137e-07 +DEAL::Diff restrict l3: 6.86101e-07 +DEAL::Diff restrict add l3: 7.81855e-07 +DEAL::Diff restrict l4: 1.39585e-06 +DEAL::Diff restrict add l4: 1.79306e-06 +DEAL::Diff restrict l5: 3.06809e-06 +DEAL::Diff restrict add l5: 3.72838e-06 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 1.09627e-07 +DEAL::Diff restrict l1: 5.44882e-07 +DEAL::Diff restrict add l1: 5.44882e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 5.32529e-09 +DEAL::Diff prolongate l2: 3.39210e-07 +DEAL::Diff restrict l1: 3.74159e-07 +DEAL::Diff restrict add l1: 3.74159e-07 +DEAL::Diff restrict l2: 1.15370e-06 +DEAL::Diff restrict add l2: 1.22900e-06 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 8.62651e-07 +DEAL::Diff restrict l1: 2.89970e-06 +DEAL::Diff restrict add l1: 3.35540e-06 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 1.39089e-07 +DEAL::Diff prolongate l2: 3.04131e-07 +DEAL::Diff prolongate l3: 1.38532e-06 +DEAL::Diff restrict l1: 6.78934e-07 +DEAL::Diff restrict add l1: 6.78934e-07 +DEAL::Diff restrict l2: 1.38175e-06 +DEAL::Diff restrict add l2: 1.35441e-06 +DEAL::Diff restrict l3: 4.35419e-06 +DEAL::Diff restrict add l3: 4.60971e-06 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 2.07245e-06 +DEAL::Diff restrict l1: 5.91522e-06 +DEAL::Diff restrict add l1: 6.32888e-06 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 7.71899e-07 +DEAL::Diff prolongate l2: 2.83835e-06 +DEAL::Diff restrict l1: 2.59603e-06 +DEAL::Diff restrict add l1: 2.87564e-06 +DEAL::Diff restrict l2: 7.95574e-06 +DEAL::Diff restrict add l2: 8.72324e-06 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 5.82505e-08 +DEAL::Diff prolongate l2: 4.03345e-07 +DEAL::Diff prolongate l3: 1.32056e-06 +DEAL::Diff prolongate l4: 4.47191e-06 +DEAL::Diff restrict l1: 3.57279e-07 +DEAL::Diff restrict add l1: 3.57279e-07 +DEAL::Diff restrict l2: 1.26665e-06 +DEAL::Diff restrict add l2: 1.64848e-06 +DEAL::Diff restrict l3: 4.01036e-06 +DEAL::Diff restrict add l3: 4.09562e-06 +DEAL::Diff restrict l4: 1.25440e-05 +DEAL::Diff restrict add l4: 1.38985e-05 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=4.output b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=4.output new file mode 100644 index 0000000000..f3a370da7c --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=4.output @@ -0,0 +1,364 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.57009e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 2.22045e-16 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 6.66134e-16 +DEAL::Diff restrict add l3: 7.69185e-16 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 4.44089e-16 +DEAL::Diff restrict add l1: 4.44089e-16 +DEAL::Diff restrict l2: 1.29473e-15 +DEAL::Diff restrict add l2: 1.40433e-15 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 5.55112e-17 +DEAL::Diff prolongate l4: 2.43554e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 5.87475e-16 +DEAL::Diff restrict add l3: 4.44089e-16 +DEAL::Diff restrict l4: 1.33227e-15 +DEAL::Diff restrict add l4: 1.47288e-15 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 3.76495e-16 +DEAL::Diff restrict l1: 1.17495e-15 +DEAL::Diff restrict add l1: 1.17495e-15 +DEAL::Diff restrict l2: 2.14132e-15 +DEAL::Diff restrict add l2: 2.39149e-15 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 2.41967e-16 +DEAL::Diff prolongate l3: 4.51828e-16 +DEAL::Diff restrict l1: 2.22045e-16 +DEAL::Diff restrict add l1: 4.44089e-16 +DEAL::Diff restrict l2: 1.48952e-15 +DEAL::Diff restrict add l2: 1.53837e-15 +DEAL::Diff restrict l3: 2.44249e-15 +DEAL::Diff restrict add l3: 2.80867e-15 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.24127e-16 +DEAL::Diff prolongate l4: 2.67665e-16 +DEAL::Diff prolongate l5: 4.95730e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 7.02167e-16 +DEAL::Diff restrict add l3: 6.28037e-16 +DEAL::Diff restrict l4: 1.52226e-15 +DEAL::Diff restrict add l4: 1.88411e-15 +DEAL::Diff restrict l5: 3.75019e-15 +DEAL::Diff restrict add l5: 3.99680e-15 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 5.35510e-16 +DEAL::Diff restrict l1: 1.53837e-15 +DEAL::Diff restrict add l1: 1.53837e-15 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 2.77902e-16 +DEAL::Diff prolongate l2: 1.02023e-15 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 4.44089e-16 +DEAL::Diff restrict l2: 2.63897e-15 +DEAL::Diff restrict add l2: 2.80867e-15 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 1.47011e-15 +DEAL::Diff restrict l1: 3.83198e-15 +DEAL::Diff restrict add l1: 4.01526e-15 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 3.87586e-16 +DEAL::Diff prolongate l2: 8.10619e-16 +DEAL::Diff prolongate l3: 1.77724e-15 +DEAL::Diff restrict l1: 7.69185e-16 +DEAL::Diff restrict add l1: 1.08779e-15 +DEAL::Diff restrict l2: 1.76940e-15 +DEAL::Diff restrict add l2: 1.83103e-15 +DEAL::Diff restrict l3: 5.45198e-15 +DEAL::Diff restrict add l3: 5.51547e-15 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 2.43957e-15 +DEAL::Diff restrict l1: 6.58340e-15 +DEAL::Diff restrict add l1: 7.00409e-15 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 1.52511e-15 +DEAL::Diff prolongate l2: 2.75500e-15 +DEAL::Diff restrict l1: 2.71778e-15 +DEAL::Diff restrict add l1: 3.13232e-15 +DEAL::Diff restrict l2: 7.50219e-15 +DEAL::Diff restrict add l2: 8.11603e-15 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 5.32625e-16 +DEAL::Diff prolongate l2: 1.03306e-15 +DEAL::Diff prolongate l3: 1.87470e-15 +DEAL::Diff prolongate l4: 3.84816e-15 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 2.07704e-15 +DEAL::Diff restrict add l2: 2.66454e-15 +DEAL::Diff restrict l3: 4.96856e-15 +DEAL::Diff restrict add l3: 5.31517e-15 +DEAL::Diff restrict l4: 1.11741e-14 +DEAL::Diff restrict add l4: 1.19415e-14 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 1.66533e-16 +DEAL::Diff restrict l1: 1.60119e-15 +DEAL::Diff restrict add l1: 1.83103e-15 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 3.11884e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 3.46845e-15 +DEAL::Diff restrict add l3: 3.87148e-15 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 5.17215e-16 +DEAL::Diff restrict l1: 4.86475e-15 +DEAL::Diff restrict add l1: 5.29193e-15 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 2.14994e-16 +DEAL::Diff prolongate l2: 9.84663e-16 +DEAL::Diff restrict l1: 1.53837e-15 +DEAL::Diff restrict add l1: 1.53837e-15 +DEAL::Diff restrict l2: 6.76417e-15 +DEAL::Diff restrict add l2: 7.29713e-15 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 3.52521e-16 +DEAL::Diff prolongate l4: 1.77530e-15 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 3.74196e-15 +DEAL::Diff restrict add l3: 3.97205e-15 +DEAL::Diff restrict l4: 1.30912e-14 +DEAL::Diff restrict add l4: 1.43901e-14 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 7.61858e-16 +DEAL::Diff restrict l1: 1.06951e-14 +DEAL::Diff restrict add l1: 1.06951e-14 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 6.76681e-16 +DEAL::Diff prolongate l2: 3.94720e-15 +DEAL::Diff restrict l1: 3.66205e-15 +DEAL::Diff restrict add l1: 3.20237e-15 +DEAL::Diff restrict l2: 2.23362e-14 +DEAL::Diff restrict add l2: 2.30199e-14 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 8.06498e-15 +DEAL::Diff restrict l1: 4.17135e-14 +DEAL::Diff restrict add l1: 4.21809e-14 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 7.45673e-16 +DEAL::Diff prolongate l2: 4.05889e-15 +DEAL::Diff prolongate l3: 1.18902e-14 +DEAL::Diff restrict l1: 3.55271e-15 +DEAL::Diff restrict add l1: 3.43990e-15 +DEAL::Diff restrict l2: 2.10627e-14 +DEAL::Diff restrict add l2: 2.12329e-14 +DEAL::Diff restrict l3: 7.30222e-14 +DEAL::Diff restrict add l3: 7.41273e-14 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 2.98023e-08 +DEAL::Diff prolongate l2: 1.17073e-07 +DEAL::Diff restrict l1: 1.09896e-07 +DEAL::Diff restrict add l1: 1.09896e-07 +DEAL::Diff restrict l2: 2.72120e-07 +DEAL::Diff restrict add l2: 3.19417e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 1.86265e-08 +DEAL::Diff prolongate l2: 8.98385e-08 +DEAL::Diff prolongate l3: 2.91263e-07 +DEAL::Diff restrict l1: 2.09548e-08 +DEAL::Diff restrict add l1: 2.59373e-07 +DEAL::Diff restrict l2: 2.81788e-07 +DEAL::Diff restrict add l2: 2.43079e-07 +DEAL::Diff restrict l3: 6.86195e-07 +DEAL::Diff restrict add l3: 9.19423e-07 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 2.10869e-07 +DEAL::Diff prolongate l2: 5.18665e-07 +DEAL::Diff restrict l1: 5.39228e-07 +DEAL::Diff restrict add l1: 6.22714e-07 +DEAL::Diff restrict l2: 1.05092e-06 +DEAL::Diff restrict add l2: 1.28920e-06 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 2.32831e-09 +DEAL::Diff prolongate l2: 1.06222e-07 +DEAL::Diff prolongate l3: 3.08336e-07 +DEAL::Diff prolongate l4: 6.35164e-07 +DEAL::Diff restrict l1: 9.77889e-08 +DEAL::Diff restrict add l1: 9.77889e-08 +DEAL::Diff restrict l2: 3.48858e-07 +DEAL::Diff restrict add l2: 4.43091e-07 +DEAL::Diff restrict l3: 6.32397e-07 +DEAL::Diff restrict add l3: 6.36345e-07 +DEAL::Diff restrict l4: 1.34609e-06 +DEAL::Diff restrict add l4: 1.74577e-06 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 4.65403e-07 +DEAL::Diff prolongate l2: 8.14610e-07 +DEAL::Diff restrict l1: 8.38442e-07 +DEAL::Diff restrict add l1: 1.04497e-06 +DEAL::Diff restrict l2: 1.93553e-06 +DEAL::Diff restrict add l2: 2.22941e-06 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 1.92120e-07 +DEAL::Diff prolongate l2: 4.89637e-07 +DEAL::Diff prolongate l3: 1.00159e-06 +DEAL::Diff restrict l1: 4.66622e-07 +DEAL::Diff restrict add l1: 6.18348e-07 +DEAL::Diff restrict l2: 1.07663e-06 +DEAL::Diff restrict add l2: 1.25560e-06 +DEAL::Diff restrict l3: 2.27705e-06 +DEAL::Diff restrict add l3: 2.76853e-06 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 1.86265e-08 +DEAL::Diff prolongate l2: 1.34182e-07 +DEAL::Diff prolongate l3: 2.50837e-07 +DEAL::Diff prolongate l4: 6.39631e-07 +DEAL::Diff prolongate l5: 1.36606e-06 +DEAL::Diff restrict l1: 1.41561e-07 +DEAL::Diff restrict add l1: 1.41561e-07 +DEAL::Diff restrict l2: 2.95878e-07 +DEAL::Diff restrict add l2: 3.03793e-07 +DEAL::Diff restrict l3: 7.65107e-07 +DEAL::Diff restrict add l3: 8.77487e-07 +DEAL::Diff restrict l4: 1.37239e-06 +DEAL::Diff restrict add l4: 1.69515e-06 +DEAL::Diff restrict l5: 2.90070e-06 +DEAL::Diff restrict add l5: 3.56294e-06 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 3.16376e-08 +DEAL::Diff restrict l1: 1.28523e-07 +DEAL::Diff restrict add l1: 6.05360e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 1.12532e-08 +DEAL::Diff prolongate l2: 3.87787e-07 +DEAL::Diff restrict l1: 6.46105e-08 +DEAL::Diff restrict add l1: 6.46105e-08 +DEAL::Diff restrict l2: 1.24234e-06 +DEAL::Diff restrict add l2: 1.24808e-06 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 8.05794e-07 +DEAL::Diff restrict l1: 2.83397e-06 +DEAL::Diff restrict add l1: 3.05075e-06 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 2.11658e-08 +DEAL::Diff prolongate l2: 3.90292e-07 +DEAL::Diff prolongate l3: 1.51881e-06 +DEAL::Diff restrict l1: 4.28758e-07 +DEAL::Diff restrict add l1: 4.28758e-07 +DEAL::Diff restrict l2: 1.01649e-06 +DEAL::Diff restrict add l2: 1.14211e-06 +DEAL::Diff restrict l3: 3.94122e-06 +DEAL::Diff restrict add l3: 4.23609e-06 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 2.14713e-06 +DEAL::Diff restrict l1: 6.15121e-06 +DEAL::Diff restrict add l1: 6.59074e-06 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 9.90071e-07 +DEAL::Diff prolongate l2: 2.90218e-06 +DEAL::Diff restrict l1: 3.04764e-06 +DEAL::Diff restrict add l1: 3.40151e-06 +DEAL::Diff restrict l2: 7.91521e-06 +DEAL::Diff restrict add l2: 8.68910e-06 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 1.73861e-08 +DEAL::Diff prolongate l2: 4.86459e-07 +DEAL::Diff prolongate l3: 1.41420e-06 +DEAL::Diff prolongate l4: 4.47432e-06 +DEAL::Diff restrict l1: 4.23752e-08 +DEAL::Diff restrict add l1: 4.34462e-07 +DEAL::Diff restrict l2: 1.49430e-06 +DEAL::Diff restrict add l2: 1.49275e-06 +DEAL::Diff restrict l3: 4.52097e-06 +DEAL::Diff restrict add l3: 4.93599e-06 +DEAL::Diff restrict l4: 1.26332e-05 +DEAL::Diff restrict add l4: 1.38610e-05 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=7.output b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=7.output new file mode 100644 index 0000000000..57c8077f85 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_01.with_p4est=true.with_trilinos=true.mpirun=7.output @@ -0,0 +1,364 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.11022e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 6.28037e-16 +DEAL::Diff restrict add l3: 7.69185e-16 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.57009e-16 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 9.42055e-16 +DEAL::Diff restrict add l2: 8.88178e-16 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 2.73361e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 7.77156e-16 +DEAL::Diff restrict add l3: 8.00593e-16 +DEAL::Diff restrict l4: 1.29473e-15 +DEAL::Diff restrict add l4: 1.66163e-15 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 1.11022e-16 +DEAL::Diff prolongate l2: 3.46945e-16 +DEAL::Diff restrict l1: 8.00593e-16 +DEAL::Diff restrict add l1: 9.93014e-16 +DEAL::Diff restrict l2: 2.36037e-15 +DEAL::Diff restrict add l2: 2.58946e-15 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 9.61481e-17 +DEAL::Diff prolongate l3: 4.83935e-16 +DEAL::Diff restrict l1: 6.66134e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 9.42055e-16 +DEAL::Diff restrict add l2: 1.17495e-15 +DEAL::Diff restrict l3: 2.48253e-15 +DEAL::Diff restrict add l3: 2.73755e-15 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 5.55112e-17 +DEAL::Diff prolongate l4: 1.57009e-16 +DEAL::Diff prolongate l5: 5.14040e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 4.96507e-16 +DEAL::Diff restrict add l3: 6.28037e-16 +DEAL::Diff restrict l4: 1.70917e-15 +DEAL::Diff restrict add l4: 1.89715e-15 +DEAL::Diff restrict l5: 3.90950e-15 +DEAL::Diff restrict add l5: 4.28264e-15 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 5.86162e-16 +DEAL::Diff restrict l1: 1.08779e-15 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 4.39840e-16 +DEAL::Diff prolongate l2: 1.33460e-15 +DEAL::Diff restrict l1: 4.44089e-16 +DEAL::Diff restrict add l1: 4.44089e-16 +DEAL::Diff restrict l2: 2.37079e-15 +DEAL::Diff restrict add l2: 2.47258e-15 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 1.30473e-15 +DEAL::Diff restrict l1: 3.36198e-15 +DEAL::Diff restrict add l1: 3.78128e-15 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 1.57927e-16 +DEAL::Diff prolongate l2: 8.20434e-16 +DEAL::Diff prolongate l3: 2.02790e-15 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 8.88178e-16 +DEAL::Diff restrict l2: 1.15911e-15 +DEAL::Diff restrict add l2: 1.08779e-15 +DEAL::Diff restrict l3: 4.45440e-15 +DEAL::Diff restrict add l3: 4.48508e-15 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 2.50604e-15 +DEAL::Diff restrict l1: 5.30560e-15 +DEAL::Diff restrict add l1: 6.22913e-15 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 1.35942e-15 +DEAL::Diff prolongate l2: 3.05918e-15 +DEAL::Diff restrict l1: 3.54664e-15 +DEAL::Diff restrict add l1: 4.52339e-15 +DEAL::Diff restrict l2: 7.68849e-15 +DEAL::Diff restrict add l2: 8.53356e-15 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 4.25711e-16 +DEAL::Diff prolongate l2: 7.75419e-16 +DEAL::Diff prolongate l3: 1.72716e-15 +DEAL::Diff prolongate l4: 3.94909e-15 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 9.93014e-16 +DEAL::Diff restrict l2: 1.25607e-15 +DEAL::Diff restrict add l2: 1.71995e-15 +DEAL::Diff restrict l3: 4.36857e-15 +DEAL::Diff restrict add l3: 4.64705e-15 +DEAL::Diff restrict l4: 1.06615e-14 +DEAL::Diff restrict add l4: 1.15035e-14 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 1.66678e-16 +DEAL::Diff restrict l1: 1.17495e-15 +DEAL::Diff restrict add l1: 8.88178e-16 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 5.55112e-17 +DEAL::Diff prolongate l3: 3.80818e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 3.01196e-15 +DEAL::Diff restrict add l3: 3.32326e-15 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 5.62008e-16 +DEAL::Diff restrict l1: 4.35117e-15 +DEAL::Diff restrict add l1: 4.44089e-15 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 9.71445e-17 +DEAL::Diff prolongate l2: 1.03975e-15 +DEAL::Diff restrict l1: 9.93014e-16 +DEAL::Diff restrict add l1: 1.25607e-15 +DEAL::Diff restrict l2: 6.21725e-15 +DEAL::Diff restrict add l2: 6.73495e-15 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 3.42475e-16 +DEAL::Diff prolongate l4: 1.72594e-15 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 2.43238e-15 +DEAL::Diff restrict add l3: 2.34990e-15 +DEAL::Diff restrict l4: 1.14348e-14 +DEAL::Diff restrict add l4: 1.23310e-14 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 6.50327e-16 +DEAL::Diff restrict l1: 6.08904e-15 +DEAL::Diff restrict add l1: 6.02392e-15 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 9.68541e-16 +DEAL::Diff prolongate l2: 4.87552e-15 +DEAL::Diff restrict l1: 4.44089e-15 +DEAL::Diff restrict add l1: 4.52884e-15 +DEAL::Diff restrict l2: 2.01905e-14 +DEAL::Diff restrict add l2: 2.02986e-14 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 8.78343e-15 +DEAL::Diff restrict l1: 3.92368e-14 +DEAL::Diff restrict add l1: 3.96547e-14 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 8.84649e-16 +DEAL::Diff prolongate l2: 3.96858e-15 +DEAL::Diff prolongate l3: 1.31313e-14 +DEAL::Diff restrict l1: 2.17558e-15 +DEAL::Diff restrict add l1: 2.17558e-15 +DEAL::Diff restrict l2: 1.66037e-14 +DEAL::Diff restrict add l2: 1.69294e-14 +DEAL::Diff restrict l3: 6.69581e-14 +DEAL::Diff restrict add l3: 6.79718e-14 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 3.72529e-08 +DEAL::Diff prolongate l2: 1.23918e-07 +DEAL::Diff restrict l1: 1.97440e-07 +DEAL::Diff restrict add l1: 1.97440e-07 +DEAL::Diff restrict l2: 3.51720e-07 +DEAL::Diff restrict add l2: 4.38541e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 3.72529e-09 +DEAL::Diff prolongate l2: 1.31323e-07 +DEAL::Diff prolongate l3: 2.69264e-07 +DEAL::Diff restrict l1: 3.37139e-07 +DEAL::Diff restrict add l1: 9.87202e-08 +DEAL::Diff restrict l2: 4.04329e-07 +DEAL::Diff restrict add l2: 3.87504e-07 +DEAL::Diff restrict l3: 6.87816e-07 +DEAL::Diff restrict add l3: 8.68312e-07 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 2.07089e-07 +DEAL::Diff prolongate l2: 5.55799e-07 +DEAL::Diff restrict l1: 5.67399e-07 +DEAL::Diff restrict add l1: 7.86516e-07 +DEAL::Diff restrict l2: 1.29939e-06 +DEAL::Diff restrict add l2: 1.57817e-06 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 1.19267e-08 +DEAL::Diff prolongate l2: 1.39742e-07 +DEAL::Diff prolongate l3: 3.09723e-07 +DEAL::Diff prolongate l4: 6.63463e-07 +DEAL::Diff restrict l1: 3.07336e-08 +DEAL::Diff restrict add l1: 3.07336e-08 +DEAL::Diff restrict l2: 1.83328e-07 +DEAL::Diff restrict add l2: 2.05324e-07 +DEAL::Diff restrict l3: 6.59020e-07 +DEAL::Diff restrict add l3: 8.18489e-07 +DEAL::Diff restrict l4: 1.44435e-06 +DEAL::Diff restrict add l4: 1.85608e-06 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 4.05180e-07 +DEAL::Diff prolongate l2: 8.54370e-07 +DEAL::Diff restrict l1: 9.93212e-07 +DEAL::Diff restrict add l1: 1.14004e-06 +DEAL::Diff restrict l2: 1.74876e-06 +DEAL::Diff restrict add l2: 2.16962e-06 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 1.74155e-07 +DEAL::Diff prolongate l2: 5.19866e-07 +DEAL::Diff prolongate l3: 9.61759e-07 +DEAL::Diff restrict l1: 3.23313e-07 +DEAL::Diff restrict add l1: 4.09015e-07 +DEAL::Diff restrict l2: 1.06199e-06 +DEAL::Diff restrict add l2: 1.32974e-06 +DEAL::Diff restrict l3: 2.21171e-06 +DEAL::Diff restrict add l3: 2.64991e-06 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.24189e-07 +DEAL::Diff prolongate l3: 2.63914e-07 +DEAL::Diff prolongate l4: 6.15720e-07 +DEAL::Diff prolongate l5: 1.36740e-06 +DEAL::Diff restrict l1: 1.08965e-07 +DEAL::Diff restrict add l1: 1.08965e-07 +DEAL::Diff restrict l2: 2.46043e-07 +DEAL::Diff restrict add l2: 3.26259e-07 +DEAL::Diff restrict l3: 7.10773e-07 +DEAL::Diff restrict add l3: 7.74864e-07 +DEAL::Diff restrict l4: 1.38466e-06 +DEAL::Diff restrict add l4: 1.63680e-06 +DEAL::Diff restrict l5: 2.98024e-06 +DEAL::Diff restrict add l5: 3.66432e-06 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 1.39089e-07 +DEAL::Diff restrict l1: 3.51210e-07 +DEAL::Diff restrict add l1: 3.51210e-07 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 5.32730e-08 +DEAL::Diff prolongate l2: 3.47201e-07 +DEAL::Diff restrict l1: 2.75424e-07 +DEAL::Diff restrict add l1: 2.75424e-07 +DEAL::Diff restrict l2: 1.37599e-06 +DEAL::Diff restrict add l2: 1.65391e-06 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 8.13494e-07 +DEAL::Diff restrict l1: 2.76829e-06 +DEAL::Diff restrict add l1: 3.07971e-06 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 5.82505e-08 +DEAL::Diff prolongate l2: 5.17285e-07 +DEAL::Diff prolongate l3: 1.42520e-06 +DEAL::Diff restrict l1: 1.60479e-07 +DEAL::Diff restrict add l1: 1.60479e-07 +DEAL::Diff restrict l2: 1.21423e-06 +DEAL::Diff restrict add l2: 1.45209e-06 +DEAL::Diff restrict l3: 4.13711e-06 +DEAL::Diff restrict add l3: 4.50632e-06 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 2.05461e-06 +DEAL::Diff restrict l1: 6.41987e-06 +DEAL::Diff restrict add l1: 7.01234e-06 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 7.72673e-07 +DEAL::Diff prolongate l2: 2.80277e-06 +DEAL::Diff restrict l1: 2.64256e-06 +DEAL::Diff restrict add l1: 3.00814e-06 +DEAL::Diff restrict l2: 8.18270e-06 +DEAL::Diff restrict add l2: 8.99079e-06 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 1.40781e-08 +DEAL::Diff prolongate l2: 3.60453e-07 +DEAL::Diff prolongate l3: 1.41714e-06 +DEAL::Diff prolongate l4: 4.48438e-06 +DEAL::Diff restrict l1: 2.01369e-07 +DEAL::Diff restrict add l1: 2.01369e-07 +DEAL::Diff restrict l2: 1.42552e-06 +DEAL::Diff restrict add l2: 1.66821e-06 +DEAL::Diff restrict l3: 4.00370e-06 +DEAL::Diff restrict add l3: 4.28661e-06 +DEAL::Diff restrict l4: 1.28845e-05 +DEAL::Diff restrict add l4: 1.39500e-05 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_02.cc new file mode 100644 index 0000000000..e6205aac85 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02.cc @@ -0,0 +1,180 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with adaptive meshes for FE_Q + +#include + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference + MGTransferPrebuilt> + transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=1.output new file mode 100644 index 0000000000..2554643d14 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=1.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 5.55112e-17 +DEAL::Diff prolongate l4: 1.46869e-16 +DEAL::Diff prolongate l5: 1.57009e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 1.06489e-15 +DEAL::Diff restrict add l3: 1.08779e-15 +DEAL::Diff restrict l4: 6.28037e-16 +DEAL::Diff restrict add l4: 6.28037e-16 +DEAL::Diff restrict l5: 5.43896e-16 +DEAL::Diff restrict add l5: 7.69185e-16 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 7.85046e-17 +DEAL::Diff prolongate l4: 1.66533e-16 +DEAL::Diff prolongate l5: 2.41967e-16 +DEAL::Diff prolongate l6: 3.92523e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 9.42055e-16 +DEAL::Diff restrict add l3: 9.93014e-16 +DEAL::Diff restrict l4: 4.00297e-16 +DEAL::Diff restrict add l4: 4.44089e-16 +DEAL::Diff restrict l5: 1.13764e-15 +DEAL::Diff restrict add l5: 1.08779e-15 +DEAL::Diff restrict l6: 1.11576e-15 +DEAL::Diff restrict add l6: 1.60119e-15 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 2.22045e-16 +DEAL::Diff prolongate l3: 1.92296e-16 +DEAL::Diff prolongate l4: 4.00297e-16 +DEAL::Diff prolongate l5: 3.26349e-16 +DEAL::Diff restrict l1: 4.96507e-16 +DEAL::Diff restrict add l1: 8.88178e-16 +DEAL::Diff restrict l2: 8.88178e-16 +DEAL::Diff restrict add l2: 9.93014e-16 +DEAL::Diff restrict l3: 9.28879e-16 +DEAL::Diff restrict add l3: 1.08779e-15 +DEAL::Diff restrict l4: 1.58960e-15 +DEAL::Diff restrict add l4: 1.73422e-15 +DEAL::Diff restrict l5: 2.10942e-15 +DEAL::Diff restrict add l5: 2.53170e-15 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 3.87150e-16 +DEAL::Diff prolongate l2: 8.39463e-16 +DEAL::Diff prolongate l3: 1.04489e-15 +DEAL::Diff prolongate l4: 6.84528e-16 +DEAL::Diff restrict l1: 6.28037e-16 +DEAL::Diff restrict add l1: 8.88178e-16 +DEAL::Diff restrict l2: 2.67435e-15 +DEAL::Diff restrict add l2: 2.87803e-15 +DEAL::Diff restrict l3: 3.27845e-15 +DEAL::Diff restrict add l3: 4.18364e-15 +DEAL::Diff restrict l4: 1.71928e-15 +DEAL::Diff restrict add l4: 1.91010e-15 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 2.36534e-16 +DEAL::Diff prolongate l2: 8.41983e-16 +DEAL::Diff prolongate l3: 1.26888e-15 +DEAL::Diff prolongate l4: 1.72555e-15 +DEAL::Diff prolongate l5: 1.18848e-15 +DEAL::Diff restrict l1: 1.25607e-15 +DEAL::Diff restrict add l1: 1.25607e-15 +DEAL::Diff restrict l2: 2.58708e-15 +DEAL::Diff restrict add l2: 2.68298e-15 +DEAL::Diff restrict l3: 3.75399e-15 +DEAL::Diff restrict add l3: 4.21300e-15 +DEAL::Diff restrict l4: 4.85334e-15 +DEAL::Diff restrict add l4: 5.51100e-15 +DEAL::Diff restrict l5: 3.22837e-15 +DEAL::Diff restrict add l5: 3.83951e-15 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 1.38498e-15 +DEAL::Diff prolongate l2: 1.34926e-15 +DEAL::Diff prolongate l3: 1.69608e-15 +DEAL::Diff prolongate l4: 1.56273e-15 +DEAL::Diff restrict l1: 3.77517e-15 +DEAL::Diff restrict add l1: 4.00297e-15 +DEAL::Diff restrict l2: 4.20833e-15 +DEAL::Diff restrict add l2: 4.82404e-15 +DEAL::Diff restrict l3: 5.06973e-15 +DEAL::Diff restrict add l3: 5.63486e-15 +DEAL::Diff restrict l4: 5.06820e-15 +DEAL::Diff restrict add l4: 5.54223e-15 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 2.02658e-16 +DEAL::Diff prolongate l4: 5.37540e-16 +DEAL::Diff prolongate l5: 4.59437e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 8.88178e-16 +DEAL::Diff restrict add l2: 8.88178e-16 +DEAL::Diff restrict l3: 1.96104e-15 +DEAL::Diff restrict add l3: 2.12978e-15 +DEAL::Diff restrict l4: 3.17919e-15 +DEAL::Diff restrict add l4: 3.97205e-15 +DEAL::Diff restrict l5: 3.37661e-15 +DEAL::Diff restrict add l5: 3.97826e-15 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 2.29404e-16 +DEAL::Diff prolongate l2: 3.60822e-16 +DEAL::Diff prolongate l3: 7.51197e-16 +DEAL::Diff prolongate l4: 1.02364e-15 +DEAL::Diff restrict l1: 1.25607e-15 +DEAL::Diff restrict add l1: 1.83103e-15 +DEAL::Diff restrict l2: 2.95411e-15 +DEAL::Diff restrict add l2: 3.14018e-15 +DEAL::Diff restrict l3: 5.89569e-15 +DEAL::Diff restrict add l3: 6.37388e-15 +DEAL::Diff restrict l4: 6.45936e-15 +DEAL::Diff restrict add l4: 7.08110e-15 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 1.07692e-15 +DEAL::Diff prolongate l2: 1.20589e-15 +DEAL::Diff restrict l1: 5.02430e-15 +DEAL::Diff restrict add l1: 4.61511e-15 +DEAL::Diff restrict l2: 6.91131e-15 +DEAL::Diff restrict add l2: 6.76052e-15 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 3.78442e-15 +DEAL::Diff prolongate l2: 5.40000e-15 +DEAL::Diff prolongate l3: 3.66590e-15 +DEAL::Diff restrict l1: 2.62434e-14 +DEAL::Diff restrict add l1: 2.64653e-14 +DEAL::Diff restrict l2: 3.55385e-14 +DEAL::Diff restrict add l2: 3.60157e-14 +DEAL::Diff restrict l3: 2.16938e-14 +DEAL::Diff restrict add l3: 2.19353e-14 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.82947e-07 +DEAL::Diff prolongate l3: 2.73352e-07 +DEAL::Diff prolongate l4: 2.90000e-07 +DEAL::Diff prolongate l5: 2.38384e-07 +DEAL::Diff restrict l1: 1.25729e-07 +DEAL::Diff restrict add l1: 1.25729e-07 +DEAL::Diff restrict l2: 4.51923e-07 +DEAL::Diff restrict add l2: 4.64551e-07 +DEAL::Diff restrict l3: 5.80701e-07 +DEAL::Diff restrict add l3: 7.99297e-07 +DEAL::Diff restrict l4: 6.55915e-07 +DEAL::Diff restrict add l4: 9.76871e-07 +DEAL::Diff restrict l5: 4.91499e-07 +DEAL::Diff restrict add l5: 6.27939e-07 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 3.00343e-08 +DEAL::Diff prolongate l2: 1.06605e-07 +DEAL::Diff prolongate l3: 3.42290e-07 +DEAL::Diff prolongate l4: 3.27767e-07 +DEAL::Diff prolongate l5: 4.72479e-07 +DEAL::Diff prolongate l6: 4.70342e-07 +DEAL::Diff restrict l1: 1.13621e-07 +DEAL::Diff restrict add l1: 1.13621e-07 +DEAL::Diff restrict l2: 3.72885e-07 +DEAL::Diff restrict add l2: 3.82058e-07 +DEAL::Diff restrict l3: 6.77499e-07 +DEAL::Diff restrict add l3: 8.80222e-07 +DEAL::Diff restrict l4: 7.41751e-07 +DEAL::Diff restrict add l4: 1.01957e-06 +DEAL::Diff restrict l5: 8.74257e-07 +DEAL::Diff restrict add l5: 1.11659e-06 +DEAL::Diff restrict l6: 9.89949e-07 +DEAL::Diff restrict add l6: 1.16693e-06 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 2.03307e-07 +DEAL::Diff prolongate l2: 4.70858e-07 +DEAL::Diff prolongate l3: 4.27724e-07 +DEAL::Diff prolongate l4: 5.97569e-07 +DEAL::Diff prolongate l5: 6.83253e-07 +DEAL::Diff restrict l1: 4.87117e-07 +DEAL::Diff restrict add l1: 7.26694e-07 +DEAL::Diff restrict l2: 1.09591e-06 +DEAL::Diff restrict add l2: 1.38195e-06 +DEAL::Diff restrict l3: 9.63365e-07 +DEAL::Diff restrict add l3: 1.11536e-06 +DEAL::Diff restrict l4: 1.13478e-06 +DEAL::Diff restrict add l4: 1.32608e-06 +DEAL::Diff restrict l5: 1.39715e-06 +DEAL::Diff restrict add l5: 1.70729e-06 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 3.02644e-08 +DEAL::Diff prolongate l2: 5.10510e-08 +DEAL::Diff restrict l1: 3.77651e-07 +DEAL::Diff restrict add l1: 3.77651e-07 +DEAL::Diff restrict l2: 4.99556e-07 +DEAL::Diff restrict add l2: 4.99556e-07 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 6.05288e-08 +DEAL::Diff prolongate l2: 2.69857e-07 +DEAL::Diff prolongate l3: 8.37737e-07 +DEAL::Diff prolongate l4: 1.27552e-06 +DEAL::Diff prolongate l5: 1.40443e-06 +DEAL::Diff restrict l1: 6.15662e-07 +DEAL::Diff restrict add l1: 6.15662e-07 +DEAL::Diff restrict l2: 1.21900e-06 +DEAL::Diff restrict add l2: 1.34318e-06 +DEAL::Diff restrict l3: 2.64206e-06 +DEAL::Diff restrict add l3: 2.85523e-06 +DEAL::Diff restrict l4: 3.79070e-06 +DEAL::Diff restrict add l4: 4.12862e-06 +DEAL::Diff restrict l5: 3.57424e-06 +DEAL::Diff restrict add l5: 3.89088e-06 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 8.63082e-07 +DEAL::Diff prolongate l2: 1.02885e-06 +DEAL::Diff prolongate l3: 1.86363e-06 +DEAL::Diff prolongate l4: 2.64187e-06 +DEAL::Diff restrict l1: 2.70130e-06 +DEAL::Diff restrict add l1: 2.81647e-06 +DEAL::Diff restrict l2: 3.09755e-06 +DEAL::Diff restrict add l2: 3.25362e-06 +DEAL::Diff restrict l3: 4.73380e-06 +DEAL::Diff restrict add l3: 5.08899e-06 +DEAL::Diff restrict l4: 6.73984e-06 +DEAL::Diff restrict add l4: 7.45000e-06 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..98d496e2cf --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.11022e-16 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 5.55112e-17 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 4.44089e-16 +DEAL::Diff restrict add l3: 4.44089e-16 +DEAL::Diff restrict l4: 6.75322e-16 +DEAL::Diff restrict add l4: 6.66134e-16 +DEAL::Diff restrict l5: 4.00297e-16 +DEAL::Diff restrict add l5: 4.44089e-16 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 5.55112e-17 +DEAL::Diff prolongate l4: 9.61481e-17 +DEAL::Diff prolongate l5: 1.92296e-16 +DEAL::Diff prolongate l6: 2.09665e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 5.87475e-16 +DEAL::Diff restrict add l3: 6.28037e-16 +DEAL::Diff restrict l4: 3.33067e-16 +DEAL::Diff restrict add l4: 4.96507e-16 +DEAL::Diff restrict l5: 8.75951e-16 +DEAL::Diff restrict add l5: 1.13221e-15 +DEAL::Diff restrict l6: 1.49365e-15 +DEAL::Diff restrict add l6: 1.53837e-15 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.92296e-16 +DEAL::Diff prolongate l3: 2.09550e-16 +DEAL::Diff prolongate l4: 3.18887e-16 +DEAL::Diff prolongate l5: 3.14325e-16 +DEAL::Diff restrict l1: 4.96507e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 1.17495e-15 +DEAL::Diff restrict add l2: 1.17495e-15 +DEAL::Diff restrict l3: 1.15911e-15 +DEAL::Diff restrict add l3: 1.35064e-15 +DEAL::Diff restrict l4: 1.20089e-15 +DEAL::Diff restrict add l4: 1.61651e-15 +DEAL::Diff restrict l5: 1.72353e-15 +DEAL::Diff restrict add l5: 1.94843e-15 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 2.93415e-16 +DEAL::Diff prolongate l2: 1.12179e-15 +DEAL::Diff prolongate l3: 8.90270e-16 +DEAL::Diff prolongate l4: 9.68765e-16 +DEAL::Diff restrict l1: 7.69185e-16 +DEAL::Diff restrict add l1: 8.88178e-16 +DEAL::Diff restrict l2: 2.12398e-15 +DEAL::Diff restrict add l2: 1.67640e-15 +DEAL::Diff restrict l3: 1.93335e-15 +DEAL::Diff restrict add l3: 1.99840e-15 +DEAL::Diff restrict l4: 1.65070e-15 +DEAL::Diff restrict add l4: 1.79018e-15 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 4.19100e-16 +DEAL::Diff prolongate l2: 7.23163e-16 +DEAL::Diff prolongate l3: 1.49879e-15 +DEAL::Diff prolongate l4: 1.67926e-15 +DEAL::Diff prolongate l5: 1.34221e-15 +DEAL::Diff restrict l1: 3.84593e-16 +DEAL::Diff restrict add l1: 6.28037e-16 +DEAL::Diff restrict l2: 1.88738e-15 +DEAL::Diff restrict add l2: 1.99840e-15 +DEAL::Diff restrict l3: 3.40071e-15 +DEAL::Diff restrict add l3: 3.43990e-15 +DEAL::Diff restrict l4: 3.82627e-15 +DEAL::Diff restrict add l4: 3.64180e-15 +DEAL::Diff restrict l5: 3.84392e-15 +DEAL::Diff restrict add l5: 4.40746e-15 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 1.54021e-15 +DEAL::Diff prolongate l2: 1.55808e-15 +DEAL::Diff prolongate l3: 2.01813e-15 +DEAL::Diff prolongate l4: 1.80659e-15 +DEAL::Diff restrict l1: 3.42779e-15 +DEAL::Diff restrict add l1: 3.95962e-15 +DEAL::Diff restrict l2: 3.98735e-15 +DEAL::Diff restrict add l2: 4.56138e-15 +DEAL::Diff restrict l3: 4.36875e-15 +DEAL::Diff restrict add l3: 5.08283e-15 +DEAL::Diff restrict l4: 4.48817e-15 +DEAL::Diff restrict add l4: 5.31053e-15 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 2.18548e-16 +DEAL::Diff prolongate l4: 4.49062e-16 +DEAL::Diff prolongate l5: 5.55805e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 2.03507e-15 +DEAL::Diff restrict add l3: 2.03507e-15 +DEAL::Diff restrict l4: 3.29345e-15 +DEAL::Diff restrict add l4: 3.46845e-15 +DEAL::Diff restrict l5: 2.99760e-15 +DEAL::Diff restrict add l5: 3.68888e-15 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 2.60370e-16 +DEAL::Diff prolongate l2: 4.20018e-16 +DEAL::Diff prolongate l3: 6.98592e-16 +DEAL::Diff prolongate l4: 1.25803e-15 +DEAL::Diff restrict l1: 1.25607e-15 +DEAL::Diff restrict add l1: 9.93014e-16 +DEAL::Diff restrict l2: 2.22045e-15 +DEAL::Diff restrict add l2: 2.39149e-15 +DEAL::Diff restrict l3: 3.57347e-15 +DEAL::Diff restrict add l3: 3.60780e-15 +DEAL::Diff restrict l4: 5.93424e-15 +DEAL::Diff restrict add l4: 7.19164e-15 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 6.25665e-16 +DEAL::Diff prolongate l2: 1.12982e-15 +DEAL::Diff restrict l1: 3.07674e-15 +DEAL::Diff restrict add l1: 2.80867e-15 +DEAL::Diff restrict l2: 7.89196e-15 +DEAL::Diff restrict add l2: 8.16448e-15 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 4.47538e-15 +DEAL::Diff prolongate l2: 6.65118e-15 +DEAL::Diff prolongate l3: 4.28755e-15 +DEAL::Diff restrict l1: 2.07451e-14 +DEAL::Diff restrict add l1: 2.17150e-14 +DEAL::Diff restrict l2: 2.76721e-14 +DEAL::Diff restrict add l2: 2.85472e-14 +DEAL::Diff restrict l3: 2.07301e-14 +DEAL::Diff restrict add l3: 2.14859e-14 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 1.53598e-08 +DEAL::Diff prolongate l2: 1.32451e-07 +DEAL::Diff prolongate l3: 2.77478e-07 +DEAL::Diff prolongate l4: 2.43327e-07 +DEAL::Diff prolongate l5: 1.99307e-07 +DEAL::Diff restrict l1: 1.55531e-07 +DEAL::Diff restrict add l1: 1.55531e-07 +DEAL::Diff restrict l2: 1.80699e-07 +DEAL::Diff restrict add l2: 2.68656e-07 +DEAL::Diff restrict l3: 5.31998e-07 +DEAL::Diff restrict add l3: 6.10878e-07 +DEAL::Diff restrict l4: 6.72091e-07 +DEAL::Diff restrict add l4: 7.96976e-07 +DEAL::Diff restrict l5: 4.78152e-07 +DEAL::Diff restrict add l5: 6.10737e-07 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 9.31323e-09 +DEAL::Diff prolongate l2: 1.14023e-07 +DEAL::Diff prolongate l3: 3.02950e-07 +DEAL::Diff prolongate l4: 3.31972e-07 +DEAL::Diff prolongate l5: 4.83178e-07 +DEAL::Diff prolongate l6: 4.49200e-07 +DEAL::Diff restrict l1: 1.00117e-08 +DEAL::Diff restrict add l1: 1.00117e-08 +DEAL::Diff restrict l2: 3.03629e-07 +DEAL::Diff restrict add l2: 3.35049e-07 +DEAL::Diff restrict l3: 6.96781e-07 +DEAL::Diff restrict add l3: 9.83613e-07 +DEAL::Diff restrict l4: 6.53890e-07 +DEAL::Diff restrict add l4: 7.96383e-07 +DEAL::Diff restrict l5: 1.05105e-06 +DEAL::Diff restrict add l5: 1.35094e-06 +DEAL::Diff restrict l6: 9.63780e-07 +DEAL::Diff restrict add l6: 1.22002e-06 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 1.96297e-07 +DEAL::Diff prolongate l2: 4.29379e-07 +DEAL::Diff prolongate l3: 3.78592e-07 +DEAL::Diff prolongate l4: 5.48624e-07 +DEAL::Diff prolongate l5: 7.03000e-07 +DEAL::Diff restrict l1: 3.35044e-07 +DEAL::Diff restrict add l1: 3.89982e-07 +DEAL::Diff restrict l2: 1.15122e-06 +DEAL::Diff restrict add l2: 1.32525e-06 +DEAL::Diff restrict l3: 1.00435e-06 +DEAL::Diff restrict add l3: 1.22192e-06 +DEAL::Diff restrict l4: 1.23935e-06 +DEAL::Diff restrict add l4: 1.47309e-06 +DEAL::Diff restrict l5: 1.32602e-06 +DEAL::Diff restrict add l5: 1.91723e-06 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 1.05367e-08 +DEAL::Diff prolongate l2: 1.17397e-07 +DEAL::Diff restrict l1: 2.84635e-07 +DEAL::Diff restrict add l1: 2.84635e-07 +DEAL::Diff restrict l2: 5.41568e-07 +DEAL::Diff restrict add l2: 8.78831e-07 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 1.39089e-07 +DEAL::Diff prolongate l2: 3.79811e-07 +DEAL::Diff prolongate l3: 1.01625e-06 +DEAL::Diff prolongate l4: 1.27553e-06 +DEAL::Diff prolongate l5: 1.29250e-06 +DEAL::Diff restrict l1: 1.37952e-07 +DEAL::Diff restrict add l1: 1.37952e-07 +DEAL::Diff restrict l2: 1.18038e-06 +DEAL::Diff restrict add l2: 1.25114e-06 +DEAL::Diff restrict l3: 2.41311e-06 +DEAL::Diff restrict add l3: 2.66759e-06 +DEAL::Diff restrict l4: 3.55824e-06 +DEAL::Diff restrict add l4: 3.81845e-06 +DEAL::Diff restrict l5: 3.73363e-06 +DEAL::Diff restrict add l5: 4.00464e-06 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 9.71673e-07 +DEAL::Diff prolongate l2: 1.00927e-06 +DEAL::Diff prolongate l3: 1.78966e-06 +DEAL::Diff prolongate l4: 2.55606e-06 +DEAL::Diff restrict l1: 2.80919e-06 +DEAL::Diff restrict add l1: 2.85094e-06 +DEAL::Diff restrict l2: 2.81573e-06 +DEAL::Diff restrict add l2: 3.01700e-06 +DEAL::Diff restrict l3: 4.79409e-06 +DEAL::Diff restrict add l3: 5.48025e-06 +DEAL::Diff restrict l4: 6.45920e-06 +DEAL::Diff restrict add l4: 7.19753e-06 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.cc new file mode 100644 index 0000000000..2d158b78cc --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.cc @@ -0,0 +1,200 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferBlockMatrixFree by comparison with MGTransferMatrixFree on a +// series of adaptive meshes for FE_Q. This is, essentially, a +// copy-paste of transfer_matrix_free_02.cc + +#include + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference + MGTransferMF transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferBlockMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + const unsigned int nb = 3; + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::BlockVector v1(nb), v2(nb), + v3(nb); + for (unsigned int b = 0; b < nb; ++b) + { + v1.block(b).reinit(mgdof.locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + v2.block(b).reinit(mgdof.locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + v3.block(b).reinit(mgdof.locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + + for (unsigned int i = 0; i < v1.block(b).locally_owned_size(); + ++i) + v1.block(b).local_element(i) = random_value(); + + transfer_ref.prolongate(level, v2.block(b), v1.block(b)); + } + + transfer.prolongate(level, v3, v1); + v3 -= v2; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::BlockVector v1(nb), v2(nb), + v3(nb); + for (unsigned int b = 0; b < nb; ++b) + { + v1.block(b).reinit(mgdof.locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + v2.block(b).reinit(mgdof.locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + v3.block(b).reinit(mgdof.locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + + for (unsigned int i = 0; i < v1.block(b).locally_owned_size(); + ++i) + v1.block(b).local_element(i) = random_value(); + + transfer_ref.restrict_and_add(level, v2.block(b), v1.block(b)); + } + + transfer.restrict_and_add(level, v3, v1); + v3 -= v2; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + for (unsigned int b = 0; b < nb; ++b) + transfer_ref.restrict_and_add(level, v3.block(b), v1.block(b)); + v3 -= v2; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..40a816017d --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff prolongate l6: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL::Diff restrict l6: 0 +DEAL::Diff restrict add l6: 0 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff prolongate l6: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL::Diff restrict l6: 0 +DEAL::Diff restrict add l6: 0 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff prolongate l5: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL::Diff restrict l5: 0 +DEAL::Diff restrict add l5: 0 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0 +DEAL::Diff prolongate l2: 0 +DEAL::Diff prolongate l3: 0 +DEAL::Diff prolongate l4: 0 +DEAL::Diff restrict l1: 0 +DEAL::Diff restrict add l1: 0 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL::Diff restrict l3: 0 +DEAL::Diff restrict add l3: 0 +DEAL::Diff restrict l4: 0 +DEAL::Diff restrict add l4: 0 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.cc new file mode 100644 index 0000000000..7ede5f71af --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.cc @@ -0,0 +1,218 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferBlockMatrixFree by comparison with MGTransferMatrixFree on a +// series of adaptive meshes for FE_Q. This is similar to +// transfer_matrix_free_02.cc but using separate DoFHandlers for each block. + +#include + +#include + +#include + +#include + +#include + +#include +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + const unsigned int nb = 2; + + FE_Q fe_1(fe_degree + 1); + FE_Q fe_2(fe_degree); + + deallog << "FE: " << fe_1.get_name() << std::endl; + deallog << "FE: " << fe_2.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof_1(tr); + mgdof_1.distribute_dofs(fe_1); + mgdof_1.distribute_mg_dofs(); + + DoFHandler mgdof_2(tr); + mgdof_2.distribute_dofs(fe_2); + mgdof_2.distribute_mg_dofs(); + + const std::vector *> mgdof_ptr{&mgdof_1, &mgdof_2}; + + std::vector mg_constrained_dofs_vector(2); + for (unsigned int i = 0; i < mgdof_ptr.size(); ++i) + { + mg_constrained_dofs_vector[i].initialize(*mgdof_ptr[i]); + mg_constrained_dofs_vector[i].make_zero_boundary_constraints( + *mgdof_ptr[i], {0}); + } + + // build reference + std::vector> transfer_ref; + for (unsigned int b = 0; b < nb; ++b) + { + transfer_ref.emplace_back(mg_constrained_dofs_vector[b]); + transfer_ref[b].build(*mgdof_ptr[b]); + } + + // build matrix-free transfer + MGTransferBlockMF transfer(mg_constrained_dofs_vector); + transfer.build(mgdof_ptr); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof_ptr[0]->get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::BlockVector v1(nb), v2(nb), + v3(nb); + for (unsigned int b = 0; b < nb; ++b) + { + v1.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + v2.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + v3.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + + for (unsigned int i = 0; i < v1.block(b).locally_owned_size(); + ++i) + v1.block(b).local_element(i) = random_value(); + + transfer_ref[b].prolongate(level, v2.block(b), v1.block(b)); + } + + transfer.prolongate(level, v3, v1); + v3 -= v2; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof_ptr[0]->get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::BlockVector v1(nb), v2(nb), + v3(nb); + for (unsigned int b = 0; b < nb; ++b) + { + v1.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level), + MPI_COMM_WORLD); + v2.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + v3.block(b).reinit(mgdof_ptr[b]->locally_owned_mg_dofs(level - 1), + MPI_COMM_WORLD); + + for (unsigned int i = 0; i < v1.block(b).locally_owned_size(); + ++i) + v1.block(b).local_element(i) = random_value(); + + transfer_ref[b].restrict_and_add(level, v2.block(b), v1.block(b)); + } + + transfer.restrict_and_add(level, v3, v1); + v3 -= v2; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + for (unsigned int b = 0; b < nb; ++b) + transfer_ref[b].restrict_and_add(level, v3.block(b), v1.block(b)); + v3 -= v2; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..62ed8e7064 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_02_block_02.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,265 @@ + +DEAL::FE: FE_Q<2>(2) +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(4) +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(4) +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_03.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_03.cc new file mode 100644 index 0000000000..0a5d1b2cfb --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_03.cc @@ -0,0 +1,154 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with adaptive meshes for FE_Q (similar to +// transfer_matrix_free_02 but on a different mesh refining into a corner) + +#include + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, 3); + for (unsigned int cycle = 0; cycle < (dim == 2 ? 10 : 7); ++cycle) + { + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->vertex(0).norm() < 1e-10) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << " on " + << tr.n_global_levels() << " levels" << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference + MGTransferPrebuilt> + transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + const Number tolerance = 1000. * std::numeric_limits::epsilon(); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_03.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_03.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..7034cc01ff --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_03.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,856 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 12 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 15 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 18 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 21 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 24 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 27 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 30 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: +DEAL::no. cells: 33 on 9 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL:: +DEAL::no. cells: 36 on 10 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL:: +DEAL::no. cells: 39 on 11 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff prolongate l10: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL::Diff restrict l10: 0.00000 +DEAL::Diff restrict add l10: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(3) +DEAL::no. cells: 12 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 15 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 18 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 21 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 24 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 27 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 30 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: +DEAL::no. cells: 33 on 9 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL:: +DEAL::no. cells: 36 on 10 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL:: +DEAL::no. cells: 39 on 11 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff prolongate l10: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL::Diff restrict l10: 0.00000 +DEAL::Diff restrict add l10: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 34 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 41 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 48 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 55 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 62 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 69 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 76 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(3) +DEAL::no. cells: 34 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 41 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 48 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 55 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 62 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 69 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 76 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 12 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 15 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 18 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 21 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 24 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 27 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 30 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: +DEAL::no. cells: 33 on 9 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL:: +DEAL::no. cells: 36 on 10 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL:: +DEAL::no. cells: 39 on 11 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff prolongate l8: 0.00000 +DEAL::Diff prolongate l9: 0.00000 +DEAL::Diff prolongate l10: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL::Diff restrict l8: 0.00000 +DEAL::Diff restrict add l8: 0.00000 +DEAL::Diff restrict l9: 0.00000 +DEAL::Diff restrict add l9: 0.00000 +DEAL::Diff restrict l10: 0.00000 +DEAL::Diff restrict add l10: 0.00000 +DEAL:: +DEAL::FE: FE_Q<3>(2) +DEAL::no. cells: 34 on 2 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 41 on 3 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 48 on 4 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 55 on 5 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 62 on 6 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 69 on 7 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 76 on 8 levels +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff prolongate l7: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL::Diff restrict l7: 0.00000 +DEAL::Diff restrict add l7: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_04.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_04.cc new file mode 100644 index 0000000000..e5adc27462 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_04.cc @@ -0,0 +1,161 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with uniform meshes for FE_DGQ (except for the different +// element and no constraints the same test as transfer_matrix_free_01) + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_DGQ fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3, 4, 5, 6, 8}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + // build reference + MGTransferPrebuilt> + transfer_ref; + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer; + transfer.build(mgdof); + + const Number tolerance = 1000. * std::numeric_limits::epsilon(); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + IndexSet relevant_set; + DoFTools::extract_locally_relevant_level_dofs(mgdof, + level, + relevant_set); + v2.reinit(mgdof.locally_owned_mg_dofs(level), + relevant_set, + MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + deallog << "Vectors have ghosts: " << v2.has_ghost_elements() << ' ' + << v3.has_ghost_elements() << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=1.output new file mode 100644 index 0000000000..c126ad7c87 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=1.output @@ -0,0 +1,455 @@ + +DEAL::FE: FE_DGQ<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 3.02285e-13 +DEAL::Diff restrict add l3: 3.02551e-13 +DEAL:: +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=4.output b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=4.output new file mode 100644 index 0000000000..c126ad7c87 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=4.output @@ -0,0 +1,455 @@ + +DEAL::FE: FE_DGQ<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 3.02285e-13 +DEAL::Diff restrict add l3: 3.02551e-13 +DEAL:: +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=7.output b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=7.output new file mode 100644 index 0000000000..c126ad7c87 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_04.with_p4est=true.with_trilinos=true.mpirun=7.output @@ -0,0 +1,455 @@ + +DEAL::FE: FE_DGQ<2>(1) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 4 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 36 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 100 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(1) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 27 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 125 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 3.02285e-13 +DEAL::Diff restrict add l3: 3.02551e-13 +DEAL:: +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 16 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 144 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 256 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 400 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 576 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1024 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(2) +DEAL::no. cells: 8 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 64 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 216 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 512 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::no. cells: 1000 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL:: +DEAL::no. cells: 1728 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 4096 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Vectors have ghosts: 0 0 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_05.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_05.cc new file mode 100644 index 0000000000..8aef5d8611 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_05.cc @@ -0,0 +1,180 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with adaptive meshes for FE_DGQ (except for the different +// element and no constraints the same test as transfer_matrix_free_01) + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_DGQ fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + // build reference + MGTransferPrebuilt> + transfer_ref; + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer; + transfer.build(mgdof); + + const Number tolerance = 1000. * std::numeric_limits::epsilon(); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " + << filter_out_small_numbers(v3.l2_norm(), tolerance) + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=1.output new file mode 100644 index 0000000000..5777a0a2e6 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=1.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_DGQ<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..5777a0a2e6 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_05.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_DGQ<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff prolongate l6: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL::Diff restrict l6: 0.00000 +DEAL::Diff restrict add l6: 0.00000 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::FE: FE_DGQ<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff prolongate l5: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL::Diff restrict l5: 0.00000 +DEAL::Diff restrict add l5: 0.00000 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 0.00000 +DEAL::Diff prolongate l4: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 0.00000 +DEAL::Diff restrict add l3: 0.00000 +DEAL::Diff restrict l4: 0.00000 +DEAL::Diff restrict add l4: 0.00000 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_06.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_06.cc new file mode 100644 index 0000000000..932fb3b769 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_06.cc @@ -0,0 +1,182 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with adaptive meshes for FESystem(FE_Q,2). Same as +// transfer_matrix_free_02 but using two components (and fewer meshes). + +#include + +#include + +#include +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FESystem fe(FE_Q(fe_degree), 2); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 6 - 2 * dim; + if (fe_degree == 1) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + // build reference + MGTransferPrebuilt> + transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=10.output b/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=10.output new file mode 100644 index 0000000000..2f9f6a1437 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=10.output @@ -0,0 +1,169 @@ + +DEAL::FE: FESystem<2>[FE_Q<2>(1)^2] +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.92296e-16 +DEAL::Diff prolongate l4: 1.57009e-16 +DEAL::Diff prolongate l5: 4.04127e-16 +DEAL::Diff prolongate l6: 3.12789e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 1.08779e-15 +DEAL::Diff restrict add l3: 1.17495e-15 +DEAL::Diff restrict l4: 1.23629e-15 +DEAL::Diff restrict add l4: 1.25607e-15 +DEAL::Diff restrict l5: 1.52226e-15 +DEAL::Diff restrict add l5: 1.77636e-15 +DEAL::Diff restrict l6: 1.80390e-15 +DEAL::Diff restrict add l6: 2.28609e-15 +DEAL:: +DEAL::no. cells: 868 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 5.55112e-17 +DEAL::Diff prolongate l4: 3.68219e-16 +DEAL::Diff prolongate l5: 4.02217e-16 +DEAL::Diff prolongate l6: 5.88130e-16 +DEAL::Diff prolongate l7: 6.83331e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 0.00000 +DEAL::Diff restrict add l2: 0.00000 +DEAL::Diff restrict l3: 9.67870e-16 +DEAL::Diff restrict add l3: 9.93014e-16 +DEAL::Diff restrict l4: 2.38116e-15 +DEAL::Diff restrict add l4: 2.48253e-15 +DEAL::Diff restrict l5: 2.18970e-15 +DEAL::Diff restrict add l5: 2.55110e-15 +DEAL::Diff restrict l6: 2.51705e-15 +DEAL::Diff restrict add l6: 3.00376e-15 +DEAL::Diff restrict l7: 3.57390e-15 +DEAL::Diff restrict add l7: 3.91580e-15 +DEAL:: +DEAL::FE: FESystem<2>[FE_Q<2>(3)^2] +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 1.19375e-15 +DEAL::Diff prolongate l2: 2.65120e-15 +DEAL::Diff prolongate l3: 4.51475e-15 +DEAL::Diff prolongate l4: 5.36184e-15 +DEAL::Diff prolongate l5: 4.26321e-15 +DEAL::Diff restrict l1: 1.93574e-15 +DEAL::Diff restrict add l1: 2.03507e-15 +DEAL::Diff restrict l2: 5.61733e-15 +DEAL::Diff restrict add l2: 6.25283e-15 +DEAL::Diff restrict l3: 8.89530e-15 +DEAL::Diff restrict add l3: 9.36017e-15 +DEAL::Diff restrict l4: 1.09472e-14 +DEAL::Diff restrict add l4: 1.09665e-14 +DEAL::Diff restrict l5: 8.06786e-15 +DEAL::Diff restrict add l5: 8.16750e-15 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 1.04513e-15 +DEAL::Diff prolongate l2: 2.59807e-15 +DEAL::Diff prolongate l3: 5.95414e-15 +DEAL::Diff prolongate l4: 6.00254e-15 +DEAL::Diff prolongate l5: 8.39305e-15 +DEAL::Diff prolongate l6: 8.37666e-15 +DEAL::Diff restrict l1: 2.51215e-15 +DEAL::Diff restrict add l1: 3.20237e-15 +DEAL::Diff restrict l2: 6.21923e-15 +DEAL::Diff restrict add l2: 6.46985e-15 +DEAL::Diff restrict l3: 1.30151e-14 +DEAL::Diff restrict add l3: 1.42247e-14 +DEAL::Diff restrict l4: 1.26215e-14 +DEAL::Diff restrict add l4: 1.28133e-14 +DEAL::Diff restrict l5: 1.56220e-14 +DEAL::Diff restrict add l5: 1.64807e-14 +DEAL::Diff restrict l6: 1.56927e-14 +DEAL::Diff restrict add l6: 1.66947e-14 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(1)^2] +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 3.14018e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 5.55112e-17 +DEAL::Diff prolongate l3: 4.45173e-16 +DEAL::Diff prolongate l4: 5.76095e-16 +DEAL::Diff prolongate l5: 8.29336e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 8.88178e-16 +DEAL::Diff restrict add l2: 8.88178e-16 +DEAL::Diff restrict l3: 2.02292e-15 +DEAL::Diff restrict add l3: 2.22045e-15 +DEAL::Diff restrict l4: 3.95027e-15 +DEAL::Diff restrict add l4: 4.19541e-15 +DEAL::Diff restrict l5: 4.67350e-15 +DEAL::Diff restrict add l5: 5.25453e-15 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(3)^2] +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 7.45167e-15 +DEAL::Diff prolongate l2: 8.99804e-15 +DEAL::Diff restrict l1: 2.31609e-14 +DEAL::Diff restrict add l1: 2.25394e-14 +DEAL::Diff restrict l2: 3.06553e-14 +DEAL::Diff restrict add l2: 3.12389e-14 +DEAL:: +DEAL::FE: FESystem<2>[FE_Q<2>(2)^2] +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 6.86910e-08 +DEAL::Diff prolongate l2: 1.77133e-07 +DEAL::Diff prolongate l3: 3.21812e-07 +DEAL::Diff prolongate l4: 4.07741e-07 +DEAL::Diff prolongate l5: 3.15483e-07 +DEAL::Diff restrict l1: 8.43965e-08 +DEAL::Diff restrict add l1: 3.78172e-07 +DEAL::Diff restrict l2: 4.04207e-07 +DEAL::Diff restrict add l2: 5.76620e-07 +DEAL::Diff restrict l3: 7.63684e-07 +DEAL::Diff restrict add l3: 9.19822e-07 +DEAL::Diff restrict l4: 9.23719e-07 +DEAL::Diff restrict add l4: 1.08789e-06 +DEAL::Diff restrict l5: 7.03670e-07 +DEAL::Diff restrict add l5: 9.16036e-07 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 7.48774e-08 +DEAL::Diff prolongate l2: 1.80284e-07 +DEAL::Diff prolongate l3: 4.12573e-07 +DEAL::Diff prolongate l4: 4.89806e-07 +DEAL::Diff prolongate l5: 7.08827e-07 +DEAL::Diff prolongate l6: 6.86261e-07 +DEAL::Diff restrict l1: 4.86098e-08 +DEAL::Diff restrict add l1: 4.86098e-08 +DEAL::Diff restrict l2: 4.41927e-07 +DEAL::Diff restrict add l2: 4.56242e-07 +DEAL::Diff restrict l3: 8.35079e-07 +DEAL::Diff restrict add l3: 1.19002e-06 +DEAL::Diff restrict l4: 1.03492e-06 +DEAL::Diff restrict add l4: 1.30417e-06 +DEAL::Diff restrict l5: 1.26083e-06 +DEAL::Diff restrict add l5: 1.66426e-06 +DEAL::Diff restrict l6: 1.45183e-06 +DEAL::Diff restrict add l6: 1.82397e-06 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(2)^2] +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 7.18146e-08 +DEAL::Diff prolongate l2: 2.81848e-07 +DEAL::Diff restrict l1: 1.78137e-07 +DEAL::Diff restrict add l1: 1.78137e-07 +DEAL::Diff restrict l2: 5.02891e-07 +DEAL::Diff restrict add l2: 5.02891e-07 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..4423d36c4e --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_06.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,169 @@ + +DEAL::FE: FESystem<2>[FE_Q<2>(1)^2] +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 9.61481e-17 +DEAL::Diff prolongate l4: 2.54384e-16 +DEAL::Diff prolongate l5: 2.97645e-16 +DEAL::Diff prolongate l6: 3.06884e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 1.08779e-15 +DEAL::Diff restrict add l3: 1.08779e-15 +DEAL::Diff restrict l4: 1.02958e-15 +DEAL::Diff restrict add l4: 9.42055e-16 +DEAL::Diff restrict l5: 1.62032e-15 +DEAL::Diff restrict add l5: 1.89715e-15 +DEAL::Diff restrict l6: 1.36877e-15 +DEAL::Diff restrict add l6: 1.58572e-15 +DEAL:: +DEAL::no. cells: 868 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff prolongate l3: 1.24127e-16 +DEAL::Diff prolongate l4: 2.93737e-16 +DEAL::Diff prolongate l5: 3.78536e-16 +DEAL::Diff prolongate l6: 4.20991e-16 +DEAL::Diff prolongate l7: 7.17496e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 4.44089e-16 +DEAL::Diff restrict l3: 1.29948e-15 +DEAL::Diff restrict add l3: 1.53837e-15 +DEAL::Diff restrict l4: 2.39149e-15 +DEAL::Diff restrict add l4: 2.73755e-15 +DEAL::Diff restrict l5: 2.31289e-15 +DEAL::Diff restrict add l5: 2.52194e-15 +DEAL::Diff restrict l6: 2.37663e-15 +DEAL::Diff restrict add l6: 2.86084e-15 +DEAL::Diff restrict l7: 3.38936e-15 +DEAL::Diff restrict add l7: 3.79430e-15 +DEAL:: +DEAL::FE: FESystem<2>[FE_Q<2>(3)^2] +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 1.24251e-15 +DEAL::Diff prolongate l2: 2.69354e-15 +DEAL::Diff prolongate l3: 4.71393e-15 +DEAL::Diff prolongate l4: 5.25000e-15 +DEAL::Diff prolongate l5: 4.24784e-15 +DEAL::Diff restrict l1: 3.10862e-15 +DEAL::Diff restrict add l1: 3.29345e-15 +DEAL::Diff restrict l2: 4.53980e-15 +DEAL::Diff restrict add l2: 5.00955e-15 +DEAL::Diff restrict l3: 8.75679e-15 +DEAL::Diff restrict add l3: 8.96466e-15 +DEAL::Diff restrict l4: 9.88904e-15 +DEAL::Diff restrict add l4: 9.94006e-15 +DEAL::Diff restrict l5: 8.14781e-15 +DEAL::Diff restrict add l5: 8.59115e-15 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 1.23403e-15 +DEAL::Diff prolongate l2: 2.59030e-15 +DEAL::Diff prolongate l3: 6.19756e-15 +DEAL::Diff prolongate l4: 5.86430e-15 +DEAL::Diff prolongate l5: 8.02510e-15 +DEAL::Diff prolongate l6: 7.89235e-15 +DEAL::Diff restrict l1: 2.04715e-15 +DEAL::Diff restrict add l1: 2.73755e-15 +DEAL::Diff restrict l2: 6.29801e-15 +DEAL::Diff restrict add l2: 6.23704e-15 +DEAL::Diff restrict l3: 1.33072e-14 +DEAL::Diff restrict add l3: 1.33171e-14 +DEAL::Diff restrict l4: 1.26068e-14 +DEAL::Diff restrict add l4: 1.29130e-14 +DEAL::Diff restrict l5: 1.74281e-14 +DEAL::Diff restrict add l5: 1.78908e-14 +DEAL::Diff restrict l6: 1.64922e-14 +DEAL::Diff restrict add l6: 1.73113e-14 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(1)^2] +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 0.00000 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 3.14018e-16 +DEAL::Diff restrict add l2: 0.00000 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 0.00000 +DEAL::Diff prolongate l2: 1.14439e-16 +DEAL::Diff prolongate l3: 4.48405e-16 +DEAL::Diff prolongate l4: 6.43898e-16 +DEAL::Diff prolongate l5: 7.94566e-16 +DEAL::Diff restrict l1: 0.00000 +DEAL::Diff restrict add l1: 0.00000 +DEAL::Diff restrict l2: 4.44089e-16 +DEAL::Diff restrict add l2: 8.88178e-16 +DEAL::Diff restrict l3: 2.38116e-15 +DEAL::Diff restrict add l3: 2.73755e-15 +DEAL::Diff restrict l4: 4.36248e-15 +DEAL::Diff restrict add l4: 4.39626e-15 +DEAL::Diff restrict l5: 4.33982e-15 +DEAL::Diff restrict add l5: 4.80356e-15 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(3)^2] +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 6.10586e-15 +DEAL::Diff prolongate l2: 9.12753e-15 +DEAL::Diff restrict l1: 2.16468e-14 +DEAL::Diff restrict add l1: 2.17558e-14 +DEAL::Diff restrict l2: 3.10285e-14 +DEAL::Diff restrict add l2: 3.09280e-14 +DEAL:: +DEAL::FE: FESystem<2>[FE_Q<2>(2)^2] +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 3.75428e-08 +DEAL::Diff prolongate l2: 1.73474e-07 +DEAL::Diff prolongate l3: 4.06743e-07 +DEAL::Diff prolongate l4: 4.56267e-07 +DEAL::Diff prolongate l5: 3.02844e-07 +DEAL::Diff restrict l1: 7.83696e-08 +DEAL::Diff restrict add l1: 7.83696e-08 +DEAL::Diff restrict l2: 4.84892e-07 +DEAL::Diff restrict add l2: 4.84892e-07 +DEAL::Diff restrict l3: 6.33157e-07 +DEAL::Diff restrict add l3: 8.51716e-07 +DEAL::Diff restrict l4: 7.38227e-07 +DEAL::Diff restrict add l4: 1.08434e-06 +DEAL::Diff restrict l5: 7.53959e-07 +DEAL::Diff restrict add l5: 9.85545e-07 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 3.80021e-08 +DEAL::Diff prolongate l2: 2.05445e-07 +DEAL::Diff prolongate l3: 4.23083e-07 +DEAL::Diff prolongate l4: 4.60938e-07 +DEAL::Diff prolongate l5: 6.34151e-07 +DEAL::Diff prolongate l6: 6.66574e-07 +DEAL::Diff restrict l1: 1.51135e-07 +DEAL::Diff restrict add l1: 1.51135e-07 +DEAL::Diff restrict l2: 4.39691e-07 +DEAL::Diff restrict add l2: 4.99465e-07 +DEAL::Diff restrict l3: 9.43038e-07 +DEAL::Diff restrict add l3: 1.07123e-06 +DEAL::Diff restrict l4: 1.06518e-06 +DEAL::Diff restrict add l4: 1.22748e-06 +DEAL::Diff restrict l5: 1.29055e-06 +DEAL::Diff restrict add l5: 1.51964e-06 +DEAL::Diff restrict l6: 1.36762e-06 +DEAL::Diff restrict add l6: 1.82467e-06 +DEAL:: +DEAL::FE: FESystem<3>[FE_Q<3>(2)^2] +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 6.46984e-08 +DEAL::Diff prolongate l2: 2.68654e-07 +DEAL::Diff restrict l1: 3.14590e-07 +DEAL::Diff restrict add l1: 3.14590e-07 +DEAL::Diff restrict l2: 9.87299e-07 +DEAL::Diff restrict add l2: 1.06546e-06 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_07.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_07.cc new file mode 100644 index 0000000000..a095a15a1a --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_07.cc @@ -0,0 +1,175 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree by comparison with MGTransferPrebuilt on a +// series of meshes with adaptive meshes for FE_DGQLegendre (except for the +// different element the same test as transfer_matrix_free_05) + +#include + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_DGQLegendre fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + unsigned int sizes[] = {1, 2, 3}; + for (unsigned int cycle = 0; cycle < sizeof(sizes) / sizeof(unsigned int); + ++cycle) + { + unsigned int n_refinements = 0; + unsigned int n_subdiv = sizes[cycle]; + if (n_subdiv > 1) + while (n_subdiv % 2 == 0) + { + n_refinements += 1; + n_subdiv /= 2; + } + n_refinements += 3 - dim; + if (fe_degree < 3) + n_refinements += 1; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, n_subdiv); + tr.refine_global(n_refinements); + + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() < 0.5) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.3 && + cell->center().norm() < 0.4) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->center().norm() > 0.33 && + cell->center().norm() < 0.37) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + // build reference + MGTransferPrebuilt> + transfer_ref; + transfer_ref.build(mgdof); + + // build matrix-free transfer + MGTransferMF transfer; + transfer.build(mgdof); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); + check<2, double>(3); + check<3, double>(1); + check<3, double>(3); + check<2, float>(2); + check<3, float>(2); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_07.with_p4est=true.with_trilinos=true.mpirun=5.output b/tests/multigrid-global-coarsening/transfer_matrix_free_07.with_p4est=true.with_trilinos=true.mpirun=5.output new file mode 100644 index 0000000000..78dccc74bc --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_07.with_p4est=true.with_trilinos=true.mpirun=5.output @@ -0,0 +1,259 @@ + +DEAL::FE: FE_DGQLegendre<2>(1) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 1.17961e-15 +DEAL::Diff prolongate l2: 2.31497e-15 +DEAL::Diff prolongate l3: 3.30061e-15 +DEAL::Diff prolongate l4: 3.68951e-15 +DEAL::Diff prolongate l5: 3.01737e-15 +DEAL::Diff restrict l1: 1.37775e-15 +DEAL::Diff restrict add l1: 1.27555e-15 +DEAL::Diff restrict l2: 2.56074e-15 +DEAL::Diff restrict add l2: 2.68298e-15 +DEAL::Diff restrict l3: 4.18622e-15 +DEAL::Diff restrict add l3: 4.14368e-15 +DEAL::Diff restrict l4: 4.18475e-15 +DEAL::Diff restrict add l4: 4.36531e-15 +DEAL::Diff restrict l5: 2.85019e-15 +DEAL::Diff restrict add l5: 2.95411e-15 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 9.09472e-16 +DEAL::Diff prolongate l2: 2.47191e-15 +DEAL::Diff prolongate l3: 3.78045e-15 +DEAL::Diff prolongate l4: 4.46449e-15 +DEAL::Diff prolongate l5: 5.14809e-15 +DEAL::Diff prolongate l6: 4.75228e-15 +DEAL::Diff restrict l1: 1.33689e-15 +DEAL::Diff restrict add l1: 1.27555e-15 +DEAL::Diff restrict l2: 2.68140e-15 +DEAL::Diff restrict add l2: 2.90573e-15 +DEAL::Diff restrict l3: 5.86300e-15 +DEAL::Diff restrict add l3: 6.12437e-15 +DEAL::Diff restrict l4: 4.88696e-15 +DEAL::Diff restrict add l4: 5.12750e-15 +DEAL::Diff restrict l5: 6.62644e-15 +DEAL::Diff restrict add l5: 7.00145e-15 +DEAL::Diff restrict l6: 6.91582e-15 +DEAL::Diff restrict add l6: 6.98735e-15 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 2.75105e-15 +DEAL::Diff prolongate l2: 6.10804e-15 +DEAL::Diff prolongate l3: 4.90801e-15 +DEAL::Diff prolongate l4: 6.30864e-15 +DEAL::Diff prolongate l5: 7.18050e-15 +DEAL::Diff restrict l1: 3.59935e-15 +DEAL::Diff restrict add l1: 3.78128e-15 +DEAL::Diff restrict l2: 8.14600e-15 +DEAL::Diff restrict add l2: 8.34663e-15 +DEAL::Diff restrict l3: 7.27681e-15 +DEAL::Diff restrict add l3: 7.55849e-15 +DEAL::Diff restrict l4: 8.39312e-15 +DEAL::Diff restrict add l4: 8.53862e-15 +DEAL::Diff restrict l5: 9.82938e-15 +DEAL::Diff restrict add l5: 1.04862e-14 +DEAL:: +DEAL::FE: FE_DGQLegendre<2>(3) +DEAL::no. cells: 34 +DEAL::Diff prolongate l1: 3.00914e-15 +DEAL::Diff prolongate l2: 6.62459e-15 +DEAL::Diff prolongate l3: 6.49387e-15 +DEAL::Diff prolongate l4: 3.09889e-15 +DEAL::Diff restrict l1: 3.64043e-15 +DEAL::Diff restrict add l1: 3.56656e-15 +DEAL::Diff restrict l2: 6.57463e-15 +DEAL::Diff restrict add l2: 6.49931e-15 +DEAL::Diff restrict l3: 6.23681e-15 +DEAL::Diff restrict add l3: 6.12739e-15 +DEAL::Diff restrict l4: 4.53656e-15 +DEAL::Diff restrict add l4: 4.58698e-15 +DEAL:: +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 2.63188e-15 +DEAL::Diff prolongate l2: 5.48505e-15 +DEAL::Diff prolongate l3: 8.92854e-15 +DEAL::Diff prolongate l4: 9.11112e-15 +DEAL::Diff prolongate l5: 6.94348e-15 +DEAL::Diff restrict l1: 3.97198e-15 +DEAL::Diff restrict add l1: 4.05953e-15 +DEAL::Diff restrict l2: 6.33031e-15 +DEAL::Diff restrict add l2: 6.60559e-15 +DEAL::Diff restrict l3: 9.09159e-15 +DEAL::Diff restrict add l3: 9.07128e-15 +DEAL::Diff restrict l4: 9.35191e-15 +DEAL::Diff restrict add l4: 9.59813e-15 +DEAL::Diff restrict l5: 7.73956e-15 +DEAL::Diff restrict add l5: 7.73261e-15 +DEAL:: +DEAL::no. cells: 141 +DEAL::Diff prolongate l1: 8.50986e-15 +DEAL::Diff prolongate l2: 9.70102e-15 +DEAL::Diff prolongate l3: 1.17234e-14 +DEAL::Diff prolongate l4: 1.10643e-14 +DEAL::Diff restrict l1: 9.82721e-15 +DEAL::Diff restrict add l1: 9.94130e-15 +DEAL::Diff restrict l2: 8.95066e-15 +DEAL::Diff restrict add l2: 8.93712e-15 +DEAL::Diff restrict l3: 1.21155e-14 +DEAL::Diff restrict add l3: 1.22089e-14 +DEAL::Diff restrict l4: 1.12588e-14 +DEAL::Diff restrict add l4: 1.14013e-14 +DEAL:: +DEAL::FE: FE_DGQLegendre<3>(1) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 2.50686e-15 +DEAL::Diff prolongate l2: 2.81673e-15 +DEAL::Diff restrict l1: 4.67086e-15 +DEAL::Diff restrict add l1: 4.74158e-15 +DEAL::Diff restrict l2: 3.52878e-15 +DEAL::Diff restrict add l2: 3.40026e-15 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 1.51799e-15 +DEAL::Diff prolongate l2: 7.46319e-15 +DEAL::Diff prolongate l3: 1.27085e-14 +DEAL::Diff prolongate l4: 1.72742e-14 +DEAL::Diff prolongate l5: 1.58362e-14 +DEAL::Diff restrict l1: 4.27400e-15 +DEAL::Diff restrict add l1: 4.35683e-15 +DEAL::Diff restrict l2: 1.31474e-14 +DEAL::Diff restrict add l2: 1.36291e-14 +DEAL::Diff restrict l3: 1.97274e-14 +DEAL::Diff restrict add l3: 1.98513e-14 +DEAL::Diff restrict l4: 2.76798e-14 +DEAL::Diff restrict add l4: 2.79761e-14 +DEAL::Diff restrict l5: 2.40156e-14 +DEAL::Diff restrict add l5: 2.45131e-14 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 1.32337e-14 +DEAL::Diff prolongate l2: 1.43823e-14 +DEAL::Diff prolongate l3: 2.25930e-14 +DEAL::Diff prolongate l4: 2.95496e-14 +DEAL::Diff restrict l1: 2.40047e-14 +DEAL::Diff restrict add l1: 2.40260e-14 +DEAL::Diff restrict l2: 2.30032e-14 +DEAL::Diff restrict add l2: 2.28488e-14 +DEAL::Diff restrict l3: 3.79362e-14 +DEAL::Diff restrict add l3: 3.79409e-14 +DEAL::Diff restrict l4: 4.92435e-14 +DEAL::Diff restrict add l4: 4.94843e-14 +DEAL:: +DEAL::FE: FE_DGQLegendre<3>(3) +DEAL::no. cells: 1 +DEAL:: +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 1.22857e-14 +DEAL::Diff prolongate l2: 1.18723e-14 +DEAL::Diff restrict l1: 1.20501e-14 +DEAL::Diff restrict add l1: 1.20596e-14 +DEAL::Diff restrict l2: 9.27744e-15 +DEAL::Diff restrict add l2: 9.37465e-15 +DEAL:: +DEAL::no. cells: 223 +DEAL::Diff prolongate l1: 2.80933e-14 +DEAL::Diff prolongate l2: 4.15818e-14 +DEAL::Diff prolongate l3: 2.64041e-14 +DEAL::Diff restrict l1: 3.10527e-14 +DEAL::Diff restrict add l1: 3.08610e-14 +DEAL::Diff restrict l2: 4.48476e-14 +DEAL::Diff restrict add l2: 4.52462e-14 +DEAL::Diff restrict l3: 2.91624e-14 +DEAL::Diff restrict add l3: 2.91101e-14 +DEAL:: +DEAL::FE: FE_DGQLegendre<2>(2) +DEAL::no. cells: 88 +DEAL::Diff prolongate l1: 1.50767e-07 +DEAL::Diff prolongate l2: 3.40269e-07 +DEAL::Diff prolongate l3: 5.31799e-07 +DEAL::Diff prolongate l4: 5.68538e-07 +DEAL::Diff prolongate l5: 5.27410e-07 +DEAL::Diff restrict l1: 1.00439e-07 +DEAL::Diff restrict add l1: 1.75118e-07 +DEAL::Diff restrict l2: 4.36168e-07 +DEAL::Diff restrict add l2: 4.67837e-07 +DEAL::Diff restrict l3: 5.13719e-07 +DEAL::Diff restrict add l3: 6.14205e-07 +DEAL::Diff restrict l4: 5.48251e-07 +DEAL::Diff restrict add l4: 6.62665e-07 +DEAL::Diff restrict l5: 3.55987e-07 +DEAL::Diff restrict add l5: 5.20885e-07 +DEAL:: +DEAL::no. cells: 250 +DEAL::Diff prolongate l1: 1.40461e-07 +DEAL::Diff prolongate l2: 4.13020e-07 +DEAL::Diff prolongate l3: 7.35401e-07 +DEAL::Diff prolongate l4: 8.37297e-07 +DEAL::Diff prolongate l5: 8.92044e-07 +DEAL::Diff prolongate l6: 8.41612e-07 +DEAL::Diff restrict l1: 1.45801e-07 +DEAL::Diff restrict add l1: 1.62850e-07 +DEAL::Diff restrict l2: 3.58578e-07 +DEAL::Diff restrict add l2: 4.84573e-07 +DEAL::Diff restrict l3: 7.21057e-07 +DEAL::Diff restrict add l3: 9.44494e-07 +DEAL::Diff restrict l4: 6.47760e-07 +DEAL::Diff restrict add l4: 8.41653e-07 +DEAL::Diff restrict l5: 8.92925e-07 +DEAL::Diff restrict add l5: 1.05666e-06 +DEAL::Diff restrict l6: 8.33874e-07 +DEAL::Diff restrict add l6: 1.00952e-06 +DEAL:: +DEAL::no. cells: 510 +DEAL::Diff prolongate l1: 5.95223e-07 +DEAL::Diff prolongate l2: 1.08340e-06 +DEAL::Diff prolongate l3: 8.76501e-07 +DEAL::Diff prolongate l4: 1.17615e-06 +DEAL::Diff prolongate l5: 1.31783e-06 +DEAL::Diff restrict l1: 4.69618e-07 +DEAL::Diff restrict add l1: 6.08473e-07 +DEAL::Diff restrict l2: 1.03701e-06 +DEAL::Diff restrict add l2: 1.26830e-06 +DEAL::Diff restrict l3: 9.65744e-07 +DEAL::Diff restrict add l3: 1.14572e-06 +DEAL::Diff restrict l4: 1.06047e-06 +DEAL::Diff restrict add l4: 1.29914e-06 +DEAL::Diff restrict l5: 1.24330e-06 +DEAL::Diff restrict add l5: 1.65485e-06 +DEAL:: +DEAL::FE: FE_DGQLegendre<3>(2) +DEAL::no. cells: 15 +DEAL::Diff prolongate l1: 5.47934e-07 +DEAL::Diff prolongate l2: 4.76393e-07 +DEAL::Diff restrict l1: 6.08284e-07 +DEAL::Diff restrict add l1: 7.43498e-07 +DEAL::Diff restrict l2: 3.41055e-07 +DEAL::Diff restrict add l2: 4.04700e-07 +DEAL:: +DEAL::no. cells: 694 +DEAL::Diff prolongate l1: 4.96241e-07 +DEAL::Diff prolongate l2: 1.65120e-06 +DEAL::Diff prolongate l3: 2.51597e-06 +DEAL::Diff prolongate l4: 3.45087e-06 +DEAL::Diff prolongate l5: 3.23786e-06 +DEAL::Diff restrict l1: 4.77286e-07 +DEAL::Diff restrict add l1: 5.02006e-07 +DEAL::Diff restrict l2: 1.37508e-06 +DEAL::Diff restrict add l2: 1.48051e-06 +DEAL::Diff restrict l3: 2.58627e-06 +DEAL::Diff restrict add l3: 2.84981e-06 +DEAL::Diff restrict l4: 3.19463e-06 +DEAL::Diff restrict add l4: 3.50298e-06 +DEAL::Diff restrict l5: 3.15360e-06 +DEAL::Diff restrict add l5: 3.41047e-06 +DEAL:: +DEAL::no. cells: 1791 +DEAL::Diff prolongate l1: 3.02960e-06 +DEAL::Diff prolongate l2: 3.11031e-06 +DEAL::Diff prolongate l3: 4.96800e-06 +DEAL::Diff prolongate l4: 6.37747e-06 +DEAL::Diff restrict l1: 2.79504e-06 +DEAL::Diff restrict add l1: 3.06625e-06 +DEAL::Diff restrict l2: 2.58243e-06 +DEAL::Diff restrict add l2: 2.91690e-06 +DEAL::Diff restrict l3: 4.58185e-06 +DEAL::Diff restrict add l3: 5.03720e-06 +DEAL::Diff restrict l4: 5.87275e-06 +DEAL::Diff restrict add l4: 6.48746e-06 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_08.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_08.cc new file mode 100644 index 0000000000..636a47f607 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_08.cc @@ -0,0 +1,128 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2019 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree for high polynomial degrees beyond 10 by +// checking a linear function that gets prolongated between the mesh +// levels. Since the function is linear, it should be exactly represented on +// the finest level. Then also look into the result of restriction + +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include "../tests.h" + + +template +void +check(const FiniteElement &fe) +{ + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + + Triangulation tr(Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(tr); + tr.refine_global(2); + + Triangulation trcoarse( + Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(trcoarse); + DoFHandler dofcoarse(trcoarse); + dofcoarse.distribute_dofs(fe); + Tensor<1, dim> exponents_monomial; + for (unsigned int d = 0; d < dim; ++d) + exponents_monomial[d] = 1; + LinearAlgebra::distributed::Vector vrefcoarse; + vrefcoarse.reinit(dofcoarse.n_dofs()); + VectorTools::interpolate(dofcoarse, + Functions::Monomial(exponents_monomial), + vrefcoarse); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + // build matrix-free transfer + MGTransferMF transfer; + transfer.build(mgdof); + + LinearAlgebra::distributed::Vector vrefdouble; + LinearAlgebra::distributed::Vector vref; + AssertDimension(mgdof.n_dofs(tr.n_global_levels() - 1), mgdof.n_dofs()); + vrefdouble.reinit(mgdof.n_dofs()); + VectorTools::interpolate(mgdof, + Functions::Monomial(exponents_monomial), + vrefdouble); + + vref.reinit(mgdof.n_dofs()); + vref = vrefdouble; + std::vector> vec( + tr.n_global_levels()); + for (unsigned int level = 0; level < tr.n_global_levels(); ++level) + vec[level].reinit(mgdof.n_dofs(level)); + vec.back() = vref; + + // prolongate monomial from coarse to fine, should be exact for monomial + vec[0] = vrefcoarse; + for (unsigned int level = 1; level < tr.n_global_levels(); ++level) + transfer.prolongate(level, vec[level], vec[level - 1]); + vec.back() -= vref; + const Number tolerance = 1000. * std::numeric_limits::epsilon(); + deallog << "Error after prolongation: " + << filter_out_small_numbers(vec.back().linfty_norm(), tolerance) + << std::endl; + + // unfortunately, no completely trivial expression of what should happen + // during restriction + vec.back() = vref; + for (unsigned int level = tr.n_global_levels() - 1; level > 0; --level) + transfer.restrict_and_add(level, vec[level - 1], vec[level]); + deallog << "Norm after restriction: " << vec[0].l2_norm() << std::endl; +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + initlog(); + + check<2, double>(FE_DGQ<2>(3)); + check<2, double>(FE_DGQ<2>(8)); + check<2, double>(FE_DGQ<2>(16)); + check<2, double>(FE_Q<2>(16)); + check<3, double>(FE_DGQ<3>(11)); + check<2, float>(FE_DGQ<2>(3)); + check<2, float>(FE_DGQ<2>(8)); + check<2, float>(FE_DGQ<2>(16)); + check<2, float>(FE_Q<2>(16)); + check<3, float>(FE_DGQ<3>(11)); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_08.output b/tests/multigrid-global-coarsening/transfer_matrix_free_08.output new file mode 100644 index 0000000000..bfb4799c28 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_08.output @@ -0,0 +1,41 @@ + +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 34.1210 +DEAL::FE: FE_DGQ<2>(8) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 71.6678 +DEAL::FE: FE_DGQ<2>(16) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 151.607 +DEAL::FE: FE_Q<2>(16) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 133.734 +DEAL::FE: FE_DGQ<3>(11) +DEAL::no. cells: 64 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 774.120 +DEAL::FE: FE_DGQ<2>(3) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 34.1210 +DEAL::FE: FE_DGQ<2>(8) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 71.6678 +DEAL::FE: FE_DGQ<2>(16) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 151.607 +DEAL::FE: FE_Q<2>(16) +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 133.734 +DEAL::FE: FE_DGQ<3>(11) +DEAL::no. cells: 64 +DEAL::Error after prolongation: 0 +DEAL::Norm after restriction: 774.120 diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_09.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_09.cc new file mode 100644 index 0000000000..66d6a77471 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_09.cc @@ -0,0 +1,129 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check that MGTransferMatrixFree::clear works correctly by comparing a +// cleared transfer system with a freshly constructed one +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include "../tests.h" + + +template +void +check(const FiniteElement &fe) +{ + deallog << "FE: " << fe.get_name() << std::endl; + + MGConstrainedDoFs mg_constrained_dofs; + MGTransferMF transfer; + Triangulation tr(Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(tr); + tr.refine_global(6 - dim); + + // run a few different sizes... + for (unsigned int c = 0; c < 4; ++c) + { + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2)) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + Tensor<1, dim> exponents_monomial; + for (unsigned int d = 0; d < dim; ++d) + exponents_monomial[d] = 1; + LinearAlgebra::distributed::Vector vref; + vref.reinit(mgdof.n_dofs()); + VectorTools::interpolate(mgdof, + Functions::Monomial(exponents_monomial), + vref); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + const std::set dirichlet_boundary = {0}; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, + dirichlet_boundary); + + // build matrix-free transfer + transfer.clear(); + transfer.initialize_constraints(mg_constrained_dofs); + transfer.build(mgdof); + MGTransferMF transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + MGLevelObject> vectors( + 0, tr.n_global_levels() - 1); + transfer_ref.copy_to_mg(mgdof, vectors, vref); + for (unsigned int level = vectors.max_level(); level > 0; --level) + { + LinearAlgebra::distributed::Vector vec2(vectors[level - 1]); + transfer_ref.restrict_and_add(level, + vectors[level - 1], + vectors[level]); + transfer.restrict_and_add(level, vec2, vectors[level]); + vec2 -= vectors[level - 1]; + deallog << "Error in restriction: " << (double)vec2.linfty_norm() + << std::endl; + } + + for (unsigned int level = 1; level < vectors.max_level(); ++level) + { + LinearAlgebra::distributed::Vector vec2(vectors[level + 1]); + transfer_ref.prolongate(level + 1, + vectors[level + 1], + vectors[level]); + transfer.prolongate(level + 1, vec2, vectors[level]); + vec2 -= vectors[level + 1]; + deallog << "Error in prolongation: " << (double)vec2.linfty_norm() + << std::endl; + } + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + initlog(); + + check<2, double>(FE_DGQ<2>(2)); + check<2, double>(FE_Q<2>(2)); + check<3, double>(FE_Q<3>(1)); + check<2, float>(FE_Q<2>(2)); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_09.output b/tests/multigrid-global-coarsening/transfer_matrix_free_09.output new file mode 100644 index 0000000000..37eaf906a4 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_09.output @@ -0,0 +1,205 @@ + +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 757 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 2808 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6847 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 33776 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_10.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_10.cc new file mode 100644 index 0000000000..cffc150bb3 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_10.cc @@ -0,0 +1,127 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 - 2022 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check that MGTransferMatrixFree::build works correctly by comparing the +// build on an already existing transfer system with a freshly constructed one +#include + +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include "../tests.h" + + +template +void +check(const FiniteElement &fe) +{ + deallog << "FE: " << fe.get_name() << std::endl; + + MGConstrainedDoFs mg_constrained_dofs; + MGTransferMF transfer(mg_constrained_dofs); + Triangulation tr(Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(tr); + tr.refine_global(6 - dim); + + // run a few different sizes... + for (unsigned int c = 0; c < 4; ++c) + { + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if ((cell->center().norm() < 0.5 && + (cell->level() < 5 || cell->center().norm() > 0.45)) || + (dim == 2 && cell->center().norm() > 1.2)) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + Tensor<1, dim> exponents_monomial; + for (unsigned int d = 0; d < dim; ++d) + exponents_monomial[d] = 1; + LinearAlgebra::distributed::Vector vref; + vref.reinit(mgdof.n_dofs()); + VectorTools::interpolate(mgdof, + Functions::Monomial(exponents_monomial), + vref); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + const std::set dirichlet_boundary = {0}; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, + dirichlet_boundary); + + // build matrix-free transfer + transfer.build(mgdof); + MGTransferMF transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + MGLevelObject> vectors( + 0, tr.n_global_levels() - 1); + transfer_ref.copy_to_mg(mgdof, vectors, vref); + for (unsigned int level = vectors.max_level(); level > 0; --level) + { + LinearAlgebra::distributed::Vector vec2(vectors[level - 1]); + transfer_ref.restrict_and_add(level, + vectors[level - 1], + vectors[level]); + transfer.restrict_and_add(level, vec2, vectors[level]); + vec2 -= vectors[level - 1]; + deallog << "Error in restriction: " << (double)vec2.linfty_norm() + << std::endl; + } + + for (unsigned int level = 1; level < vectors.max_level(); ++level) + { + LinearAlgebra::distributed::Vector vec2(vectors[level + 1]); + transfer_ref.prolongate(level + 1, + vectors[level + 1], + vectors[level]); + transfer.prolongate(level + 1, vec2, vectors[level]); + vec2 -= vectors[level + 1]; + deallog << "Error in prolongation: " << (double)vec2.linfty_norm() + << std::endl; + } + } +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + initlog(); + + check<2, double>(FE_DGQ<2>(2)); + check<2, double>(FE_Q<2>(2)); + check<3, double>(FE_Q<3>(1)); + check<2, float>(FE_Q<2>(2)); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_10.output b/tests/multigrid-global-coarsening/transfer_matrix_free_10.output new file mode 100644 index 0000000000..37eaf906a4 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_10.output @@ -0,0 +1,205 @@ + +DEAL::FE: FE_DGQ<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<3>(1) +DEAL::no. cells: 757 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 2808 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6847 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 33776 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::FE: FE_Q<2>(2) +DEAL::no. cells: 448 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 766 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 1924 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::no. cells: 6082 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in restriction: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 +DEAL::Error in prolongation: 0 diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_11.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_11.cc new file mode 100644 index 0000000000..3596df96e6 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_11.cc @@ -0,0 +1,145 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Check MGTransferMatrixFree and MGTransferPrebuilt for periodic boundary +// conditions + +#include + +#include + +#include +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check(const unsigned int fe_degree) +{ + FE_Q fe(fe_degree); + deallog << "FE: " << fe.get_name() << std::endl; + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::hyper_cube(tr, -1, 1, true); + std::vector< + GridTools::PeriodicFacePair::cell_iterator>> + periodicity_vector; + GridTools::collect_periodic_faces(tr, 0, 1, 0, periodicity_vector); + GridTools::collect_periodic_faces(tr, 2, 3, 1, periodicity_vector); + tr.add_periodicity(periodicity_vector); + tr.refine_global(2); + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + + // build reference + MGTransferPrebuilt> transfer_ref( + mg_constrained_dofs); + transfer_ref.build(mgdof); + deallog << "Transfer matrices: " << std::endl; + transfer_ref.print_matrices(deallog.get_file_stream()); + deallog << std::endl; + + // build matrix-free transfer + MGTransferMF transfer(mg_constrained_dofs); + transfer.build(mgdof); + + // check prolongation for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.prolongate(level, v2, v1); + transfer_ref.prolongate(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff prolongate l" << level << ": " << v3.l2_norm() + << std::endl; + if (v3.l2_norm() > 1e-12) + { + // On level 0, we expect the matrix-based constraints to be wrong + // because it cannot capture the periodicity connections with a + // single cell + v2_cpy.print(deallog.get_file_stream()); + v3.print(deallog.get_file_stream()); + } + } + + // check restriction for all levels using random vector + for (unsigned int level = 1; + level < mgdof.get_triangulation().n_global_levels(); + ++level) + { + LinearAlgebra::distributed::Vector v1, v2; + LinearAlgebra::distributed::Vector v1_cpy, v2_cpy, v3; + v1.reinit(mgdof.locally_owned_mg_dofs(level), MPI_COMM_WORLD); + v2.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + v3.reinit(mgdof.locally_owned_mg_dofs(level - 1), MPI_COMM_WORLD); + for (unsigned int i = 0; i < v1.locally_owned_size(); ++i) + v1.local_element(i) = random_value(); + v1_cpy = v1; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict l" << level << ": " << v3.l2_norm() + << std::endl; + + v2 = 1.; + v3 = 1.; + transfer.restrict_and_add(level, v2, v1); + transfer_ref.restrict_and_add(level, v3, v1_cpy); + v2_cpy = v2; + v3 -= v2_cpy; + deallog << "Diff restrict add l" << level << ": " << v3.l2_norm() + << std::endl; + } + deallog << std::endl; +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2, double>(1); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_11.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/multigrid-global-coarsening/transfer_matrix_free_11.with_p4est=true.with_trilinos=true.mpirun=1.output new file mode 100644 index 0000000000..49963ec916 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_11.with_p4est=true.with_trilinos=true.mpirun=1.output @@ -0,0 +1,64 @@ + +DEAL::FE: FE_Q<2>(1) +DEAL::no. cells: 16 +DEAL::Transfer matrices: +Level 0 +(3,3) 0.250000 +(5,3) 0.500000 +(7,3) 0.500000 +(8,3) 1.00000 + +Level 1 +(3,3) 0.250000 +(3,5) 0.250000 +(3,7) 0.250000 +(3,8) 0.250000 +(5,3) 0.500000 +(5,7) 0.500000 +(7,3) 0.500000 +(7,5) 0.500000 +(8,3) 1.00000 +(10,3) 0.250000 +(10,5) 0.250000 +(10,7) 0.250000 +(10,8) 0.250000 +(12,5) 0.500000 +(12,8) 0.500000 +(13,3) 0.500000 +(13,5) 0.500000 +(14,5) 1.00000 +(16,3) 0.250000 +(16,5) 0.250000 +(16,7) 0.250000 +(16,8) 0.250000 +(17,3) 0.500000 +(17,7) 0.500000 +(19,7) 0.500000 +(19,8) 0.500000 +(20,7) 1.00000 +(21,3) 0.250000 +(21,5) 0.250000 +(21,7) 0.250000 +(21,8) 0.250000 +(22,5) 0.500000 +(22,8) 0.500000 +(23,7) 0.500000 +(23,8) 0.500000 +(24,8) 1.00000 + +DEAL:: +DEAL::Diff prolongate l1: 0.823013 +Process #0 +Local range: [0, 9), global size: 9 +Vector data: +0.000e+00 0.000e+00 0.000e+00 7.984e-01 0.000e+00 7.984e-01 0.000e+00 7.984e-01 7.984e-01 +Process #0 +Local range: [0, 9), global size: 9 +Vector data: +0.000e+00 0.000e+00 0.000e+00 -5.988e-01 0.000e+00 -3.992e-01 0.000e+00 -3.992e-01 0.000e+00 +DEAL::Diff prolongate l2: 0 +DEAL::Diff restrict l1: 0.555735 +DEAL::Diff restrict add l1: 0.555735 +DEAL::Diff restrict l2: 0 +DEAL::Diff restrict add l2: 0 +DEAL:: diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_12.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_12.cc new file mode 100644 index 0000000000..6b4cf76a37 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_12.cc @@ -0,0 +1,131 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 - 2019 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Similar to transfer_matrix_free_08 but using a system of equations: high +// polynomial degrees beyond 10 that are compared against a linear function +// that gets prolongated between the mesh levels. Since the function is +// linear, it should be exactly represented on the finest level. Then also +// look into the result of restriction + +#include + +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include + +#include "../tests.h" + + +template +void +check(const FiniteElement &fe_scalar) +{ + FESystem fe(fe_scalar, dim); + deallog << "FE: " << fe.get_name() << std::endl; + + // run a few different sizes... + + Triangulation tr(Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(tr); + tr.refine_global(2); + + Triangulation trcoarse( + Triangulation::limit_level_difference_at_vertices); + GridGenerator::hyper_cube(trcoarse); + DoFHandler dofcoarse(trcoarse); + dofcoarse.distribute_dofs(fe); + Tensor<1, dim> exponents_monomial; + for (unsigned int d = 0; d < dim; ++d) + exponents_monomial[d] = 1; + LinearAlgebra::distributed::Vector vrefcoarse; + vrefcoarse.reinit(dofcoarse.n_dofs()); + VectorTools::interpolate(dofcoarse, + Functions::Monomial(exponents_monomial, dim), + vrefcoarse); + + deallog << "no. cells: " << tr.n_global_active_cells() << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + // build matrix-free transfer + MGTransferMF transfer; + transfer.build(mgdof); + + LinearAlgebra::distributed::Vector vrefdouble; + LinearAlgebra::distributed::Vector vref; + AssertDimension(mgdof.n_dofs(tr.n_global_levels() - 1), mgdof.n_dofs()); + vrefdouble.reinit(mgdof.n_dofs()); + VectorTools::interpolate(mgdof, + Functions::Monomial(exponents_monomial, dim), + vrefdouble); + + vref.reinit(mgdof.n_dofs()); + vref = vrefdouble; + std::vector> vec( + tr.n_global_levels()); + for (unsigned int level = 0; level < tr.n_global_levels(); ++level) + vec[level].reinit(mgdof.n_dofs(level)); + vec.back() = vref; + + // prolongate monomial from coarse to fine, should be exact for monomial + vec[0] = vrefcoarse; + for (unsigned int level = 1; level < tr.n_global_levels(); ++level) + transfer.prolongate(level, vec[level], vec[level - 1]); + vec.back() -= vref; + const Number tolerance = 1000. * std::numeric_limits::epsilon(); + deallog << "Error after prolongation: " + << filter_out_small_numbers(vec.back().linfty_norm(), tolerance) + << std::endl; + + // unfortunately, no completely trivial expression of what should happen + // during restriction + vec.back() = vref; + for (unsigned int level = tr.n_global_levels() - 1; level > 0; --level) + transfer.restrict_and_add(level, vec[level - 1], vec[level]); + deallog << "Norm after restriction: " << vec[0].l2_norm() << std::endl; +} + + +int +main(int argc, char **argv) +{ + // no threading in this test... + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + initlog(); + + check<2, double>(FE_DGQ<2>(3)); + check<2, double>(FE_DGQ<2>(8)); + check<2, double>(FE_DGQ<2>(16)); + check<2, double>(FE_Q<2>(16)); + check<3, double>(FE_DGQ<3>(11)); + check<2, float>(FE_DGQ<2>(3)); + check<2, float>(FE_DGQ<2>(8)); + check<2, float>(FE_DGQ<2>(16)); + check<2, float>(FE_Q<2>(16)); + check<3, float>(FE_DGQ<3>(11)); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_12.output b/tests/multigrid-global-coarsening/transfer_matrix_free_12.output new file mode 100644 index 0000000000..b3cf0ec67f --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_12.output @@ -0,0 +1,41 @@ + +DEAL::FE: FESystem<2>[FE_DGQ<2>(3)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 48.2543 +DEAL::FE: FESystem<2>[FE_DGQ<2>(8)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 101.354 +DEAL::FE: FESystem<2>[FE_DGQ<2>(16)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 214.405 +DEAL::FE: FESystem<2>[FE_Q<2>(16)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 189.129 +DEAL::FE: FESystem<3>[FE_DGQ<3>(11)^3] +DEAL::no. cells: 64 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 1340.82 +DEAL::FE: FESystem<2>[FE_DGQ<2>(3)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 48.2544 +DEAL::FE: FESystem<2>[FE_DGQ<2>(8)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 101.354 +DEAL::FE: FESystem<2>[FE_DGQ<2>(16)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 214.405 +DEAL::FE: FESystem<2>[FE_Q<2>(16)^2] +DEAL::no. cells: 16 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 189.129 +DEAL::FE: FESystem<3>[FE_DGQ<3>(11)^3] +DEAL::no. cells: 64 +DEAL::Error after prolongation: 0.00000 +DEAL::Norm after restriction: 1340.82 diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_14.cc b/tests/multigrid-global-coarsening/transfer_matrix_free_14.cc new file mode 100644 index 0000000000..1c44df81a1 --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_14.cc @@ -0,0 +1,94 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2016 - 2021 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// document a bug in MGLevelGlobalTransfer in 3d: + +/* +An error occurred in line <341> of file +<../source/multigrid/mg_level_global_transfer.cc> in function void +dealii::MGLevelGlobalTransfer >::fill_and_communicate_copy_indices(const +dealii::DoFHandler&) [with int dim = 3; int spacedim = 3; +Number = double] The violated condition was: + ::dealii::deal_II_exceptions::internals::compare_for_equality(this->copy_indices_level_mine.back().n_rows(), +0) Additional information: Dimension 2 not equal to 0. +*/ + +#include + +#include + +#include + +#include +#include + +#include "../tests.h" + +template +void +check() +{ + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + typename parallel::distributed::Triangulation::Settings( + parallel::distributed::Triangulation< + dim>::mesh_reconstruction_after_repartitioning | + parallel::distributed::Triangulation< + dim>::construct_multigrid_hierarchy)); + + GridGenerator::hyper_cube(tr); + + tr.refine_global(2); + + // coarsen a few cells: + for (const auto &cell : tr.active_cell_iterators()) + { + if (cell->is_artificial()) + continue; + const std::string id = cell->parent()->id().to_string(); + if (id == "0_1:0" || id == "0_1:1" || id == "0_1:2" || id == "0_1:3") + cell->set_coarsen_flag(); + } + + tr.execute_coarsening_and_refinement(); + + FE_Q fe(1); + DoFHandler mgdof(tr); + MGTransferMF transfer_mf; + + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + deallog << "n_dofs = " << mgdof.n_dofs() << std::endl; + + transfer_mf.build(mgdof); + + tr.coarsen_global(); + deallog << "OK" << std::endl; +} + + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + MPILogInitAll all; + + check<2>(); + check<3>(); +} diff --git a/tests/multigrid-global-coarsening/transfer_matrix_free_14.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/transfer_matrix_free_14.with_p4est=true.mpirun=2.output new file mode 100644 index 0000000000..cde307a16c --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_matrix_free_14.with_p4est=true.mpirun=2.output @@ -0,0 +1,11 @@ + +DEAL:0::n_dofs = 9 +DEAL:0::OK +DEAL:0::n_dofs = 84 +DEAL:0::OK + +DEAL:1::n_dofs = 9 +DEAL:1::OK +DEAL:1::n_dofs = 84 +DEAL:1::OK + diff --git a/tests/multigrid-global-coarsening/transfer_prebuilt_04.cc b/tests/multigrid-global-coarsening/transfer_prebuilt_04.cc new file mode 100644 index 0000000000..4e2cb5d0cf --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_prebuilt_04.cc @@ -0,0 +1,111 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2000 - 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// Deadlock reported by Kronbichler (github +// https://github.com/dealii/dealii/issues/2051) with 3 processes +// in MGTransferPrebuilt + + +#include + +#include + +#include + +#include +#include + +#include + +#include +#include + +#include "../tests.h" + + +template +void +check() +{ + FE_Q fe(1); + + parallel::distributed::Triangulation tr( + MPI_COMM_WORLD, + Triangulation::limit_level_difference_at_vertices, + parallel::distributed::Triangulation::construct_multigrid_hierarchy); + GridGenerator::subdivided_hyper_cube(tr, 3); + for (unsigned int cycle = 0; cycle < (dim == 2 ? 10 : 7); ++cycle) + { + // adaptive refinement into a circle + for (typename Triangulation::active_cell_iterator cell = + tr.begin_active(); + cell != tr.end(); + ++cell) + if (cell->is_locally_owned() && cell->vertex(0).norm() < 1e-10) + cell->set_refine_flag(); + tr.execute_coarsening_and_refinement(); + + deallog << "no. cells: " << tr.n_global_active_cells() << " on " + << tr.n_global_levels() << " levels" << std::endl; + + DoFHandler mgdof(tr); + mgdof.distribute_dofs(fe); + mgdof.distribute_mg_dofs(); + + MGConstrainedDoFs mg_constrained_dofs; + mg_constrained_dofs.initialize(mgdof); + mg_constrained_dofs.make_zero_boundary_constraints(mgdof, {0}); + + unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD); + + if (0) + { + std::ofstream grid_output( + ("out" + Utilities::to_string(myid) + ".svg").c_str()); + GridOut grid_out; + GridOutFlags::Svg flags; + flags.label_level_subdomain_id = true; + flags.coloring = GridOutFlags::Svg::level_subdomain_id; + flags.convert_level_number_to_height = true; + grid_out.set_flags(flags); + + grid_out.write_svg(tr, grid_output); + } +#ifdef DEAL_II_WITH_TRILINOS + { + // MGTransferPrebuilt internally uses Trilinos matrices, so only + // create this if we have Trilinos + MGTransferPrebuilt> + transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + } +#endif + { + // but the matrix free transfer will work without Trilinos + MGTransferMF transfer_ref(mg_constrained_dofs); + transfer_ref.build(mgdof); + } + } +} + +int +main(int argc, char **argv) +{ + Utilities::MPI::MPI_InitFinalize mpi(argc, argv, 1); + mpi_initlog(); + + check<2>(); +} diff --git a/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=2.output b/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=2.output new file mode 100644 index 0000000000..2df36ef18f --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=2.output @@ -0,0 +1,11 @@ + +DEAL::no. cells: 12 on 2 levels +DEAL::no. cells: 15 on 3 levels +DEAL::no. cells: 18 on 4 levels +DEAL::no. cells: 21 on 5 levels +DEAL::no. cells: 24 on 6 levels +DEAL::no. cells: 27 on 7 levels +DEAL::no. cells: 30 on 8 levels +DEAL::no. cells: 33 on 9 levels +DEAL::no. cells: 36 on 10 levels +DEAL::no. cells: 39 on 11 levels diff --git a/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=3.output b/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=3.output new file mode 100644 index 0000000000..2df36ef18f --- /dev/null +++ b/tests/multigrid-global-coarsening/transfer_prebuilt_04.with_p4est=true.mpirun=3.output @@ -0,0 +1,11 @@ + +DEAL::no. cells: 12 on 2 levels +DEAL::no. cells: 15 on 3 levels +DEAL::no. cells: 18 on 4 levels +DEAL::no. cells: 21 on 5 levels +DEAL::no. cells: 24 on 6 levels +DEAL::no. cells: 27 on 7 levels +DEAL::no. cells: 30 on 8 levels +DEAL::no. cells: 33 on 9 levels +DEAL::no. cells: 36 on 10 levels +DEAL::no. cells: 39 on 11 levels