]> https://gitweb.dealii.org/ - dealii.git/commitdiff
hp::DoFHandler: Provide own CoarseningStrategy while transferring active_fe_indices... 8637/head
authormarcfehling <marc.fehling@gmx.net>
Fri, 23 Aug 2019 00:35:40 +0000 (02:35 +0200)
committerMarc Fehling <marc.fehling@gmx.net>
Sun, 25 Aug 2019 13:23:33 +0000 (15:23 +0200)
source/hp/dof_handler.cc
tests/mpi/solution_transfer_05.cc [new file with mode: 0644]
tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=1.output [new file with mode: 0644]
tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=2.output [new file with mode: 0644]
tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=4.output [new file with mode: 0644]

index c4b84a7b47c89773447996d351414f97cb6bcd81..db2a3296607b79b58cd1088a59f379e3ea7d7760 100644 (file)
@@ -37,8 +37,6 @@
 #include <deal.II/hp/dof_handler.h>
 #include <deal.II/hp/dof_level.h>
 
-#include <deal.II/numerics/coarsening_strategies.h>
-
 #include <boost/serialization/array.hpp>
 
 #include <algorithm>
@@ -1228,6 +1226,40 @@ namespace internal
               cell->set_active_fe_index(coarsen.second);
             }
         }
+
+
+        /**
+         * Coarsening strategy for the CellDataTransfer object responsible for
+         * tranferring the active_fe_index of each cell on
+         * parallel::distributed::Triangulation objects that have been refined.
+         *
+         * A finite element index needs to be determined for the (not yet
+         * active) parent cell from its (still active) children.  Out of the set
+         * of elements previously assigned to the former children, we choose the
+         * one dominated by all children for the parent cell.
+         */
+        template <int dim, int spacedim>
+        static unsigned int
+        determine_fe_from_children(
+          const std::vector<unsigned int> &        children_fe_indices,
+          dealii::hp::FECollection<dim, spacedim> &fe_collection)
+        {
+          Assert(!children_fe_indices.empty(), ExcInternalError());
+
+          // convert vector to set
+          const std::set<unsigned int> children_fe_indices_set(
+            children_fe_indices.begin(), children_fe_indices.end());
+
+          const unsigned int dominated_fe_index =
+            fe_collection.find_dominated_fe_extended(children_fe_indices_set,
+                                                     /*codim=*/0);
+
+          Assert(dominated_fe_index != numbers::invalid_unsigned_int,
+                 typename dealii::hp::FECollection<
+                   dim>::ExcNoDominatedFiniteElementAmongstChildren());
+
+          return dominated_fe_index;
+        }
       };
     } // namespace DoFHandlerImplementation
   }   // namespace hp
@@ -2041,45 +2073,21 @@ namespace hp
         active_fe_index_transfer =
           std_cxx14::make_unique<ActiveFEIndexTransfer>();
 
-        // First, do what we would do in the sequential case.
-        dealii::internal::hp::DoFHandlerImplementation::Implementation::
-          collect_fe_indices_on_cells_to_be_refined(*this);
-
         // If we work on a p::d::Triangulation, we have to transfer all
         // active_fe_indices since ownership of cells may change. We will
         // use our p::d::CellDataTransfer member to achieve this. Further,
         // we prepare the values in such a way that they will correspond to
         // the active_fe_indices on the new mesh.
 
-        // Gather all current active_fe_indices.
-        get_active_fe_indices(active_fe_index_transfer->active_fe_indices);
-
-        // Overwrite active_fe_indices of cells that change by either
-        // h/p refinement/coarsening.
-        for (const auto &pair :
-             active_fe_index_transfer->persisting_cells_fe_index)
-          active_fe_index_transfer
-            ->active_fe_indices[pair.first->active_cell_index()] = pair.second;
-
-        for (const auto &pair :
-             active_fe_index_transfer->refined_cells_fe_index)
-          active_fe_index_transfer
-            ->active_fe_indices[pair.first->active_cell_index()] = pair.second;
-
-        for (const auto &pair :
-             active_fe_index_transfer->coarsened_cells_fe_index)
-          for (unsigned int child_index = 0;
-               child_index < pair.first->n_children();
-               ++child_index)
-            {
-              // Make sure that all children belong to the same subdomain.
-              Assert(pair.first->child(child_index)->is_locally_owned(),
-                     ExcInternalError());
+        // Gather all current future_fe_indices.
+        active_fe_index_transfer->active_fe_indices.resize(
+          get_triangulation().n_active_cells(), numbers::invalid_unsigned_int);
 
-              active_fe_index_transfer
-                ->active_fe_indices[pair.first->child(child_index)
-                                      ->active_cell_index()] = pair.second;
-            }
+        for (const auto &cell : active_cell_iterators())
+          if (cell->is_locally_owned())
+            active_fe_index_transfer
+              ->active_fe_indices[cell->active_cell_index()] =
+              cell->future_fe_index();
 
         // Create transfer object and attach to it.
         const auto *distributed_tria = dynamic_cast<
@@ -2091,7 +2099,10 @@ namespace hp
             CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
           *distributed_tria,
           /*transfer_variable_size_data=*/false,
-          &CoarseningStrategies::check_equality<unsigned int>);
+          std::bind(&dealii::internal::hp::DoFHandlerImplementation::
+                      Implementation::determine_fe_from_children<dim, spacedim>,
+                    std::placeholders::_1,
+                    std::ref(fe_collection)));
 
         active_fe_index_transfer->cell_data_transfer
           ->prepare_for_coarsening_and_refinement(
@@ -2198,7 +2209,10 @@ namespace hp
             CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
           *distributed_tria,
           /*transfer_variable_size_data=*/false,
-          &CoarseningStrategies::check_equality<unsigned int>);
+          std::bind(&dealii::internal::hp::DoFHandlerImplementation::
+                      Implementation::determine_fe_from_children<dim, spacedim>,
+                    std::placeholders::_1,
+                    std::ref(fe_collection)));
 
         // If we work on a p::d::Triangulation, we have to transfer all
         // active fe indices since ownership of cells may change.
@@ -2271,7 +2285,10 @@ namespace hp
             CellDataTransfer<dim, spacedim, std::vector<unsigned int>>>(
           *distributed_tria,
           /*transfer_variable_size_data=*/false,
-          &CoarseningStrategies::check_equality<unsigned int>);
+          std::bind(&dealii::internal::hp::DoFHandlerImplementation::
+                      Implementation::determine_fe_from_children<dim, spacedim>,
+                    std::placeholders::_1,
+                    std::ref(fe_collection)));
 
         // Unpack active_fe_indices.
         active_fe_index_transfer->active_fe_indices.resize(
diff --git a/tests/mpi/solution_transfer_05.cc b/tests/mpi/solution_transfer_05.cc
new file mode 100644 (file)
index 0000000..cdc4a8a
--- /dev/null
@@ -0,0 +1,127 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 1998 - 2018 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.
+//
+// ---------------------------------------------------------------------
+
+
+
+#include <deal.II/base/function.h>
+
+#include <deal.II/distributed/solution_transfer.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/dofs/dof_accessor.h>
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/fe/fe_dgq.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/hp/dof_handler.h>
+#include <deal.II/hp/fe_collection.h>
+
+#include <deal.II/lac/la_parallel_vector.h>
+
+#include <deal.II/numerics/vector_tools.h>
+
+#include <iostream>
+#include <vector>
+
+#include "../tests.h"
+
+
+template <int dim>
+void
+transfer(std::ostream &out)
+{
+  parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+  GridGenerator::hyper_cube(tria);
+  tria.refine_global(2);
+
+  const unsigned int    max_degree = 6 - dim;
+  hp::FECollection<dim> fe_dgq;
+  for (unsigned int deg = 1; deg <= max_degree; ++deg)
+    fe_dgq.push_back(FE_Q<dim>(deg));
+
+  hp::DoFHandler<dim> dgq_dof_handler(tria);
+
+  // randomly assign FE orders
+  for (const auto &cell : dgq_dof_handler.active_cell_iterators())
+    if (cell->is_locally_owned())
+      cell->set_active_fe_index(Testing::rand() % max_degree);
+  dgq_dof_handler.distribute_dofs(fe_dgq);
+
+  IndexSet dgq_locally_owned_dofs = dgq_dof_handler.locally_owned_dofs();
+  IndexSet dgq_locally_relevant_dofs;
+  dealii::DoFTools::extract_locally_relevant_dofs(dgq_dof_handler,
+                                                  dgq_locally_relevant_dofs);
+  IndexSet dgq_ghost_dofs = dgq_locally_relevant_dofs;
+  dgq_ghost_dofs.subtract_set(dgq_locally_owned_dofs);
+
+  LinearAlgebra::distributed::Vector<double> dgq_solution;
+  dgq_solution.reinit(dgq_locally_owned_dofs, dgq_ghost_dofs, MPI_COMM_WORLD);
+
+  VectorTools::interpolate(dgq_dof_handler, ZeroFunction<dim>(), dgq_solution);
+
+  parallel::distributed::SolutionTransfer<
+    dim,
+    LinearAlgebra::distributed::Vector<double>,
+    hp::DoFHandler<dim>>
+    dgq_soltrans(dgq_dof_handler);
+
+  LinearAlgebra::distributed::Vector<double> dgq_old_solution = dgq_solution;
+  dgq_old_solution.update_ghost_values();
+  {
+    unsigned int counter = 0;
+    for (auto cell = tria.begin_active(); cell != tria.end(); ++cell, ++counter)
+      if (cell->is_locally_owned())
+        {
+          if (counter > ((dim == 2) ? 4 : 8))
+            cell->set_coarsen_flag();
+          else
+            cell->set_refine_flag();
+        }
+  }
+
+  tria.prepare_coarsening_and_refinement();
+  dgq_soltrans.prepare_for_coarsening_and_refinement(dgq_old_solution);
+  tria.execute_coarsening_and_refinement();
+
+  dgq_dof_handler.distribute_dofs(fe_dgq);
+
+  dgq_locally_owned_dofs = dgq_dof_handler.locally_owned_dofs();
+  dealii::DoFTools::extract_locally_relevant_dofs(dgq_dof_handler,
+                                                  dgq_locally_relevant_dofs);
+  dgq_ghost_dofs = dgq_locally_relevant_dofs;
+  dgq_ghost_dofs.subtract_set(dgq_locally_owned_dofs);
+
+  dgq_solution.reinit(dgq_locally_owned_dofs, dgq_ghost_dofs, MPI_COMM_WORLD);
+  dgq_soltrans.interpolate(dgq_solution);
+
+  deallog << "OK" << std::endl;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+  Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+  MPILogInitAll                    log;
+
+  deallog.push("2d");
+  transfer<2>(deallog.get_file_stream());
+  deallog.pop();
+  deallog.push("3d");
+  transfer<3>(deallog.get_file_stream());
+  deallog.pop();
+}
diff --git a/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=1.output b/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=1.output
new file mode 100644 (file)
index 0000000..995f6e4
--- /dev/null
@@ -0,0 +1,3 @@
+
+DEAL:0:2d::OK
+DEAL:0:3d::OK
diff --git a/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=2.output b/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=2.output
new file mode 100644 (file)
index 0000000..4aa9062
--- /dev/null
@@ -0,0 +1,7 @@
+
+DEAL:0:2d::OK
+DEAL:0:3d::OK
+
+DEAL:1:2d::OK
+DEAL:1:3d::OK
+
diff --git a/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=4.output b/tests/mpi/solution_transfer_05.with_p4est=true.with_trilinos=true.mpirun=4.output
new file mode 100644 (file)
index 0000000..c0650f6
--- /dev/null
@@ -0,0 +1,15 @@
+
+DEAL:0:2d::OK
+DEAL:0:3d::OK
+
+DEAL:1:2d::OK
+DEAL:1:3d::OK
+
+
+DEAL:2:2d::OK
+DEAL:2:3d::OK
+
+
+DEAL:3:2d::OK
+DEAL:3:3d::OK
+

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.