From: wolf Date: Tue, 9 Mar 2004 17:33:34 +0000 (+0000) Subject: More stuff for subdomain handling. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cff710451fddf52af0b9ca7d5489770b0127a4f6;p=dealii-svn.git More stuff for subdomain handling. git-svn-id: https://svn.dealii.org/trunk@8704 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/deal.II/include/dofs/dof_renumbering.h b/deal.II/deal.II/include/dofs/dof_renumbering.h index 3741c050a9..b3e138faa0 100644 --- a/deal.II/deal.II/include/dofs/dof_renumbering.h +++ b/deal.II/deal.II/include/dofs/dof_renumbering.h @@ -235,7 +235,7 @@ class DoFRenumbering */ template static void - compute_Cuthill_McKee (std::vector&, + compute_Cuthill_McKee (std::vector& new_dof_indices, const DoFHandler&, const bool reversed_numbering = false, const bool use_constraints = false, @@ -352,7 +352,7 @@ class DoFRenumbering */ template static unsigned int - compute_component_wise (std::vector& new_index, + compute_component_wise (std::vector& new_dof_indices, ITERATOR& start, const ENDITERATOR& end, const std::vector &target_component); @@ -393,7 +393,7 @@ class DoFRenumbering */ template static void - compute_cell_wise_dg (std::vector&, + compute_cell_wise_dg (std::vector &new_dof_indices, const DoFHandler &dof_handler, const std::vector::cell_iterator> &cell_order); @@ -467,7 +467,7 @@ class DoFRenumbering */ template static void - compute_downstream_dg (std::vector&, + compute_downstream_dg (std::vector &new_dof_indices, const DoFHandler &dof_handler, const Point &direction); @@ -516,7 +516,7 @@ class DoFRenumbering */ template static void - compute_clockwise_dg (std::vector&, + compute_clockwise_dg (std::vector &new_dof_indices, const DoFHandler &dof_handler, const Point ¢er, const bool counter); @@ -551,7 +551,7 @@ class DoFRenumbering */ template static void - compute_sort_selected_dofs_back (std::vector&, + compute_sort_selected_dofs_back (std::vector &new_dof_indices, const DoFHandler&, const std::vector&selected_dofs); @@ -574,9 +574,57 @@ class DoFRenumbering */ template static void - compute_random (std::vector&, + compute_random (std::vector &new_dof_indices, const DoFHandler &dof_handler); + /** + * Renumber the degrees of freedom such + * that they are associated with the + * subdomain id of the cells they are + * living on, i.e. first all degrees of + * freedom that belong to cells with + * subdomain zero, then all with + * subdomain one, etc. This is useful + * when doing parallel computations after + * assigning subdomain ids using a + * partitioner (see the + * @p{GridTools::partition_triangulation} + * function for this). + * + * Note that degrees of freedom + * associated with faces, edges, and + * vertices may be associated with + * multiple subdomains if they are + * sitting on partition boundaries. It + * would therefore be undefined with + * which subdomain they have to be + * associated. For this, we use what we + * get from the + * @p{DoFTools::get_subdomain_association} + * function. + * + * The algorithm is stable, i.e. if + * two dofs i,j have @p{i + static void + subdomain_wise (DoFHandler &dof_handler); + + /** + * Computes the renumbering vector needed + * by the @p{subdomain_wise} + * function. Does not perform the + * renumbering on the @p{DoFHandler} dofs + * but returns the renumbering vector. + */ + template + static void + compute_subdomain_wise (std::vector &new_dof_indices, + const DoFHandler &dof_handler); + /** * Exception */ diff --git a/deal.II/deal.II/include/dofs/dof_tools.h b/deal.II/deal.II/include/dofs/dof_tools.h index 2f05695365..1f860573e7 100644 --- a/deal.II/deal.II/include/dofs/dof_tools.h +++ b/deal.II/deal.II/include/dofs/dof_tools.h @@ -761,12 +761,50 @@ class DoFTools * freedom are not mutually * exclusive for different * subdomain ids. + * + * If you want to get a unique + * association of degree of freedom with + * subdomains, use the + * @p{get_subdomain_association} + * function. */ template static void extract_subdomain_dofs (const DoFHandler &dof_handler, const unsigned int subdomain_id, std::vector &selected_dofs); + + /** + * For each DoF, return in the output + * array to which subdomain (as given by + * the @p{cell->subdomain_id()} function) + * it belongs. The output array is + * supposed to have the right size + * already when calling this function. + * + * Note that degrees of freedom + * associated with faces, edges, and + * vertices may be associated with + * multiple subdomains if they are + * sitting on partition boundaries. In + * these cases, we put them into one of + * the associated partitions in an + * undefined way. This may sometimes lead + * to different numbers of degrees of + * freedom in partitions, even if the + * number of cells is perfectly + * equidistributed. While this is + * regrettable, it is not a problem in + * practice since the number of degrees + * of freedom on partition boundaries is + * asymptotically vanishing as we refine + * the mesh as long as the number of + * partitions is kept constant. + */ + template + static void + get_subdomain_association (const DoFHandler &dof_handler, + std::vector &subdomain); /** * Count how many degrees of diff --git a/deal.II/deal.II/source/dofs/dof_renumbering.cc b/deal.II/deal.II/source/dofs/dof_renumbering.cc index 1ea8ed5348..befe26f954 100644 --- a/deal.II/deal.II/source/dofs/dof_renumbering.cc +++ b/deal.II/deal.II/source/dofs/dof_renumbering.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -498,9 +498,9 @@ void DoFRenumbering::Cuthill_McKee ( template void -DoFRenumbering::component_wise ( - DoFHandler &dof_handler, - const std::vector &component_order_arg) +DoFRenumbering:: +component_wise (DoFHandler &dof_handler, + const std::vector &component_order_arg) { std::vector renumbering (dof_handler.n_dofs(), DoFHandler::invalid_dof_index); @@ -531,10 +531,10 @@ DoFRenumbering::component_wise ( template -void DoFRenumbering::component_wise ( - MGDoFHandler& dof_handler, - unsigned int level, - const std::vector &component_order_arg) +void DoFRenumbering:: +component_wise (MGDoFHandler &dof_handler, + const unsigned int level, + const std::vector &component_order_arg) { std::vector renumbering (dof_handler.n_dofs(level), DoFHandler::invalid_dof_index); @@ -566,11 +566,11 @@ void DoFRenumbering::component_wise ( template unsigned int -DoFRenumbering::compute_component_wise ( - std::vector& new_indices, - ITERATOR& start, - const ENDITERATOR& end, - const std::vector &component_order_arg) +DoFRenumbering:: +compute_component_wise (std::vector& new_indices, + ITERATOR& start, + const ENDITERATOR& end, + const std::vector &component_order_arg) { // Modify for hp const FiniteElement& fe = start->get_fe(); @@ -1104,9 +1104,8 @@ DoFRenumbering::random (DoFHandler &dof_handler) template void -DoFRenumbering::compute_random ( - std::vector& new_indices, - const DoFHandler &dof_handler) +DoFRenumbering::compute_random (std::vector &new_indices, + const DoFHandler &dof_handler) { const unsigned int n_dofs = dof_handler.n_dofs(); Assert(new_indices.size() == n_dofs, @@ -1120,6 +1119,68 @@ DoFRenumbering::compute_random ( +template +void +DoFRenumbering::subdomain_wise (DoFHandler &dof_handler) +{ + std::vector renumbering(dof_handler.n_dofs(), + DoFHandler::invalid_dof_index); + compute_subdomain_wise(renumbering, dof_handler); + + dof_handler.renumber_dofs(renumbering); +} + + +template +void +DoFRenumbering:: +compute_subdomain_wise (std::vector &new_dof_indices, + const DoFHandler &dof_handler) +{ + const unsigned int n_dofs = dof_handler.n_dofs(); + Assert (new_dof_indices.size() == n_dofs, + ExcDimensionMismatch (new_dof_indices.size(), n_dofs)); + + // first get the association of each dof + // with a subdomain and determine the total + // number of subdomain ids used + std::vector subdomain_association (n_dofs); + DoFTools::get_subdomain_association (dof_handler, + subdomain_association); + const unsigned int n_subdomains + = *std::max_element (subdomain_association.begin(), + subdomain_association.end()) + 1; + + // then renumber the subdomains by first + // looking at those belonging to subdomain + // 0, then those of subdomain 1, etc. note + // that the algorithm is stable, i.e. if + // two dofs i,j have i (DoFHandler &); +template +void DoFRenumbering::subdomain_wise +(DoFHandler &); + template void DoFRenumbering::compute_random (std::vector&, const DoFHandler &); +template +void +DoFRenumbering::compute_subdomain_wise +(std::vector&, + const DoFHandler &); + template void DoFRenumbering::Cuthill_McKee (MGDoFHandler&, diff --git a/deal.II/deal.II/source/dofs/dof_tools.cc b/deal.II/deal.II/source/dofs/dof_tools.cc index 36be5668be..f3f04aa07e 100644 --- a/deal.II/deal.II/source/dofs/dof_tools.cc +++ b/deal.II/deal.II/source/dofs/dof_tools.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 by the deal.II authors +// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -1648,16 +1648,13 @@ DoFTools::extract_subdomain_dofs (const DoFHandler &dof_handler, { Assert(selected_dofs.size() == dof_handler.n_dofs(), ExcDimensionMismatch(selected_dofs.size(), dof_handler.n_dofs())); - // preset all values by false + + // preset all values by false std::fill_n (selected_dofs.begin(), dof_handler.n_dofs(), false); const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell; std::vector local_dof_indices (dofs_per_cell); - // this function is similar to the - // make_sparsity_pattern function, - // see there for more information - typename DoFHandler::active_cell_iterator cell = dof_handler.begin_active(), endc = dof_handler.end(); @@ -1672,6 +1669,52 @@ DoFTools::extract_subdomain_dofs (const DoFHandler &dof_handler, +template +void +DoFTools:: +get_subdomain_association (const DoFHandler &dof_handler, + std::vector &subdomain_association) +{ + Assert(subdomain_association.size() == dof_handler.n_dofs(), + ExcDimensionMismatch(subdomain_association.size(), + dof_handler.n_dofs())); + + // preset all values by an invalid value + std::fill_n (subdomain_association.begin(), dof_handler.n_dofs(), + deal_II_numbers::invalid_unsigned_int); + + const unsigned int dofs_per_cell = dof_handler.get_fe().dofs_per_cell; + std::vector local_dof_indices (dofs_per_cell); + + // this function is similar to the + // make_sparsity_pattern function, + // see there for more information + + typename DoFHandler::active_cell_iterator + cell = dof_handler.begin_active(), + endc = dof_handler.end(); + for (; cell!=endc; ++cell) + { + const unsigned int subdomain_id = cell->subdomain_id(); + cell->get_dof_indices (local_dof_indices); + + // set subdomain ids. if dofs already + // have their values set then they must + // be on partition interfaces. don't + // worry about that, just overwrite it + for (unsigned int i=0; i void DoFTools:: @@ -2989,6 +3032,12 @@ DoFTools::extract_subdomain_dofs const unsigned int subdomain_id, std::vector &selected_dofs); +template +void +DoFTools::get_subdomain_association +(const DoFHandler &dof_handler, + std::vector &subdomain_association); + template void