]> https://gitweb.dealii.org/ - dealii.git/commitdiff
make it possible to fill RPE with GT::DistributedComputePointLocationsInternal 15154/head
authorJohannes Heinz <johannes.heinz@tuwien.ac.at>
Fri, 28 Apr 2023 09:02:36 +0000 (11:02 +0200)
committerJohannes Heinz <johannes.heinz@tuwien.ac.at>
Sun, 7 May 2023 15:26:29 +0000 (17:26 +0200)
include/deal.II/base/mpi_remote_point_evaluation.h
include/deal.II/grid/grid_tools.h
source/base/mpi_remote_point_evaluation.cc
source/grid/grid_tools.cc
source/grid/grid_tools.inst.in

index 7dfbf220f99e415c50ba0307f701650c2905b446..b357d28f6dee320b4b7c9052588396749145dc4f 100644 (file)
 
 DEAL_II_NAMESPACE_OPEN
 
+// Forward declarations
+namespace GridTools
+{
+  namespace internal
+  {
+    template <int dim, int spacedim>
+    struct DistributedComputePointLocationsInternal;
+  }
+} // namespace GridTools
 
 namespace Utilities
 {
@@ -86,6 +95,21 @@ namespace Utilities
              const Triangulation<dim, spacedim> &tria,
              const Mapping<dim, spacedim> &      mapping);
 
+      /**
+       * Set up internal data structures and communication pattern based on
+       * GridTools::internal::DistributedComputePointLocationsInternal.
+       *
+       * This function is called internally by the reinit() function above.
+       * Having it as a seperate function makes it possible to setup the class
+       * if it is known in which cells corresponding reference points are
+       * located (e.g. if intersections of cells are known).
+       */
+      void
+      reinit(const GridTools::internal::
+               DistributedComputePointLocationsInternal<dim, spacedim> &data,
+             const Triangulation<dim, spacedim> &                       tria,
+             const Mapping<dim, spacedim> &mapping);
+
       /**
        * Data of points positioned in a cell.
        */
index 7bf25de6f97d5ab0e272b2cf03559c550546f70e..d48e80213d3a67060485047c9170062bf5eedd3e 100644 (file)
@@ -1213,6 +1213,22 @@ namespace GridTools
     template <int dim, int spacedim>
     struct DistributedComputePointLocationsInternal
     {
+      DistributedComputePointLocationsInternal();
+
+      /**
+       * Function which sets up @p send_ranks, @p send_ptrs, @p recv_ranks,
+       * and @p recv_ptrs from @p send_components, @p recv_components,
+       * and @p n_searched_points. Internally @p send_components and @p recv_components
+       * are sorted and enumerated.
+       */
+      void
+      finalize_setup();
+
+      /**
+       * Number of searched point locations.
+       */
+      unsigned int n_searched_points;
+
       /**
        * Information of each point on sending/evaluation side. The elements of
        * the tuple are as follows: 0) cell level and index, 1) rank of the
index 656be3e2a6940e111229340b0c923b7a6b34fae3..43565aa536f012b49bf44ce533df090170312b45 100644 (file)
@@ -78,9 +78,6 @@ namespace Utilities
       tria_signal =
         tria.signals.any_change.connect([&]() { this->ready_flag = false; });
 
-      this->tria    = &tria;
-      this->mapping = &mapping;
-
       std::vector<BoundingBox<spacedim>> local_boxes;
       for (const auto &cell :
            tria.active_cell_iterators() | IteratorFilters::LocallyOwnedCell())
@@ -105,6 +102,23 @@ namespace Utilities
           true,
           enforce_unique_mapping);
 
+      this->reinit(data, tria, mapping);
+#endif
+    }
+
+
+
+    template <int dim, int spacedim>
+    void
+    RemotePointEvaluation<dim, spacedim>::reinit(
+      const GridTools::internal::
+        DistributedComputePointLocationsInternal<dim, spacedim> &data,
+      const Triangulation<dim, spacedim> &                       tria,
+      const Mapping<dim, spacedim> &                             mapping)
+    {
+      this->tria    = &tria;
+      this->mapping = &mapping;
+
       this->recv_ranks = data.recv_ranks;
       this->recv_ptrs  = data.recv_ptrs;
 
@@ -113,7 +127,7 @@ namespace Utilities
 
       this->recv_permutation = {};
       this->recv_permutation.resize(data.recv_components.size());
-      this->point_ptrs.assign(points.size() + 1, 0);
+      this->point_ptrs.assign(data.n_searched_points + 1, 0);
       for (unsigned int i = 0; i < data.recv_components.size(); ++i)
         {
           AssertIndexRange(std::get<2>(data.recv_components[i]),
@@ -130,7 +144,7 @@ namespace Utilities
       std::tuple<unsigned int, unsigned int> n_owning_processes_local =
         n_owning_processes_default;
 
-      for (unsigned int i = 0; i < points.size(); ++i)
+      for (unsigned int i = 0; i < data.n_searched_points; ++i)
         {
           std::get<0>(n_owning_processes_local) =
             std::min(std::get<0>(n_owning_processes_local),
@@ -196,7 +210,6 @@ namespace Utilities
         cell_data.reference_point_values.size());
 
       this->ready_flag = true;
-#endif
     }
 
 
index dfce19ff5dad971deb31291ffc874a9c241f3c70..8afe92502e026b38c2b211052e60ca13987c51e5 100644 (file)
@@ -6168,6 +6168,127 @@ namespace GridTools
         return locally_owned_active_cells_around_point;
     }
 
+    template <int dim, int spacedim>
+    DistributedComputePointLocationsInternal<dim, spacedim>::
+      DistributedComputePointLocationsInternal()
+      : n_searched_points(numbers::invalid_unsigned_int)
+    {}
+
+    template <int dim, int spacedim>
+    void
+    DistributedComputePointLocationsInternal<dim, spacedim>::finalize_setup()
+    {
+      // before reshuffeling the data check if data.recv_components and
+      // n_searched_points are in a valid state.
+      Assert(n_searched_points != numbers::invalid_unsigned_int,
+             ExcInternalError());
+      Assert(recv_components.empty() ||
+               std::get<1>(*std::max_element(recv_components.begin(),
+                                             recv_components.end(),
+                                             [](const auto &a, const auto &b) {
+                                               return std::get<1>(a) <
+                                                      std::get<1>(b);
+                                             })) < n_searched_points,
+             ExcInternalError());
+
+      send_ranks.clear();
+      recv_ranks.clear();
+      send_ptrs.clear();
+      recv_ptrs.clear();
+
+      if (true)
+        {
+          // sort according to rank (and point index and cell) -> make
+          // deterministic
+          std::sort(send_components.begin(),
+                    send_components.end(),
+                    [&](const auto &a, const auto &b) {
+                      if (std::get<1>(a) != std::get<1>(b)) // rank
+                        return std::get<1>(a) < std::get<1>(b);
+
+                      if (std::get<2>(a) != std::get<2>(b)) // point index
+                        return std::get<2>(a) < std::get<2>(b);
+
+                      return std::get<0>(a) < std::get<0>(b); // cell
+                    });
+
+          // perform enumeration and extract rank information
+          for (unsigned int i = 0, dummy = numbers::invalid_unsigned_int;
+               i < send_components.size();
+               ++i)
+            {
+              std::get<5>(send_components[i]) = i;
+
+              if (dummy != std::get<1>(send_components[i]))
+                {
+                  dummy = std::get<1>(send_components[i]);
+                  send_ranks.push_back(dummy);
+                  send_ptrs.push_back(i);
+                }
+            }
+          send_ptrs.push_back(send_components.size());
+
+          // sort according to cell, rank, point index (while keeping
+          // partial ordering)
+          std::sort(send_components.begin(),
+                    send_components.end(),
+                    [&](const auto &a, const auto &b) {
+                      if (std::get<0>(a) != std::get<0>(b))
+                        return std::get<0>(a) < std::get<0>(b); // cell
+
+                      if (std::get<1>(a) != std::get<1>(b))
+                        return std::get<1>(a) < std::get<1>(b); // rank
+
+                      if (std::get<2>(a) != std::get<2>(b))
+                        return std::get<2>(a) < std::get<2>(b); // point index
+
+                      return std::get<5>(a) < std::get<5>(b); // enumeration
+                    });
+        }
+
+      if (recv_components.size() > 0)
+        {
+          // sort according to rank (and point index) -> make deterministic
+          std::sort(recv_components.begin(),
+                    recv_components.end(),
+                    [&](const auto &a, const auto &b) {
+                      if (std::get<0>(a) != std::get<0>(b))
+                        return std::get<0>(a) < std::get<0>(b); // rank
+
+                      return std::get<1>(a) < std::get<1>(b); // point index
+                    });
+
+          // perform enumeration and extract rank information
+          for (unsigned int i = 0, dummy = numbers::invalid_unsigned_int;
+               i < recv_components.size();
+               ++i)
+            {
+              std::get<2>(recv_components[i]) = i;
+
+              if (dummy != std::get<0>(recv_components[i]))
+                {
+                  dummy = std::get<0>(recv_components[i]);
+                  recv_ranks.push_back(dummy);
+                  recv_ptrs.push_back(i);
+                }
+            }
+          recv_ptrs.push_back(recv_components.size());
+
+          // sort according to point index and rank (while keeping partial
+          // ordering)
+          std::sort(recv_components.begin(),
+                    recv_components.end(),
+                    [&](const auto &a, const auto &b) {
+                      if (std::get<1>(a) != std::get<1>(b))
+                        return std::get<1>(a) < std::get<1>(b); // point index
+
+                      if (std::get<0>(a) != std::get<0>(b))
+                        return std::get<0>(a) < std::get<0>(b); // rank
+
+                      return std::get<2>(a) < std::get<2>(b); // enumeration
+                    });
+        }
+    }
 
 
     template <int dim, int spacedim>
@@ -6182,13 +6303,10 @@ namespace GridTools
       const bool enforce_unique_mapping)
     {
       DistributedComputePointLocationsInternal<dim, spacedim> result;
+      result.n_searched_points = points.size();
 
       auto &send_components = result.send_components;
-      auto &send_ranks      = result.send_ranks;
-      auto &send_ptrs       = result.send_ptrs;
       auto &recv_components = result.recv_components;
-      auto &recv_ranks      = result.recv_ranks;
-      auto &recv_ptrs       = result.recv_ptrs;
 
       const auto comm = cache.get_triangulation().get_communicator();
 
@@ -6330,98 +6448,7 @@ namespace GridTools
         process_answer,
         comm);
 
-      if (true)
-        {
-          // sort according to rank (and point index and cell) -> make
-          // deterministic
-          std::sort(send_components.begin(),
-                    send_components.end(),
-                    [&](const auto &a, const auto &b) {
-                      if (std::get<1>(a) != std::get<1>(b)) // rank
-                        return std::get<1>(a) < std::get<1>(b);
-
-                      if (std::get<2>(a) != std::get<2>(b)) // point index
-                        return std::get<2>(a) < std::get<2>(b);
-
-                      return std::get<0>(a) < std::get<0>(b); // cell
-                    });
-
-          // perform enumeration and extract rank information
-          for (unsigned int i = 0, dummy = numbers::invalid_unsigned_int;
-               i < send_components.size();
-               ++i)
-            {
-              std::get<5>(send_components[i]) = i;
-
-              if (dummy != std::get<1>(send_components[i]))
-                {
-                  dummy = std::get<1>(send_components[i]);
-                  send_ranks.push_back(dummy);
-                  send_ptrs.push_back(i);
-                }
-            }
-          send_ptrs.push_back(send_components.size());
-
-          // sort according to cell, rank, point index (while keeping
-          // partial ordering)
-          std::sort(send_components.begin(),
-                    send_components.end(),
-                    [&](const auto &a, const auto &b) {
-                      if (std::get<0>(a) != std::get<0>(b))
-                        return std::get<0>(a) < std::get<0>(b); // cell
-
-                      if (std::get<1>(a) != std::get<1>(b))
-                        return std::get<1>(a) < std::get<1>(b); // rank
-
-                      if (std::get<2>(a) != std::get<2>(b))
-                        return std::get<2>(a) < std::get<2>(b); // point index
-
-                      return std::get<5>(a) < std::get<5>(b); // enumeration
-                    });
-        }
-
-      if (perform_handshake)
-        {
-          // sort according to rank (and point index) -> make deterministic
-          std::sort(recv_components.begin(),
-                    recv_components.end(),
-                    [&](const auto &a, const auto &b) {
-                      if (std::get<0>(a) != std::get<0>(b))
-                        return std::get<0>(a) < std::get<0>(b); // rank
-
-                      return std::get<1>(a) < std::get<1>(b); // point index
-                    });
-
-          // perform enumeration and extract rank information
-          for (unsigned int i = 0, dummy = numbers::invalid_unsigned_int;
-               i < recv_components.size();
-               ++i)
-            {
-              std::get<2>(recv_components[i]) = i;
-
-              if (dummy != std::get<0>(recv_components[i]))
-                {
-                  dummy = std::get<0>(recv_components[i]);
-                  recv_ranks.push_back(dummy);
-                  recv_ptrs.push_back(i);
-                }
-            }
-          recv_ptrs.push_back(recv_components.size());
-
-          // sort according to point index and rank (while keeping partial
-          // ordering)
-          std::sort(recv_components.begin(),
-                    recv_components.end(),
-                    [&](const auto &a, const auto &b) {
-                      if (std::get<1>(a) != std::get<1>(b))
-                        return std::get<1>(a) < std::get<1>(b); // point index
-
-                      if (std::get<0>(a) != std::get<0>(b))
-                        return std::get<0>(a) < std::get<0>(b); // rank
-
-                      return std::get<2>(a) < std::get<2>(b); // enumeration
-                    });
-        }
+      result.finalize_setup();
 
       return result;
     }
index ec06814639da6ce96b6c9e52520969dec8576038..9e5d8fe3387b4ac7b9a5a9970fba97ee6e3c9cd9 100644 (file)
@@ -141,6 +141,10 @@ for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
         const std::vector<bool> &marked_vertices,
         const bool               enforce_unique_mapping);
 
+      template struct internal::DistributedComputePointLocationsInternal<
+        deal_II_dimension,
+        deal_II_space_dimension>;
+
       template internal::DistributedComputePointLocationsInternal<
         deal_II_dimension,
         deal_II_space_dimension>

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.