]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Refine MGTwoLevelTransfer::enable_inplace_operations_if_possible() 13525/head
authorPeter Munch <peterrmuench@gmail.com>
Wed, 9 Mar 2022 19:04:52 +0000 (20:04 +0100)
committerPeter Munch <peterrmuench@gmail.com>
Fri, 11 Mar 2022 15:56:37 +0000 (16:56 +0100)
include/deal.II/multigrid/mg_transfer_global_coarsening.h
include/deal.II/multigrid/mg_transfer_global_coarsening.templates.h

index 339fcad8751d5cdc02b1e771090d7882f0bda591..cc6b5552a9a492d682ed84f3bd16fe8c7b88fb66 100644 (file)
@@ -644,7 +644,7 @@ MGTransferGlobalCoarsening<dim, VectorType>::build(
       const unsigned int min_level = transfer.min_level();
       const unsigned int max_level = transfer.max_level();
 
-      AssertDimension(external_partitioners.size(), max_level - min_level + 1);
+      AssertDimension(external_partitioners.size(), transfer.n_levels());
 
       this->initialize_dof_vector =
         [external_partitioners, min_level](
@@ -669,18 +669,19 @@ MGTransferGlobalCoarsening<dim, VectorType>::build(
 {
   if (initialize_dof_vector)
     {
-      const unsigned int n_levels =
-        transfer.max_level() - transfer.min_level() + 1;
+      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<std::shared_ptr<const Utilities::MPI::Partitioner>>
         external_partitioners(n_levels);
 
-      for (unsigned int level = 0; level < n_levels; ++level)
+      for (unsigned int l = min_level; l <= max_level; ++l)
         {
           LinearAlgebra::distributed::Vector<typename VectorType::value_type>
             vector;
-          initialize_dof_vector(level, vector);
-          external_partitioners[level] = vector.get_partitioner();
+          initialize_dof_vector(l, vector);
+          external_partitioners[l - min_level] = vector.get_partitioner();
         }
 
       build(external_partitioners);
index 94c7ca8eef2ba60b9a5c0bf3ea8c72762e488e2d..9f0f74af6b2a677cfd8be93f81ec2662083d6ec6 100644 (file)
@@ -2905,19 +2905,73 @@ void
 MGTwoLevelTransfer<dim, LinearAlgebra::distributed::Vector<Number>>::
   enable_inplace_operations_if_possible(
     const std::shared_ptr<const Utilities::MPI::Partitioner>
-      &partitioner_coarse,
-    const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner_fine)
+      &external_partitioner_coarse,
+    const std::shared_ptr<const Utilities::MPI::Partitioner>
+      &external_partitioner_fine)
 {
-  if (this->partitioner_coarse->is_globally_compatible(*partitioner_coarse))
+  const auto is_partitioner_contained =
+    [](const auto &partitioner, const auto &external_partitioner) -> bool {
+    // no external partitioner has been given
+    if (external_partitioner.get() == nullptr)
+      return false;
+
+    // check if locally owned ranges are the same
+    if (external_partitioner->size() != partitioner->size())
+      return false;
+
+    if (external_partitioner->locally_owned_range() !=
+        partitioner->locally_owned_range())
+      return false;
+
+    const int ghosts_locally_contained =
+      ((external_partitioner->ghost_indices() & partitioner->ghost_indices()) ==
+       partitioner->ghost_indices()) ?
+        1 :
+        0;
+
+    // check if ghost values are contained in external partititioner
+    return Utilities::MPI::min(ghosts_locally_contained,
+                               partitioner->get_mpi_communicator()) == 1;
+  };
+
+  if (this->partitioner_coarse->is_globally_compatible(
+        *external_partitioner_coarse))
     {
-      this->partitioner_coarse = partitioner_coarse;
       this->vec_coarse.reinit(0);
+      this->partitioner_coarse = external_partitioner_coarse;
+    }
+  else if (is_partitioner_contained(this->partitioner_coarse,
+                                    external_partitioner_coarse))
+    {
+      this->vec_coarse.reinit(0);
+
+      for (auto &i : constraint_info.dof_indices)
+        i = external_partitioner_coarse->global_to_local(
+          this->partitioner_coarse->local_to_global(i));
+
+      for (auto &i : constraint_info.plain_dof_indices)
+        i = external_partitioner_coarse->global_to_local(
+          this->partitioner_coarse->local_to_global(i));
+
+      this->partitioner_coarse = external_partitioner_coarse;
     }
 
-  if (this->partitioner_fine->is_globally_compatible(*partitioner_fine))
+  if (this->partitioner_fine->is_globally_compatible(
+        *external_partitioner_fine))
     {
-      this->partitioner_fine = partitioner_fine;
       this->vec_fine.reinit(0);
+      this->partitioner_fine = external_partitioner_fine;
+    }
+  else if (is_partitioner_contained(this->partitioner_fine,
+                                    external_partitioner_fine))
+    {
+      this->vec_fine.reinit(0);
+
+      for (auto &i : level_dof_indices_fine)
+        i = external_partitioner_fine->global_to_local(
+          this->partitioner_fine->local_to_global(i));
+
+      this->partitioner_fine = external_partitioner_fine;
     }
 }
 

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.