From ff563e37a90532059f1fe4f4a2c7b3255db61c9f Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Thu, 24 Sep 2015 15:44:44 +0200 Subject: [PATCH] Implementation of DoFTools::locally_relevant_dofs_per_subdomain. Also added Denis' authorship for DofTools::locally_owned_dofs_per_subdomain --- doc/news/changes.h | 7 ++++ include/deal.II/dofs/dof_tools.h | 20 ++++++++++++ source/dofs/dof_tools.cc | 55 ++++++++++++++++++++++++++++++++ source/dofs/dof_tools.inst.in | 27 ++++++++++++++++ 4 files changed, 109 insertions(+) diff --git a/doc/news/changes.h b/doc/news/changes.h index 673990896e..5984fc3f59 100644 --- a/doc/news/changes.h +++ b/doc/news/changes.h @@ -356,6 +356,13 @@ inconvenience this causes.
    +
  1. Added: DoFTools::locally_relevant_dofs_per_subdomain can be used + to extract an IndexSet of locally relevant DoFs for a Triangulation + partitioned using METIS or with a parallel::shared::Triangulation . +
    + (Jean-Paul Pelteret, 2015/09/24) +
  2. +
  3. Fixed: hp::SolutionTransfer could get confused when dealing with FE_Nothing elements. This is now fixed.
    diff --git a/include/deal.II/dofs/dof_tools.h b/include/deal.II/dofs/dof_tools.h index f4922d3b79..729dcb0420 100644 --- a/include/deal.II/dofs/dof_tools.h +++ b/include/deal.II/dofs/dof_tools.h @@ -1427,11 +1427,31 @@ namespace DoFTools * we do not have information about all cells of the triangulation available locally, * and consequently can not say anything definitive about the degrees of freedom active on other * processors' locally owned cells. + * + * @author Denis Davydov, 2015 */ template std::vector locally_owned_dofs_per_subdomain (const DH &dof_handler); + /** + * + * For each processor, determine the set of locally relevant degrees of freedom as an IndexSet. + * This function then returns a vector of index sets, where the vector has size equal to the + * number of MPI processes that participate in the DoF handler object. + * + * The function can be used for objects of type dealii::Triangulation or parallel::shared::Triangulation. + * It will not work for objects of type parallel::distributed::Triangulation since for such triangulations + * we do not have information about all cells of the triangulation available locally, + * and consequently can not say anything definitive about the degrees of freedom active on other + * processors' locally owned cells. + * + * @author Jean-Paul Pelteret, 2015 + */ + template + std::vector + locally_relevant_dofs_per_subdomain (const DH &dof_handler); + /** * For each DoF, return in the output array to which subdomain (as given by * the cell->subdomain_id() function) it belongs. The output array diff --git a/source/dofs/dof_tools.cc b/source/dofs/dof_tools.cc index 12665d0565..16c0e42cd9 100644 --- a/source/dofs/dof_tools.cc +++ b/source/dofs/dof_tools.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -1123,6 +1124,60 @@ namespace DoFTools return index_sets; } + template + std::vector + locally_relevant_dofs_per_subdomain (const DH &dof_handler) + { + // Collect all the locally owned DoFs + // Note: Even though the distribution of DoFs by the locally_owned_dofs_per_subdomain + // function is pseudo-random, we will collect all the DoFs on the subdomain + // and its layer cell. Therefore, the random nature of this function does + // not play a role in the extraction of the locally relevant DoFs + std::vector dof_set = locally_owned_dofs_per_subdomain(dof_handler); + const dealii::types::subdomain_id n_subdomains = dof_set.size(); + + // Add the DoFs on the adjacent (equivalent ghost) cells to the IndexSet, + // cache them in a set. Need to check each DoF manually because we can't + // be sure that the DoF range of locally_owned_dofs is really contiguous. + for (dealii::types::subdomain_id subdomain_id = 0; + subdomain_id < n_subdomains; ++subdomain_id) + { + // Extract the layer of cells around this subdomain + std_cxx11::function predicate + = IteratorFilters::SubdomainEqualTo(subdomain_id); + const std::vector + active_halo_layer = GridTools::compute_active_cell_halo_layer (dof_handler, + predicate); + + // Extract DoFs associated with halo layer + std::vector local_dof_indices; + std::set subdomain_halo_global_dof_indices; + for (typename std::vector::const_iterator + it_cell = active_halo_layer.begin(); it_cell!=active_halo_layer.end(); ++it_cell) + { + const typename DH::active_cell_iterator &cell = *it_cell; + Assert(cell->subdomain_id() != subdomain_id, + ExcMessage("The subdomain ID of the halo cell should not match that of the vector entry.")); + + local_dof_indices.resize(cell->get_fe().dofs_per_cell); + cell->get_dof_indices(local_dof_indices); + + for (std::vector::iterator it=local_dof_indices.begin(); + it!=local_dof_indices.end(); + ++it) + if (!dof_set[subdomain_id].is_element(*it)) + subdomain_halo_global_dof_indices.insert(*it); + } + + dof_set[subdomain_id].add_indices(subdomain_halo_global_dof_indices.begin(), + subdomain_halo_global_dof_indices.end()); + + dof_set[subdomain_id].compress(); + } + + return dof_set; + } + template void get_subdomain_association (const DH &dof_handler, diff --git a/source/dofs/dof_tools.inst.in b/source/dofs/dof_tools.inst.in index 0ac9e83efb..607b040036 100644 --- a/source/dofs/dof_tools.inst.in +++ b/source/dofs/dof_tools.inst.in @@ -279,6 +279,15 @@ std::vector DoFTools::locally_owned_dofs_per_subdomain > (const hp::DoFHandler &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const DoFHandler &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const hp::DoFHandler &dof_handler); + template unsigned int DoFTools::count_dofs_with_subdomain_association > @@ -380,6 +389,15 @@ std::vector DoFTools::locally_owned_dofs_per_subdomain > (const hp::DoFHandler &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const DoFHandler &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const hp::DoFHandler &dof_handler); + template void DoFTools::count_dofs_with_subdomain_association > @@ -425,6 +443,15 @@ std::vector DoFTools::locally_owned_dofs_per_subdomain > (const hp::DoFHandler<1,3> &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const DoFHandler<1,3> &dof_handler); +template +std::vector +DoFTools::locally_relevant_dofs_per_subdomain > +(const hp::DoFHandler<1,3> &dof_handler); + template unsigned int DoFTools::count_dofs_with_subdomain_association > -- 2.39.5