From 4f96f0cbb06e34c4d05aaa1092b59e76d9cfe8ab Mon Sep 17 00:00:00 2001 From: goll Date: Wed, 6 Jul 2011 16:14:35 +0000 Subject: [PATCH] Implement DoFTools::count_dofs_per_component also for hp::DoFhandler. git-svn-id: https://svn.dealii.org/trunk@23924 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 5 + deal.II/include/deal.II/dofs/dof_tools.h | 6 +- deal.II/source/dofs/dof_tools.cc | 114 ++++++++++++++---- deal.II/source/dofs/dof_tools.inst.in | 28 ++++- tests/bits/count_dofs_per_component_hp.cc | 83 +++++++++++++ .../count_dofs_per_component_hp/cmp/generic | 19 +++ 6 files changed, 221 insertions(+), 34 deletions(-) create mode 100644 tests/bits/count_dofs_per_component_hp.cc create mode 100644 tests/bits/count_dofs_per_component_hp/cmp/generic diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index 8a0a0fe2ba..1dbab530f8 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -216,6 +216,11 @@ should be fixed now.

Specific improvements

    +
  1. New: The function DoFTools::count_dofs_per_component now also works +for objects of type hp::DoFHandler. +
    +(Christian Goll, Wolfgang Bangerth 2011/07/06) +
  2. Fixed: Under some circumstances, the Threads::Thread::join() could only be called once and would generate a system exception when called a second time. Since it is often useful to not track whether this function had already been diff --git a/deal.II/include/deal.II/dofs/dof_tools.h b/deal.II/include/deal.II/dofs/dof_tools.h index 26585a2193..2f9b90f2b3 100644 --- a/deal.II/include/deal.II/dofs/dof_tools.h +++ b/deal.II/include/deal.II/dofs/dof_tools.h @@ -1580,9 +1580,9 @@ namespace DoFTools * targetted by target_components * are left untouched. */ - template + template void - count_dofs_per_component (const DoFHandler& dof_handler, + count_dofs_per_component (const DH & dof_handler, std::vector& dofs_per_component, const bool vector_valued_once = false, std::vector target_component @@ -2100,7 +2100,7 @@ namespace DoFTools std::vector > dof_couplings_from_component_couplings (const hp::FECollection &fe, const Table<2,Coupling> &component_couplings); - + /** * Exception */ diff --git a/deal.II/source/dofs/dof_tools.cc b/deal.II/source/dofs/dof_tools.cc index 56003aa3f4..335931698d 100644 --- a/deal.II/source/dofs/dof_tools.cc +++ b/deal.II/source/dofs/dof_tools.cc @@ -51,7 +51,7 @@ DEAL_II_NAMESPACE_OPEN namespace DoFTools { - + template void make_sparsity_pattern (const DH &dof, @@ -732,14 +732,14 @@ namespace DoFTools return return_value; } - + namespace internal { - namespace + namespace { - + // implementation of the same function in // namespace DoFTools for non-hp // DoFHandlers @@ -972,7 +972,7 @@ namespace DoFTools } } } - + // implementation of the same function in // namespace DoFTools for non-hp @@ -1166,14 +1166,14 @@ namespace DoFTools } } } - + } template - void + void make_flux_sparsity_pattern (const DH &dof, SparsityPattern &sparsity, const Table<2,Coupling> &int_mask, @@ -1199,7 +1199,7 @@ namespace DoFTools Assert (flux_mask.n_cols() == n_comp, ExcDimensionMismatch (flux_mask.n_cols(), n_comp)); - + // Clear user flags because we will // need them. But first we save // them and make sure that we @@ -1214,7 +1214,7 @@ namespace DoFTools internal::make_flux_sparsity_pattern (dof, sparsity, int_mask, flux_mask); - + // finally restore the user flags const_cast &>(dof.get_tria()).load_user_flags(user_flags); } @@ -2710,7 +2710,7 @@ namespace DoFTools == FiniteElementDomination::no_requirements) continue; - + // Same procedure as for the // mother cell. Extract the face // DoFs from the cell DoFs. @@ -3245,7 +3245,7 @@ namespace DoFTools // nothing to do here break; } - + default: // we shouldn't get // here @@ -4085,7 +4085,7 @@ namespace DoFTools template void - + extract_hanging_node_dofs (const DoFHandler &dof_handler, std::vector &selected_dofs) { @@ -4470,6 +4470,10 @@ namespace DoFTools namespace internal { +//TODO: why is this function so complicated? It would be nice to have +// comments that explain why we can't just loop over all components +// and count the entries in dofs_by_component that have this +// component's index template void resolve_components (const FiniteElement&fe, @@ -4509,18 +4513,78 @@ namespace DoFTools } } } + + template + void + resolve_components (const hp::FECollection&fe_collection, + const std::vector &dofs_by_component, + const std::vector &target_component, + const bool only_once, + std::vector &dofs_per_component, + unsigned int &component) + { + // assert that all elements in the collection have the same + // structure (base elements and multiplicity, components per base + // element) and then simply call the function above + for (unsigned int fe=1; fe + namespace internal + { + namespace { + /** + * Return true if the given element is primitive. + */ + template + bool all_elements_are_primitive (const FiniteElement &fe) + { + return fe.is_primitive(); + } + + + /** + * Return true if each element of the given element collection is primitive. + */ + template + bool all_elements_are_primitive (const dealii::hp::FECollection &fe_collection) + { + for (unsigned int i=0; i void count_dofs_per_component ( - const DoFHandler& dof_handler, + const DH & dof_handler, std::vector& dofs_per_component, bool only_once, std::vector target_component) { - const FiniteElement& fe = dof_handler.get_fe(); + const unsigned int n_components = dof_handler.get_fe().n_components(); std::fill (dofs_per_component.begin(), dofs_per_component.end(), 0U); @@ -4529,21 +4593,20 @@ namespace DoFTools // vector as identity. if (target_component.size()==0) { - target_component.resize(fe.n_components()); - for (unsigned int i=0; i * tria - = (dynamic_cast*> + if (const parallel::distributed::Triangulation * tria + = (dynamic_cast*> (&dof_handler.get_tria()))) { std::vector local_dof_count = dofs_per_component; @@ -4601,7 +4665,7 @@ namespace DoFTools template - void + void count_dofs_per_block (const DoFHandler& dof_handler, std::vector &dofs_per_block, std::vector target_block) diff --git a/deal.II/source/dofs/dof_tools.inst.in b/deal.II/source/dofs/dof_tools.inst.in index ddabf8f8c2..28287e1cf9 100644 --- a/deal.II/source/dofs/dof_tools.inst.in +++ b/deal.II/source/dofs/dof_tools.inst.in @@ -487,20 +487,36 @@ DoFTools::count_dofs_with_subdomain_association template void -DoFTools::count_dofs_per_component ( +DoFTools::count_dofs_per_component > ( const DoFHandler&, std::vector&, bool, std::vector); -#if deal_II_dimension < 3 -template void DoFTools::extract_level_dofs -(const unsigned int level, const MGDoFHandler&, - const std::vector&, std::vector&, bool); +template +void +DoFTools::count_dofs_per_component > ( + const hp::DoFHandler&, + std::vector&, bool, std::vector); + +#if deal_II_dimension < 3 template void -DoFTools::count_dofs_per_component ( +DoFTools::count_dofs_per_component > ( const DoFHandler&, std::vector&, bool, std::vector); + +template +void +DoFTools::count_dofs_per_component > ( + const hp::DoFHandler&, + std::vector&, bool, std::vector); + +template +void +DoFTools::extract_level_dofs +(const unsigned int level, const MGDoFHandler&, + const std::vector&, std::vector&, bool); + #endif template diff --git a/tests/bits/count_dofs_per_component_hp.cc b/tests/bits/count_dofs_per_component_hp.cc new file mode 100644 index 0000000000..184f1397ec --- /dev/null +++ b/tests/bits/count_dofs_per_component_hp.cc @@ -0,0 +1,83 @@ +//---------------------------------------------------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2003, 2004, 2005, 2009 by the deal.II authors +// +// 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. +// +//---------------------------------------------------------------------- + +#include "../tests.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// check +// DoFTools:: +// count_dofs_per_component (...); +// for the hp case + + +using namespace std; + +template +void test () +{ + Triangulation triangulation; + GridGenerator::hyper_cube(triangulation); + triangulation.refine_global(3); + + //define DoFhandler and FEs + FE_Q u(2); + FE_Q p(1); + + FESystem fe_system(u, 2, p, 1); + + hp::FECollection fe_collection; + fe_collection.push_back(fe_system); + + hp::DoFHandler hp_dof_handler(triangulation); + DoFHandler dof_handler(triangulation); + + //distribute dofs + hp_dof_handler.distribute_dofs(fe_collection); + dof_handler.distribute_dofs(fe_system); + + //count dofs per component and show them on the screen + std::vector dofs_per_component(3,0); + std::vector dofs_per_component_hp(3,0); + DoFTools::count_dofs_per_component(dof_handler, dofs_per_component); + DoFTools::count_dofs_per_component(hp_dof_handler, dofs_per_component_hp); + + for (unsigned int i=0; i<3; i++) + { + deallog <<"DoFs in the " < (); + test<2> (); + test<3> (); + return 0; +} diff --git a/tests/bits/count_dofs_per_component_hp/cmp/generic b/tests/bits/count_dofs_per_component_hp/cmp/generic new file mode 100644 index 0000000000..d51c9477d2 --- /dev/null +++ b/tests/bits/count_dofs_per_component_hp/cmp/generic @@ -0,0 +1,19 @@ + +DEAL::DoFs in the 0. component for classical FE: 17 +DEAL::DoFs in the 0. component for hp FE: 17 +DEAL::DoFs in the 1. component for classical FE: 17 +DEAL::DoFs in the 1. component for hp FE: 17 +DEAL::DoFs in the 2. component for classical FE: 9 +DEAL::DoFs in the 2. component for hp FE: 9 +DEAL::DoFs in the 0. component for classical FE: 289 +DEAL::DoFs in the 0. component for hp FE: 289 +DEAL::DoFs in the 1. component for classical FE: 289 +DEAL::DoFs in the 1. component for hp FE: 289 +DEAL::DoFs in the 2. component for classical FE: 81 +DEAL::DoFs in the 2. component for hp FE: 81 +DEAL::DoFs in the 0. component for classical FE: 4913 +DEAL::DoFs in the 0. component for hp FE: 4913 +DEAL::DoFs in the 1. component for classical FE: 4913 +DEAL::DoFs in the 1. component for hp FE: 4913 +DEAL::DoFs in the 2. component for classical FE: 729 +DEAL::DoFs in the 2. component for hp FE: 729 -- 2.39.5