From 642db8de91ffa5342d8d12cd3799ef6d3ab71973 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Sat, 10 Aug 2013 11:44:30 +0000 Subject: [PATCH] Implement face_to_cell_index() also for FESystem. git-svn-id: https://svn.dealii.org/trunk@30277 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/doc/news/changes.h | 14 ++++- deal.II/include/deal.II/fe/fe_system.h | 42 ++++++++++++++ deal.II/source/fe/fe_system.cc | 39 +++++++++++++ tests/fe/face_to_cell_q2xq2_2d.cc | 67 ++++++++++++++++++++++ tests/fe/face_to_cell_q2xq2_2d/cmp/generic | 21 +++++++ tests/fe/face_to_cell_q3xq4_2d.cc | 67 ++++++++++++++++++++++ tests/fe/face_to_cell_q3xq4_2d/cmp/generic | 21 +++++++ 7 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 tests/fe/face_to_cell_q2xq2_2d.cc create mode 100644 tests/fe/face_to_cell_q2xq2_2d/cmp/generic create mode 100644 tests/fe/face_to_cell_q3xq4_2d.cc create mode 100644 tests/fe/face_to_cell_q3xq4_2d/cmp/generic diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index ad91e1e985..b02cded52b 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -1,5 +1,5 @@ /** - * @page changes_after_8_0 Changes after Version 8.0 +// * @page changes_after_8_0 Changes after Version 8.0

This is the list of changes made after the release of @@ -54,6 +54,18 @@ back already. Please use FiniteElement::face_to_cell_index() instead.

Specific improvements

    +
  1. + Fixed: The FiniteElement::face_to_cell_index() function had a bug + that made it work incorrectly for elements that have more than one + degree of freedom per line (in 2d) or per quad (in 3d). This is now + fixed for the most common cases, namely the FE_Q elements as well + as elements composed of FESystem elements. For all other cases, an + exception is generated reporting that this case is not implemented. + If you run into this, let us know. +
    + (Wolfgang Bangerth, 2013/08/10) +
  2. +
  3. New: DataOutBase::VtkFlags now has a flag DataOutBase::VtkFlags::print_date_and_time that can be used to suppress output diff --git a/deal.II/include/deal.II/fe/fe_system.h b/deal.II/include/deal.II/fe/fe_system.h index 96a0d2dfbd..083a167da2 100644 --- a/deal.II/include/deal.II/fe/fe_system.h +++ b/deal.II/include/deal.II/fe/fe_system.h @@ -413,6 +413,48 @@ public: get_prolongation_matrix (const unsigned int child, const RefinementCase &refinement_case=RefinementCase::isotropic_refinement) const; + /** + * Given an index in the natural ordering of indices on a face, return the + * index of the same degree of freedom on the cell. + * + * To explain the concept, consider the case where we would like to know + * whether a degree of freedom on a face, for example as part of an FESystem + * element, is primitive. Unfortunately, the + * is_primitive() function in the FiniteElement class takes a cell index, so + * we would need to find the cell index of the shape function that + * corresponds to the present face index. This function does that. + * + * Code implementing this would then look like this: + * @code + * for (i=0; i } +template +unsigned int +FESystem:: +face_to_cell_index (const unsigned int face_dof_index, + const unsigned int face, + const bool face_orientation, + const bool face_flip, + const bool face_rotation) const +{ + // we need to ask the base elements how they want to translate + // the DoFs within their own numbering. thus, translate to + // the base element numbering and then back + const std::pair, unsigned int> + face_base_index = this->face_system_to_base_index(face_dof_index); + + const unsigned int + base_face_to_cell_index + = this->base_element(face_base_index.first.first).face_to_cell_index (face_base_index.second, + face, + face_orientation, + face_flip, + face_rotation); + + // it would be nice if we had a base_to_system_index function, but + // all that exists is a component_to_system_index function. we can't do + // this here because it won't work for non-primitive elements. consequently, + // simply do a loop over all dofs till we find whether it corresponds + // to the one we're interested in -- crude, maybe, but works for now + const std::pair, unsigned int> + target = std::make_pair (face_base_index.first, base_face_to_cell_index); + for (unsigned int i=0; idofs_per_cell; ++i) + if (this->system_to_base_index(i) == target) + return i; + + Assert (false, ExcInternalError()); + return numbers::invalid_unsigned_int; +} + + //--------------------------------------------------------------------------- // Data field initialization diff --git a/tests/fe/face_to_cell_q2xq2_2d.cc b/tests/fe/face_to_cell_q2xq2_2d.cc new file mode 100644 index 0000000000..a515f9aff6 --- /dev/null +++ b/tests/fe/face_to_cell_q2xq2_2d.cc @@ -0,0 +1,67 @@ +// --------------------------------------------------------------------- +// $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 +// Q2XQ2 when using the face flip flag. this test is for the 2d case for the Q2XQ2 +// case + +#include "../tests.h" +#include +#include + +#include +#include +#include + +template +void test() +{ + FESystem fe(FE_Q(2), 1, + FE_Q(2), 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_q2xq2_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_q2xq2_2d/cmp/generic b/tests/fe/face_to_cell_q2xq2_2d/cmp/generic new file mode 100644 index 0000000000..15b96ad51f --- /dev/null +++ b/tests/fe/face_to_cell_q2xq2_2d/cmp/generic @@ -0,0 +1,21 @@ + +DEAL::Face=0 +DEAL:: flip=false +DEAL:: 0 - 1 - 4 - 5 - 8 - 9 - +DEAL:: flip=true +DEAL:: 4 - 5 - 0 - 1 - 8 - 9 - +DEAL::Face=1 +DEAL:: flip=false +DEAL:: 2 - 3 - 6 - 7 - 10 - 11 - +DEAL:: flip=true +DEAL:: 6 - 7 - 2 - 3 - 10 - 11 - +DEAL::Face=2 +DEAL:: flip=false +DEAL:: 0 - 1 - 2 - 3 - 12 - 13 - +DEAL:: flip=true +DEAL:: 2 - 3 - 0 - 1 - 12 - 13 - +DEAL::Face=3 +DEAL:: flip=false +DEAL:: 4 - 5 - 6 - 7 - 14 - 15 - +DEAL:: flip=true +DEAL:: 6 - 7 - 4 - 5 - 14 - 15 - diff --git a/tests/fe/face_to_cell_q3xq4_2d.cc b/tests/fe/face_to_cell_q3xq4_2d.cc new file mode 100644 index 0000000000..52c059e5ec --- /dev/null +++ b/tests/fe/face_to_cell_q3xq4_2d.cc @@ -0,0 +1,67 @@ +// --------------------------------------------------------------------- +// $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 Q3XQ4 +// case + +#include "../tests.h" +#include +#include + +#include +#include +#include + +template +void test() +{ + FESystem fe(FE_Q(3), 1, + FE_Q(4), 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_q3xq4_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_q3xq4_2d/cmp/generic b/tests/fe/face_to_cell_q3xq4_2d/cmp/generic new file mode 100644 index 0000000000..3f20c26a8e --- /dev/null +++ b/tests/fe/face_to_cell_q3xq4_2d/cmp/generic @@ -0,0 +1,21 @@ + +DEAL::Face=0 +DEAL:: flip=false +DEAL:: 0 - 1 - 4 - 5 - 8 - 9 - 10 - 11 - 12 - +DEAL:: flip=true +DEAL:: 4 - 5 - 0 - 1 - 9 - 8 - 12 - 11 - 10 - +DEAL::Face=1 +DEAL:: flip=false +DEAL:: 2 - 3 - 6 - 7 - 13 - 14 - 15 - 16 - 17 - +DEAL:: flip=true +DEAL:: 6 - 7 - 2 - 3 - 14 - 13 - 17 - 16 - 15 - +DEAL::Face=2 +DEAL:: flip=false +DEAL:: 0 - 1 - 2 - 3 - 18 - 19 - 20 - 21 - 22 - +DEAL:: flip=true +DEAL:: 2 - 3 - 0 - 1 - 19 - 18 - 22 - 21 - 20 - +DEAL::Face=3 +DEAL:: flip=false +DEAL:: 4 - 5 - 6 - 7 - 23 - 24 - 25 - 26 - 27 - +DEAL:: flip=true +DEAL:: 6 - 7 - 4 - 5 - 24 - 23 - 27 - 26 - 25 - -- 2.39.5