From 6a66088a7c0e97c2c4545e1b2e8c278c3f2d09b5 Mon Sep 17 00:00:00 2001 From: bangerth Date: Thu, 29 Aug 2013 22:10:55 +0000 Subject: [PATCH] No longer use DoFObjects for the hp DoFs on cells. This will make things a bit simpler and allow for some code simplification. git-svn-id: https://svn.dealii.org/trunk@30527 0785d39b-7218-0410-832d-ea1e28bc413d --- .../deal.II/dofs/dof_accessor.templates.h | 30 +- deal.II/include/deal.II/hp/dof_levels.h | 389 +++++++++++++++++- deal.II/source/hp/dof_handler.cc | 36 +- deal.II/source/hp/dof_levels.cc | 5 +- 4 files changed, 421 insertions(+), 39 deletions(-) diff --git a/deal.II/include/deal.II/dofs/dof_accessor.templates.h b/deal.II/include/deal.II/dofs/dof_accessor.templates.h index 989591f843..3f1bedb386 100644 --- a/deal.II/include/deal.II/dofs/dof_accessor.templates.h +++ b/deal.II/include/deal.II/dofs/dof_accessor.templates.h @@ -476,7 +476,7 @@ namespace internal const unsigned int local_index, const dealii::internal::int2type<1> &) { - return dof_handler.levels[obj_level]->dof_object. + return dof_handler.levels[obj_level]-> get_dof_index (dof_handler, obj_index, fe_index, @@ -496,7 +496,7 @@ namespace internal const dealii::internal::int2type<1> &, const types::global_dof_index global_index) { - dof_handler.levels[obj_level]->dof_object. + dof_handler.levels[obj_level]-> set_dof_index (dof_handler, obj_index, fe_index, @@ -556,7 +556,7 @@ namespace internal const unsigned int local_index, const dealii::internal::int2type<2> &) { - return dof_handler.levels[obj_level]->dof_object. + return dof_handler.levels[obj_level]-> get_dof_index (dof_handler, obj_index, fe_index, @@ -576,7 +576,7 @@ namespace internal const dealii::internal::int2type<2> &, const types::global_dof_index global_index) { - dof_handler.levels[obj_level]->dof_object. + dof_handler.levels[obj_level]-> set_dof_index (dof_handler, obj_index, fe_index, @@ -676,7 +676,7 @@ namespace internal const unsigned int local_index, const dealii::internal::int2type<3> &) { - return dof_handler.levels[obj_level]->dof_object. + return dof_handler.levels[obj_level]-> get_dof_index (dof_handler, obj_index, fe_index, @@ -696,7 +696,7 @@ namespace internal const dealii::internal::int2type<3> &, const types::global_dof_index global_index) { - dof_handler.levels[obj_level]->dof_object. + dof_handler.levels[obj_level]-> set_dof_index (dof_handler, obj_index, fe_index, @@ -825,7 +825,7 @@ namespace internal const unsigned int fe_index, const dealii::internal::int2type<1> &) { - return dof_handler.levels[obj_level]->dof_object.fe_index_is_active(dof_handler, + return dof_handler.levels[obj_level]->fe_index_is_active(dof_handler, obj_index, fe_index, obj_level); @@ -840,7 +840,7 @@ namespace internal const unsigned int obj_index, const dealii::internal::int2type<1> &) { - return dof_handler.levels[obj_level]->dof_object.n_active_fe_indices (dof_handler, + return dof_handler.levels[obj_level]->n_active_fe_indices (dof_handler, obj_index); } @@ -855,7 +855,7 @@ namespace internal const unsigned int n, const dealii::internal::int2type<1> &) { - return dof_handler.levels[obj_level]->dof_object.nth_active_fe_index (dof_handler, + return dof_handler.levels[obj_level]->nth_active_fe_index (dof_handler, obj_level, obj_index, n); @@ -917,7 +917,7 @@ namespace internal const unsigned int fe_index, const dealii::internal::int2type<2> &) { - return dof_handler.levels[obj_level]->dof_object.fe_index_is_active(dof_handler, + return dof_handler.levels[obj_level]->fe_index_is_active(dof_handler, obj_index, fe_index, obj_level); @@ -932,7 +932,7 @@ namespace internal const unsigned int obj_index, const dealii::internal::int2type<2> &) { - return dof_handler.levels[obj_level]->dof_object.n_active_fe_indices (dof_handler, + return dof_handler.levels[obj_level]->n_active_fe_indices (dof_handler, obj_index); } @@ -947,7 +947,7 @@ namespace internal const unsigned int n, const dealii::internal::int2type<2> &) { - return dof_handler.levels[obj_level]->dof_object.nth_active_fe_index (dof_handler, + return dof_handler.levels[obj_level]->nth_active_fe_index (dof_handler, obj_level, obj_index, n); @@ -1026,7 +1026,7 @@ namespace internal const unsigned int fe_index, const dealii::internal::int2type<3> &) { - return dof_handler.levels[obj_level]->dof_object.fe_index_is_active(dof_handler, + return dof_handler.levels[obj_level]->fe_index_is_active(dof_handler, obj_index, fe_index, obj_level); @@ -1072,7 +1072,7 @@ namespace internal const unsigned int obj_index, const dealii::internal::int2type<3> &) { - return dof_handler.levels[obj_level]->dof_object.n_active_fe_indices (dof_handler, + return dof_handler.levels[obj_level]->n_active_fe_indices (dof_handler, obj_index); } @@ -1087,7 +1087,7 @@ namespace internal const unsigned int n, const dealii::internal::int2type<3> &) { - return dof_handler.levels[obj_level]->dof_object.nth_active_fe_index (dof_handler, + return dof_handler.levels[obj_level]->nth_active_fe_index (dof_handler, obj_level, obj_index, n); diff --git a/deal.II/include/deal.II/hp/dof_levels.h b/deal.II/include/deal.II/hp/dof_levels.h index 19d9f7e33d..9ac98d14d2 100644 --- a/deal.II/include/deal.II/hp/dof_levels.h +++ b/deal.II/include/deal.II/hp/dof_levels.h @@ -94,7 +94,7 @@ namespace internal * * Access to this kind of data, as well as the distinction between * cells and objects of lower dimensionality are encoded in the - * accessor functions, DoFObjects::set_dof_index() and + * accessor functions, DoFLevel::set_dof_index() and * DoFLevel::get_dof_index() They are able to traverse this * list and pick out or set a DoF index given the finite element index * and its location within the set of DoFs corresponding to this @@ -125,10 +125,139 @@ namespace internal std::vector active_fe_indices; /** - * Store the dof-indices and related data of - * the cells on the current level corresponding to this object. + * Store the start index for + * the degrees of freedom of each + * object in the @p dofs array. + * + * The type we store is then obviously the type the @p dofs array + * uses for indexing. */ - internal::hp::DoFObjects dof_object; + std::vector::size_type> dof_offsets; + + /** + * Store the global indices of + * the degrees of freedom. See + * DoFLevel() for detailed + * information. + */ + std::vector dofs; + + /** + * Set the global index of + * the @p local_index-th + * degree of freedom located + * on the object with number @p + * obj_index to the value + * given by @p global_index. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, denotes which of + * the finite elements + * associated with this + * object we shall + * access. Refer to the + * general documentation of + * the internal::hp::DoFLevel + * class template for more + * information. + */ + template + void + set_dof_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const types::global_dof_index global_index, + const unsigned int obj_level); + + /** + * Return the global index of + * the @p local_index-th + * degree of freedom located + * on the object with number @p + * obj_index. The @p + * dof_handler argument is + * used to access the finite + * element that is to be used + * to compute the location + * where this data is stored. + * + * The third argument, @p + * fe_index, denotes which of + * the finite elements + * associated with this + * object we shall + * access. Refer to the + * general documentation of + * the internal::hp::DoFLevel + * class template for more + * information. + */ + template + types::global_dof_index + get_dof_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const; + + /** + * Return the number of + * finite elements that are + * active on a given + * object. If this is a cell, + * the answer is of course + * one. If it is a face, the + * answer may be one or two, + * depending on whether the + * two adjacent cells use the + * same finite element or + * not. If it is an edge in + * 3d, the possible return + * value may be one or any + * other value larger than + * that. + * + * If the object is not part + * of an active cell, then no + * degrees of freedom have + * been distributed and zero + * is returned. + */ + template + unsigned int + n_active_fe_indices (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index) const; + + /** + * Return the fe_index of the + * n-th active finite element + * on this object. + */ + template + types::global_dof_index + nth_active_fe_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int n) const; + + /** + * Check whether a given + * finite element index is + * used on the present + * object or not. + */ + template + bool + fe_index_is_active (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const; /** * Determine an estimate for the @@ -137,6 +266,258 @@ namespace internal */ std::size_t memory_consumption () const; }; + + + // -------------------- template functions -------------------------------- + + template + template + inline + types::global_dof_index + DoFLevel:: + get_dof_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const unsigned int obj_level) const + { + Assert ((fe_index != dealii::hp::DoFHandler::default_fe_index), + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < + dof_handler.get_fe()[fe_index].template n_dofs_per_object(), + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index] + .template n_dofs_per_object())); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != numbers::invalid_dof_index, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + if (dim == dimm) + { + // if we are on a cell, then + // the only set of indices we + // store is the one for the + // cell, which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + return dofs[dof_offsets[obj_index]+local_index]; + } + else + { + Assert (false, ExcInternalError()); + return 0; + } + } + + + + template + template + inline + void + DoFLevel:: + set_dof_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int local_index, + const types::global_dof_index global_index, + const unsigned int obj_level) + { + Assert ((fe_index != dealii::hp::DoFHandler::default_fe_index), + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + Assert (local_index < + dof_handler.get_fe()[fe_index].template n_dofs_per_object(), + ExcIndexRange(local_index, 0, + dof_handler.get_fe()[fe_index] + .template n_dofs_per_object())); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != numbers::invalid_dof_index, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + if (dim == dimm) + { + // if we are on a cell, then + // the only set of indices we + // store is the one for the + // cell, which is unique. then + // fe_index must be + // active_fe_index + Assert (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index], + ExcMessage ("FE index does not match that of the present cell")); + dofs[dof_offsets[obj_index]+local_index] = global_index; + } + else + { + Assert (false, ExcInternalError()); + } + } + + + + template + template + inline + unsigned int + DoFLevel:: + n_active_fe_indices (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index) const + { + Assert (dim <= dimm, ExcInternalError()); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + if (dof_offsets[obj_index] == numbers::invalid_dof_index) + return 0; + + // if we are on a cell, then the + // only set of indices we store + // is the one for the cell, + // which is unique + if (dim == dimm) + return 1; + else + { + Assert (false, ExcInternalError()); + return 0; + } + } + + + + template + template + inline + types::global_dof_index + DoFLevel:: + nth_active_fe_index (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_level, + const unsigned int obj_index, + const unsigned int n) const + { + Assert (dim <= dimm, ExcInternalError()); + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, dof_offsets.size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != numbers::invalid_dof_index, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + if (dim == dimm) + { + // this is a cell, so there + // is only a single + // fe_index + Assert (n == 0, ExcIndexRange (n, 0, 1)); + + return dof_handler.levels[obj_level]->active_fe_indices[obj_index]; + } + else + { + Assert (false, ExcInternalError()); + return 0; + } + } + + + + template + template + inline + bool + DoFLevel:: + fe_index_is_active (const dealii::hp::DoFHandler &dof_handler, + const unsigned int obj_index, + const unsigned int fe_index, + const unsigned int obj_level) const + { + Assert (&dof_handler != 0, + ExcMessage ("No DoFHandler is specified for this iterator")); + Assert (&dof_handler.get_fe() != 0, + ExcMessage ("No finite element collection is associated with " + "this DoFHandler")); + Assert (obj_index < dof_offsets.size(), + ExcIndexRange (obj_index, 0, static_cast(dof_offsets.size()))); + Assert ((fe_index != dealii::hp::DoFHandler::default_fe_index), + ExcMessage ("You need to specify a FE index when working " + "with hp DoFHandlers")); + Assert (fe_index < dof_handler.get_fe().size(), + ExcIndexRange (fe_index, 0, dof_handler.get_fe().size())); + + // make sure we are on an + // object for which DoFs have + // been allocated at all + Assert (dof_offsets[obj_index] != numbers::invalid_dof_index, + ExcMessage ("You are trying to access degree of freedom " + "information for an object on which no such " + "information is available")); + + if (dim == dimm) + { + // if we are on a cell, + // then the only set of + // indices we store is the + // one for the cell, which + // is unique + Assert (obj_index < dof_handler.levels[obj_level]->active_fe_indices.size(), + ExcInternalError()); + return (fe_index == dof_handler.levels[obj_level]->active_fe_indices[obj_index]); + } + else + { + Assert (false, ExcInternalError()); + return false; + } + } + } // namespace hp } // namespace internal diff --git a/deal.II/source/hp/dof_handler.cc b/deal.II/source/hp/dof_handler.cc index 205071413e..5881e47859 100644 --- a/deal.II/source/hp/dof_handler.cc +++ b/deal.II/source/hp/dof_handler.cc @@ -576,7 +576,7 @@ namespace internal // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - dof_handler.levels[level]->dof_object.dof_offsets + dof_handler.levels[level]->dof_offsets = std::vector::size_type> ( dof_handler.tria->n_raw_lines(level), DoFHandler::invalid_dof_index); @@ -587,11 +587,11 @@ namespace internal cell!=dof_handler.end_active(level); ++cell) if (!cell->has_children()) { - dof_handler.levels[level]->dof_object.dof_offsets[cell->index()] = next_free_dof; + dof_handler.levels[level]->dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_line; } - dof_handler.levels[level]->dof_object.dofs + dof_handler.levels[level]->dofs = std::vector (next_free_dof, DoFHandler::invalid_dof_index); } @@ -613,11 +613,11 @@ namespace internal if (!cell->has_children()) counter += cell->get_fe().dofs_per_line; - Assert (dof_handler.levels[level]->dof_object.dofs.size() == counter, + Assert (dof_handler.levels[level]->dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (dof_handler.levels[level]->dof_object.dof_offsets.begin(), - dof_handler.levels[level]->dof_object.dof_offsets.end(), + (std::count (dof_handler.levels[level]->dof_offsets.begin(), + dof_handler.levels[level]->dof_offsets.end(), DoFHandler::invalid_dof_index)) == dof_handler.tria->n_raw_lines(level) - dof_handler.tria->n_active_lines(level), @@ -693,7 +693,7 @@ namespace internal // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - dof_handler.levels[level]->dof_object.dof_offsets + dof_handler.levels[level]->dof_offsets = std::vector::size_type> ( dof_handler.tria->n_raw_quads(level), DoFHandler::invalid_dof_index); @@ -704,11 +704,11 @@ namespace internal cell!=dof_handler.end_active(level); ++cell) if (!cell->has_children()) { - dof_handler.levels[level]->dof_object.dof_offsets[cell->index()] = next_free_dof; + dof_handler.levels[level]->dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_quad; } - dof_handler.levels[level]->dof_object.dofs + dof_handler.levels[level]->dofs = std::vector (next_free_dof, DoFHandler::invalid_dof_index); } @@ -730,11 +730,11 @@ namespace internal if (!cell->has_children()) counter += cell->get_fe().dofs_per_quad; - Assert (dof_handler.levels[level]->dof_object.dofs.size() == counter, + Assert (dof_handler.levels[level]->dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (dof_handler.levels[level]->dof_object.dof_offsets.begin(), - dof_handler.levels[level]->dof_object.dof_offsets.end(), + (std::count (dof_handler.levels[level]->dof_offsets.begin(), + dof_handler.levels[level]->dof_offsets.end(), DoFHandler::invalid_dof_index)) == dof_handler.tria->n_raw_quads(level) - dof_handler.tria->n_active_quads(level), @@ -1059,7 +1059,7 @@ namespace internal // finite element is used for it for (unsigned int level=0; leveln_levels(); ++level) { - dof_handler.levels[level]->dof_object.dof_offsets + dof_handler.levels[level]->dof_offsets = std::vector::size_type> (dof_handler.tria->n_raw_hexs(level), DoFHandler::invalid_dof_index); @@ -1070,11 +1070,11 @@ namespace internal cell!=dof_handler.end_active(level); ++cell) if (!cell->has_children()) { - dof_handler.levels[level]->dof_object.dof_offsets[cell->index()] = next_free_dof; + dof_handler.levels[level]->dof_offsets[cell->index()] = next_free_dof; next_free_dof += cell->get_fe().dofs_per_hex; } - dof_handler.levels[level]->dof_object.dofs + dof_handler.levels[level]->dofs = std::vector (next_free_dof, DoFHandler::invalid_dof_index); } @@ -1096,11 +1096,11 @@ namespace internal if (!cell->has_children()) counter += cell->get_fe().dofs_per_hex; - Assert (dof_handler.levels[level]->dof_object.dofs.size() == counter, + Assert (dof_handler.levels[level]->dofs.size() == counter, ExcInternalError()); Assert (static_cast - (std::count (dof_handler.levels[level]->dof_object.dof_offsets.begin(), - dof_handler.levels[level]->dof_object.dof_offsets.end(), + (std::count (dof_handler.levels[level]->dof_offsets.begin(), + dof_handler.levels[level]->dof_offsets.end(), DoFHandler::invalid_dof_index)) == dof_handler.tria->n_raw_hexs(level) - dof_handler.tria->n_active_hexs(level), diff --git a/deal.II/source/hp/dof_levels.cc b/deal.II/source/hp/dof_levels.cc index ff5dc868b1..6e28511809 100644 --- a/deal.II/source/hp/dof_levels.cc +++ b/deal.II/source/hp/dof_levels.cc @@ -27,8 +27,9 @@ namespace internal std::size_t DoFLevel::memory_consumption () const { - return MemoryConsumption::memory_consumption (active_fe_indices) + - MemoryConsumption::memory_consumption (dof_object); + return (MemoryConsumption::memory_consumption (active_fe_indices) + + MemoryConsumption::memory_consumption (dofs) + + MemoryConsumption::memory_consumption (dof_offsets)); } -- 2.39.5