From 24281b7dcc1fa551175e76681f1bbe4b70cbef15 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 8 Aug 2013 22:11:08 +0000 Subject: [PATCH] Document a problem with FiniteElementBase::face_to_cell_index in a couple of different places. Add an assertion. Add two tests. git-svn-id: https://svn.dealii.org/trunk@30260 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/doxygen/headers/glossary.h | 5 +- deal.II/include/deal.II/fe/fe_base.h | 20 +++++++- deal.II/source/fe/fe_data.cc | 9 ++++ tests/fe/face_to_cell_q1_2d.cc | 65 +++++++++++++++++++++++++ tests/fe/face_to_cell_q1_2d/cmp/generic | 21 ++++++++ tests/fe/face_to_cell_q2_2d.cc | 65 +++++++++++++++++++++++++ tests/fe/face_to_cell_q2_2d/cmp/generic | 21 ++++++++ 7 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 tests/fe/face_to_cell_q1_2d.cc create mode 100644 tests/fe/face_to_cell_q1_2d/cmp/generic create mode 100644 tests/fe/face_to_cell_q2_2d.cc create mode 100644 tests/fe/face_to_cell_q2_2d/cmp/generic diff --git a/deal.II/doc/doxygen/headers/glossary.h b/deal.II/doc/doxygen/headers/glossary.h index c9a106b569..a4acb8b8c6 100644 --- a/deal.II/doc/doxygen/headers/glossary.h +++ b/deal.II/doc/doxygen/headers/glossary.h @@ -837,7 +837,10 @@ * is pointing the other direction. There are not very many places in * application programs where you need this information actually, but * a few places in the library make use of this. Note that in 2d, the - * result is always @p true. + * result is always @p true. However, while every face in 2d is always + * in standard orientation, you can sometimes specify something to + * assume that this is not so; an example is the function + * DoFTools::make_periodicity_constraints(). * * There are two other flags that describe the orientation of a face: * face_flip and face_rotation. Some documentation for these diff --git a/deal.II/include/deal.II/fe/fe_base.h b/deal.II/include/deal.II/fe/fe_base.h index f7e0de1021..c317c45b32 100644 --- a/deal.II/include/deal.II/fe/fe_base.h +++ b/deal.II/include/deal.II/fe/fe_base.h @@ -426,7 +426,25 @@ public: * @return The index of this degree of freedom within the set * of degrees of freedom on the entire cell. The returned value * will be between zero and dofs_per_cell. - */ + * + * @note This function exists in this class because that is where it + * was first implemented. However, it can't really work in the most + * general case without knowing what element we have. The reason is that + * when a face is flipped or rotated, we also need to know whether we + * need to swap the degrees of freedom on this face, or whether they + * are immune from this. For this, consider the situation of a $Q_3$ + * element in 2d. If face_flip is true, then we need to consider + * the two degrees of freedom on the edge in reverse order. On the other + * hand, if the element were a $Q_1^2$, then because the two degrees of + * freedom on this edge belong to different vector components, they + * should not be considered in reverse order. What all of this shows is + * that the function can't work if there are more than one degree of + * freedom per line or quad, and that in these cases the function will + * throw an exception pointing out that this functionality will need + * to be provided by a derived class that knows what degrees of freedom + * actually represent. + */ + virtual unsigned int face_to_cell_index (const unsigned int face_dof_index, const unsigned int face, const bool face_orientation = true, diff --git a/deal.II/source/fe/fe_data.cc b/deal.II/source/fe/fe_data.cc index e0873d9ba3..1a0f0b02b8 100644 --- a/deal.II/source/fe/fe_data.cc +++ b/deal.II/source/fe/fe_data.cc @@ -113,6 +113,15 @@ face_to_cell_index (const unsigned int face_index, Assert (face < GeometryInfo::faces_per_cell, ExcIndexRange(face, 0, GeometryInfo::faces_per_cell)); + // see the function's documentation for an explanation of this + // assertion -- in essence, derived classes have to implement + // an overloaded version of this function + Assert ((this->dofs_per_line <= 1) && (this->dofs_per_quad <= 1), + ExcMessage ("The function in this base class can not handle this case. " + "Rather, the derived class you are using must provide " + "an overloaded version but apparently hasn't done so. See " + "the documentation of this function for more information.")); + // DoF on a vertex if (face_index < this->first_face_line_index) { diff --git a/tests/fe/face_to_cell_q1_2d.cc b/tests/fe/face_to_cell_q1_2d.cc new file mode 100644 index 0000000000..da4e1a7217 --- /dev/null +++ b/tests/fe/face_to_cell_q1_2d.cc @@ -0,0 +1,65 @@ +// --------------------------------------------------------------------- +// $Id$ +// +// Copyright (C) 1998 - 2013 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +// it turns out that FE_Q::face_to_cell_index() had a bug for elements beyond +// Q2 when using the face flip flag. this test is for the 2d case for the Q1 +// case + +#include "../tests.h" +#include +#include + +#include +#include + +template +void test() +{ + FE_Q fe(1); + const unsigned int dofs_per_face = fe.dofs_per_face; + + for (unsigned int face=0; face<4; ++face) + { + deallog << "Face=" << face << std::endl; + + for (int flip=0; flip<2; ++flip) + { + deallog << " flip=" << (flip == 0 ? "false" : "true") + << std::endl + << " "; + for (unsigned int i = 0; i < dofs_per_face; ++i) + deallog << fe.face_to_cell_index(i, face, + true, + (flip == 0 ? false : true), + false) << " - "; + deallog << std::endl; + } + } +} + +int main() +{ + std::ofstream logfile("face_to_cell_q1_2d/output"); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + test<2>(); +} + + + diff --git a/tests/fe/face_to_cell_q1_2d/cmp/generic b/tests/fe/face_to_cell_q1_2d/cmp/generic new file mode 100644 index 0000000000..338a958296 --- /dev/null +++ b/tests/fe/face_to_cell_q1_2d/cmp/generic @@ -0,0 +1,21 @@ + +DEAL::Face=0 +DEAL:: flip=false +DEAL:: 0 - 2 - +DEAL:: flip=true +DEAL:: 2 - 0 - +DEAL::Face=1 +DEAL:: flip=false +DEAL:: 1 - 3 - +DEAL:: flip=true +DEAL:: 3 - 1 - +DEAL::Face=2 +DEAL:: flip=false +DEAL:: 0 - 1 - +DEAL:: flip=true +DEAL:: 1 - 0 - +DEAL::Face=3 +DEAL:: flip=false +DEAL:: 2 - 3 - +DEAL:: flip=true +DEAL:: 3 - 2 - diff --git a/tests/fe/face_to_cell_q2_2d.cc b/tests/fe/face_to_cell_q2_2d.cc new file mode 100644 index 0000000000..c261b333c1 --- /dev/null +++ b/tests/fe/face_to_cell_q2_2d.cc @@ -0,0 +1,65 @@ +// --------------------------------------------------------------------- +// $Id$ +// +// Copyright (C) 1998 - 2013 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +// it turns out that FE_Q::face_to_cell_index() had a bug for elements beyond +// Q2 when using the face flip flag. this test is for the 2d case for the Q2 +// case + +#include "../tests.h" +#include +#include + +#include +#include + +template +void test() +{ + FE_Q fe(2); + const unsigned int dofs_per_face = fe.dofs_per_face; + + for (unsigned int face=0; face<4; ++face) + { + deallog << "Face=" << face << std::endl; + + for (int flip=0; flip<2; ++flip) + { + deallog << " flip=" << (flip == 0 ? "false" : "true") + << std::endl + << " "; + for (unsigned int i = 0; i < dofs_per_face; ++i) + deallog << fe.face_to_cell_index(i, face, + true, + (flip == 0 ? false : true), + false) << " - "; + deallog << std::endl; + } + } +} + +int main() +{ + std::ofstream logfile("face_to_cell_q2_2d/output"); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + test<2>(); +} + + + diff --git a/tests/fe/face_to_cell_q2_2d/cmp/generic b/tests/fe/face_to_cell_q2_2d/cmp/generic new file mode 100644 index 0000000000..3cf9017e05 --- /dev/null +++ b/tests/fe/face_to_cell_q2_2d/cmp/generic @@ -0,0 +1,21 @@ + +DEAL::Face=0 +DEAL:: flip=false +DEAL:: 0 - 2 - 4 - +DEAL:: flip=true +DEAL:: 2 - 0 - 4 - +DEAL::Face=1 +DEAL:: flip=false +DEAL:: 1 - 3 - 5 - +DEAL:: flip=true +DEAL:: 3 - 1 - 5 - +DEAL::Face=2 +DEAL:: flip=false +DEAL:: 0 - 1 - 6 - +DEAL:: flip=true +DEAL:: 1 - 0 - 6 - +DEAL::Face=3 +DEAL:: flip=false +DEAL:: 2 - 3 - 7 - +DEAL:: flip=true +DEAL:: 3 - 2 - 7 - -- 2.39.5