From 7bd11063c61bdf3a0072e8d26a5c4b66ef1102c8 Mon Sep 17 00:00:00 2001 From: wolf Date: Fri, 18 Oct 2002 14:55:42 +0000 Subject: [PATCH] Make DoFTools::extract_dofs and DoFTools::count_dofs_per_component work with non-primitive elements. git-svn-id: https://svn.dealii.org/trunk@6690 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/deal.II/include/dofs/dof_tools.h | 79 ++++++-- deal.II/deal.II/source/dofs/dof_tools.cc | 202 ++++++++++++++++--- tests/fe/Makefile | 3 +- tests/fe/anna_3.cc | 135 +++++++++++++ tests/fe/anna_3.checked | 241 +++++++++++++++++++++++ 5 files changed, 610 insertions(+), 50 deletions(-) create mode 100644 tests/fe/anna_3.cc create mode 100644 tests/fe/anna_3.checked diff --git a/deal.II/deal.II/include/dofs/dof_tools.h b/deal.II/deal.II/include/dofs/dof_tools.h index e8409aaab0..336899f67a 100644 --- a/deal.II/deal.II/include/dofs/dof_tools.h +++ b/deal.II/deal.II/include/dofs/dof_tools.h @@ -559,25 +559,53 @@ class DoFTools const unsigned int component = 0); /** - * Extract the indices of the degrees - * of freedom belonging to certain - * components. The bit vector @p{select} - * defines, which components of an - * @ref{FESystem} are to be extracted - * from the @ref{DoFHandler} @p{dof}. The - * respective entries in @p{selected_dofs} - * are then flagged @p{true}, while all - * others are set to @p{false}. + * Extract the indices of the + * degrees of freedom belonging + * to certain vector components + * of a vector-valued finite + * element. The bit vector + * @p{select} defines, which + * components of an + * @ref{FESystem} are to be + * extracted from the + * @ref{DoFHandler} @p{dof}. The + * entries in @p{selected_dofs} + * corresponding to degrees of + * freedom belonging to these + * components are then flagged + * @p{true}, while all others are + * set to @p{false}. * - * The size of @p{component_select} - * shall equal the number of - * components in the finite - * element used by @p{dof}. The - * size of @p{selected_dofs} shall - * equal + * The size of + * @p{component_select} shall + * equal the number of components + * in the finite element used by + * @p{dof}. The size of + * @p{selected_dofs} shall equal * @p{dof_handler.n_dofs()}. Previous * contents of this array or * overwritten. + * + * If the finite element under + * consideration is not + * primitive, that is some or all + * of its shape functions are + * non-zero in more than one + * vector component (which holds, + * for example, for Nedelec or + * Raviart-Thomas elements), then + * shape functions cannot be + * associated with a single + * vector component. In this + * case, if @em{one} shape vector + * component of this element is + * flagged in + * @p{component_select}, then + * this is equivalent to + * selecting @em{all} vector + * components corresponding to + * this non-primitive base + * element. */ template static void @@ -705,8 +733,8 @@ class DoFTools * number belong to each * components. If the number of * components the finite element - * has (i.e. you only have one - * scalar variable), then the + * has is one (i.e. you only have + * one scalar variable), then the * number in this component * obviously equals the total * number of degrees of @@ -715,6 +743,23 @@ class DoFTools * needs to equal the total * number. * + * However, the last statement + * does not hold true if the + * finite element is not + * primitive, i.e. some or all of + * its shape functions are + * non-zero in more than one + * vector component. This + * applies, for example, to the + * Nedelec or Raviart-Thomas + * elements. In this case, a + * degree of freedom is counted + * in each component in which it + * is non-zero, so that the sum + * mentioned above is greater + * than the total number of + * degrees of freedom. + * * The result is returned in the * last argument. */ diff --git a/deal.II/deal.II/source/dofs/dof_tools.cc b/deal.II/deal.II/source/dofs/dof_tools.cc index 03594a9080..080219ddaf 100644 --- a/deal.II/deal.II/source/dofs/dof_tools.cc +++ b/deal.II/deal.II/source/dofs/dof_tools.cc @@ -1050,22 +1050,87 @@ DoFTools::extract_dofs (const DoFHandler &dof, Assert(selected_dofs.size() == dof.n_dofs(), ExcDimensionMismatch(selected_dofs.size(), dof.n_dofs())); + // two special cases: no component + // is selected, and all components + // are selected, both rather + // stupid, but easy to catch + if (std::count (component_select.begin(), component_select.end(), true) + == 0) + { + std::fill_n (selected_dofs.begin(), dof.n_dofs(), false); + return; + }; + if (std::count (component_select.begin(), component_select.end(), true) + == static_cast(component_select.size())) + { + std::fill_n (selected_dofs.begin(), dof.n_dofs(), true); + return; + }; + + // preset all values by false - fill_n (selected_dofs.begin(), dof.n_dofs(), false); + std::fill_n (selected_dofs.begin(), dof.n_dofs(), false); + + // next set up a table for the + // degrees of freedom on each of + // the cells whether it is + // something interesting or not + std::vector local_selected_dofs (fe.dofs_per_cell, false); + for (unsigned int i=0; i indices(fe.dofs_per_cell); - typename DoFHandler::active_cell_iterator c; - for (c = dof.begin_active() ; c != dof.end() ; ++ c) + for (c=dof.begin_active(); c!=dof.end(); ++ c) { c->get_dof_indices(indices); - for (unsigned int i=0;i(component_select.size())) + { + std::fill_n (selected_dofs.begin(), dof.n_dofs(level), true); + return; + }; - std::vector indices(fe.dofs_per_cell); - + // preset all values by false + std::fill_n (selected_dofs.begin(), dof.n_dofs(level), false); + + // next set up a table for the + // degrees of freedom on each of + // the cells whether it is + // something interesting or not + std::vector local_selected_dofs (fe.dofs_per_cell, false); + for (unsigned int i=0; i indices(fe.dofs_per_cell); typename MGDoFHandler::cell_iterator c; for (c = dof.begin(level) ; c != dof.end(level) ; ++ c) { c->get_mg_dof_indices(indices); - for (unsigned int i=0;i &dof_handler, template void -DoFTools::count_dofs_per_component (const DoFHandler &dof_handler, - std::vector &dofs_per_component) +DoFTools:: +count_dofs_per_component (const DoFHandler &dof_handler, + std::vector &dofs_per_component) { const unsigned int n_components = dof_handler.get_fe().n_components(); dofs_per_component.resize (n_components); @@ -1418,17 +1549,19 @@ DoFTools::count_dofs_per_component (const DoFHandler &dof_handler, // otherwise determine the number // of dofs in each component // separately. do so in parallel - std::vector > dofs_in_component (n_components, - std::vector(dof_handler.n_dofs(), - false)); - std::vector > component_select (n_components, - std::vector(n_components, false)); + std::vector > + dofs_in_component (n_components, + std::vector(dof_handler.n_dofs(), false)); + std::vector > + component_select (n_components, + std::vector(n_components, false)); Threads::ThreadManager thread_manager; for (unsigned int i=0; i &, const std::vector &, - std::vector &) = &DoFTools::template extract_dofs; + std::vector &) + = &DoFTools::template extract_dofs; component_select[i][i] = true; Threads::spawn (thread_manager, Threads::encapsulate (fun_ptr) @@ -1443,10 +1576,15 @@ DoFTools::count_dofs_per_component (const DoFHandler &dof_handler, dofs_in_component[i].end(), true); - // finally sanity check - Assert (std::accumulate (dofs_per_component.begin(), dofs_per_component.end(), 0U) - == - dof_handler.n_dofs(), + // finally sanity check. this is + // only valid if the finite element + // is actually primitive, so + // exclude other elements from this + Assert (!dof_handler.get_fe().is_primitive() + || + (std::accumulate (dofs_per_component.begin(), + dofs_per_component.end(), 0U) + == dof_handler.n_dofs()), ExcInternalError()); }; diff --git a/tests/fe/Makefile b/tests/fe/Makefile index d6fcfbdb0b..0e798005c1 100644 --- a/tests/fe/Makefile +++ b/tests/fe/Makefile @@ -41,12 +41,13 @@ transfer.exe : transfer.go $(libraries) up_and_down.exe : up_and_down.go $(libraries) anna_1.exe : anna_1.go $(libraries) anna_2.exe : anna_2.go $(libraries) +anna_3.exe : anna_3.go $(libraries) tests = derivatives fe_data_test fe_traits fe_tools_test mapping \ mapping_c1 shapes numbering mapping_q1_eulerian \ transfer internals \ non_primitive_1 non_primitive_2 \ - nedelec nedelec_2 nedelec_3 up_and_down anna_1 anna_2 + nedelec nedelec_2 nedelec_3 up_and_down anna_1 anna_2 anna_3 ############################################################ diff --git a/tests/fe/anna_3.cc b/tests/fe/anna_3.cc new file mode 100644 index 0000000000..dd1c25db35 --- /dev/null +++ b/tests/fe/anna_3.cc @@ -0,0 +1,135 @@ +//---------------------------- anna_3.cc --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2002 by the deal.II authors and Anna Schneebeli +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- anna_3.cc --------------------------- + + +// check some things about Nedelec elements, here that +// DoFTools::component_select and DoFTools::count_dofs_per_component +// works +// +// this program is a modified version of one by Anna Schneebeli, +// University of Basel + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +template +class SystemTest +{ + public: + SystemTest (); + void run (); + + private: + void make_grid_and_dofs (); + void check (); + + + Triangulation triangulation; + FESystem fe; + DoFHandler dof_handler; + + +}; + +template +SystemTest::SystemTest () : + fe (FE_Nedelec(1), 2, + FE_Q(1), 1), + dof_handler (triangulation) +{}; + + +template +void SystemTest::make_grid_and_dofs () +{ + + GridGenerator::hyper_cube (triangulation, -1, 1); + triangulation.refine_global (0); + deallog << "Number of active cells: " << triangulation.n_active_cells() + << std::endl; + deallog << "Total number of cells: " << triangulation.n_cells() + << std::endl; + + dof_handler.distribute_dofs (fe); + deallog << "Number of degrees of freedom: " << dof_handler.n_dofs() + << std::endl; + +}; + + +template +void SystemTest::check () +{ + for (unsigned int c=0; c x(fe.n_components(), false); + x[c] = true; + std::vector sel(dof_handler.n_dofs()); + DoFTools::extract_dofs (dof_handler, x, sel); + + for (unsigned int i=0; i dofs_per_component (fe.n_components(), 0U); + DoFTools::count_dofs_per_component (dof_handler, dofs_per_component); + deallog << "DoFs per component: "; + for (unsigned int i=0; i +void SystemTest::run () +{ + deallog << "************* " << dim << "D *************" << std::endl; + make_grid_and_dofs (); + check(); + + // renumber degrees of freedom and + // try again + deallog << std::endl << "*** Renumbering ***" << std::endl; + DoFRenumbering::component_wise (dof_handler); + check (); +}; + + + +int main () +{ + std::ofstream logfile("anna_3.output"); + deallog.attach(logfile); + deallog.depth_console(0); + + SystemTest<2>().run(); + SystemTest<3>().run(); + return 0; +}; diff --git a/tests/fe/anna_3.checked b/tests/fe/anna_3.checked new file mode 100644 index 0000000000..6cea739ad1 --- /dev/null +++ b/tests/fe/anna_3.checked @@ -0,0 +1,241 @@ + +DEAL::************* 2D ************* +DEAL::Number of active cells: 1 +DEAL::Total number of cells: 1 +DEAL::Number of degrees of freedom: 12 +DEAL::Checking for component 0 +DEAL:: DoF 4 +DEAL:: DoF 6 +DEAL:: DoF 8 +DEAL:: DoF 10 +DEAL::Checking for component 1 +DEAL:: DoF 4 +DEAL:: DoF 6 +DEAL:: DoF 8 +DEAL:: DoF 10 +DEAL::Checking for component 2 +DEAL:: DoF 5 +DEAL:: DoF 7 +DEAL:: DoF 9 +DEAL:: DoF 11 +DEAL::Checking for component 3 +DEAL:: DoF 5 +DEAL:: DoF 7 +DEAL:: DoF 9 +DEAL:: DoF 11 +DEAL::Checking for component 4 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL::DoFs per component: 4 4 4 4 4 +DEAL:: +DEAL::*** Renumbering *** +DEAL::Checking for component 0 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL::Checking for component 1 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL::Checking for component 2 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL::Checking for component 3 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL::Checking for component 4 +DEAL:: DoF 8 +DEAL:: DoF 9 +DEAL:: DoF 10 +DEAL:: DoF 11 +DEAL::DoFs per component: 4 4 4 4 4 +DEAL::************* 3D ************* +DEAL::Number of active cells: 1 +DEAL::Total number of cells: 1 +DEAL::Number of degrees of freedom: 32 +DEAL::Checking for component 0 +DEAL:: DoF 8 +DEAL:: DoF 10 +DEAL:: DoF 12 +DEAL:: DoF 14 +DEAL:: DoF 16 +DEAL:: DoF 18 +DEAL:: DoF 20 +DEAL:: DoF 22 +DEAL:: DoF 24 +DEAL:: DoF 26 +DEAL:: DoF 28 +DEAL:: DoF 30 +DEAL::Checking for component 1 +DEAL:: DoF 8 +DEAL:: DoF 10 +DEAL:: DoF 12 +DEAL:: DoF 14 +DEAL:: DoF 16 +DEAL:: DoF 18 +DEAL:: DoF 20 +DEAL:: DoF 22 +DEAL:: DoF 24 +DEAL:: DoF 26 +DEAL:: DoF 28 +DEAL:: DoF 30 +DEAL::Checking for component 2 +DEAL:: DoF 8 +DEAL:: DoF 10 +DEAL:: DoF 12 +DEAL:: DoF 14 +DEAL:: DoF 16 +DEAL:: DoF 18 +DEAL:: DoF 20 +DEAL:: DoF 22 +DEAL:: DoF 24 +DEAL:: DoF 26 +DEAL:: DoF 28 +DEAL:: DoF 30 +DEAL::Checking for component 3 +DEAL:: DoF 9 +DEAL:: DoF 11 +DEAL:: DoF 13 +DEAL:: DoF 15 +DEAL:: DoF 17 +DEAL:: DoF 19 +DEAL:: DoF 21 +DEAL:: DoF 23 +DEAL:: DoF 25 +DEAL:: DoF 27 +DEAL:: DoF 29 +DEAL:: DoF 31 +DEAL::Checking for component 4 +DEAL:: DoF 9 +DEAL:: DoF 11 +DEAL:: DoF 13 +DEAL:: DoF 15 +DEAL:: DoF 17 +DEAL:: DoF 19 +DEAL:: DoF 21 +DEAL:: DoF 23 +DEAL:: DoF 25 +DEAL:: DoF 27 +DEAL:: DoF 29 +DEAL:: DoF 31 +DEAL::Checking for component 5 +DEAL:: DoF 9 +DEAL:: DoF 11 +DEAL:: DoF 13 +DEAL:: DoF 15 +DEAL:: DoF 17 +DEAL:: DoF 19 +DEAL:: DoF 21 +DEAL:: DoF 23 +DEAL:: DoF 25 +DEAL:: DoF 27 +DEAL:: DoF 29 +DEAL:: DoF 31 +DEAL::Checking for component 6 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL::DoFs per component: 12 12 12 12 12 12 8 +DEAL:: +DEAL::*** Renumbering *** +DEAL::Checking for component 0 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL:: DoF 8 +DEAL:: DoF 9 +DEAL:: DoF 10 +DEAL:: DoF 11 +DEAL::Checking for component 1 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL:: DoF 8 +DEAL:: DoF 9 +DEAL:: DoF 10 +DEAL:: DoF 11 +DEAL::Checking for component 2 +DEAL:: DoF 0 +DEAL:: DoF 1 +DEAL:: DoF 2 +DEAL:: DoF 3 +DEAL:: DoF 4 +DEAL:: DoF 5 +DEAL:: DoF 6 +DEAL:: DoF 7 +DEAL:: DoF 8 +DEAL:: DoF 9 +DEAL:: DoF 10 +DEAL:: DoF 11 +DEAL::Checking for component 3 +DEAL:: DoF 12 +DEAL:: DoF 13 +DEAL:: DoF 14 +DEAL:: DoF 15 +DEAL:: DoF 16 +DEAL:: DoF 17 +DEAL:: DoF 18 +DEAL:: DoF 19 +DEAL:: DoF 20 +DEAL:: DoF 21 +DEAL:: DoF 22 +DEAL:: DoF 23 +DEAL::Checking for component 4 +DEAL:: DoF 12 +DEAL:: DoF 13 +DEAL:: DoF 14 +DEAL:: DoF 15 +DEAL:: DoF 16 +DEAL:: DoF 17 +DEAL:: DoF 18 +DEAL:: DoF 19 +DEAL:: DoF 20 +DEAL:: DoF 21 +DEAL:: DoF 22 +DEAL:: DoF 23 +DEAL::Checking for component 5 +DEAL:: DoF 12 +DEAL:: DoF 13 +DEAL:: DoF 14 +DEAL:: DoF 15 +DEAL:: DoF 16 +DEAL:: DoF 17 +DEAL:: DoF 18 +DEAL:: DoF 19 +DEAL:: DoF 20 +DEAL:: DoF 21 +DEAL:: DoF 22 +DEAL:: DoF 23 +DEAL::Checking for component 6 +DEAL:: DoF 24 +DEAL:: DoF 25 +DEAL:: DoF 26 +DEAL:: DoF 27 +DEAL:: DoF 28 +DEAL:: DoF 29 +DEAL:: DoF 30 +DEAL:: DoF 31 +DEAL::DoFs per component: 12 12 12 12 12 12 8 -- 2.39.5