The (hp::)DoFHandler::n_boundary_dofs() functions were specialized for
the 1d case back in the day when faces in 1d were not usable the same
way faces in 2d/3d were accessible via iterators. Because C++ doesn't
allow partial specialization of member functions, the code was also
replicated three times for the <1,1>, <1,2>, and <1,3> cases.
Fix this: We can now always use the generic approach since the necessary
iterators were added several years ago. This also fixes a bug: in <1,2>
and <1,3>, we allow triangulations to have more than 2 end points,
which the existing code was not equipped to deal with.
David Wells [Sat, 8 Jul 2017 18:25:06 +0000 (14:25 -0400)]
Change MappingManifold<1, spacedim> to use face manifolds.
As of db5ea0f52db we support get_manifold on 1D manifolds, so we can look up the
manifold on a 1D face in a dimension-independent way. This is a slight change
from the current behavior, but using Manifolds in 1D is a very obscure use case.
David Wells [Fri, 7 Jul 2017 23:52:28 +0000 (19:52 -0400)]
de-templatize SparsityPattern::copy_from.
This template is instantiated for only SparsityPattern and is overloaded for
DynamicSparsityPattern, so it is a bit simpler to just overload a non-template
method.
Simplify the template signature of DoFRenumbering::compute_component_wise().
We previously had two template arguments because the types of, for example,
DoFHandler::begin_active() and DoFHandler::end() are different. But this makes
no sense. Just cast the end iterator to the same type as the begin iterator.
David Wells [Fri, 7 Jul 2017 19:23:41 +0000 (15:23 -0400)]
Add a more general fallthrough attribute.
GCC7 raises implicit fallthrough warnings in a lot of places when we
compile without C++17 support. This patch adds a second check for the
GCC extension `__attribute__((fallthrough))` that works in C++11 and
C++14 and fixes these warnings.
The TODO isn't really addressed, but previous to #4560, the functions
in question simply did the wrong thing, whereas since #4560, we at
least get an ExcNotImplemented().
The DoF indices for a vertex are stored in an array where we just
collate the indices for each level. There is currently another
array that stors the offset within this array where the DoFs
for a given level start. This array is dynamically allocated,
but it is altogether unnecessary because the offsets are computable:
they are simply the number of the multigrid level times
dofs_per_vertex.
Consequently, get rid of the array and replace it by storing dofs_per_vertex.
We can then easily compute the starting offset wherever necessary, rather than
having to look it up.
The hp DoF renumbering function for the <3,3> case was unnecessarily
convoluted because it tried to look just like the functions that
deal with faces of higher dimensional cells. But we know that in <3,3>,
a hex is a cell, and so there can only be one finite element associated
with the cell. This allows simplifying a fair share of code.
Currently, the code is duplicated between the DoFHandler and the policy
class. This makes no sense, and indeed the policy class code is more
evolved, so let the former call the latter following exposing the
interface in the previous patch.
The existing code in DoFHandler looks like it did not actually support
parallel triangulations (either shared or distributed). This was
probably a bug, and consequently the implementation of the functionality
in the ParallelDistributed policy class now just throws an error.
This relates to the discussion in #4559.
The previous refactoring allows parallelizing renumbering for vertices,
cells, and faces, since these all work on mutually independent data
structures.
The 1d, 2d, and 3d implementations of these functions had most of their code
duplicated. This can be done more elegantly by instead splitting the code into
vertices, cells, and faces. The main function then becomes dimension independent,
as are the functions dealing with vertices and cells, and only the face function
requires dimensional specialization.
Make the DoFHandler a template type of the Sequential policy.
Also adjust all of the places where the class is used.
This change by itself is not useful, but will become useful when also
using the policy class from hp::DoFHandler. Similar changes will at a
later time be made for the ParallelShared and ParallelDistributed
policies.
When distributing MG DoF indices, we accidentally used 'unsigned int'
instead of 'types::global_dof_index'. That's a bug. We didn't notice
this because we never have more than 4B unknowns on one processor,
and the function was only called in the parallel context to enumerate
the DoFs on the *local* portion of the mesh, before indices were
shifted after communication with other processors. Regardless, it's
worth fixing.
We had a function with a funny comment suggesting that a compiler did not
correctly understand the code. But the comment is wrong: when the only
argument to a function that references a 'dim' or 'spacedim' template
argument is of the form
onst typename DoFHandler<dim,spacedim>::level_cell_iterator &
then 'dim' and 'spacedim' are simply not deducible. That's how C++ works.
The function therefore had a dummy argument of type DoFHandler<dim,spacedim>
that isn't used. That's awkward, but works. But we have a way to deal
with the lack of deducibility that's used elsewhere in the library
namely internal::int2type. Use this approach here as well, and remove
the misleading comment.