]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Bug fix of MF face eval for hanging nodes and non-standard orientation
authorMartin Kronbichler <martin.kronbichler@it.uu.se>
Mon, 20 Dec 2021 09:20:13 +0000 (10:20 +0100)
committerMartin Kronbichler <martin.kronbichler@it.uu.se>
Tue, 21 Dec 2021 11:57:54 +0000 (12:57 +0100)
include/deal.II/matrix_free/evaluation_kernels.h
include/deal.II/matrix_free/face_setup_internal.h
include/deal.II/matrix_free/shape_info.h
include/deal.II/matrix_free/shape_info.templates.h

index d4101092faf87380744551d4a19d1370a3bc2130..d26e9ce2b45a342e73e853e4e2c1e3a0b30fe078 100644 (file)
@@ -3783,19 +3783,18 @@ namespace internal
                 }
             }
           else if (fe_eval.get_face_orientation() != 0)
-            for (unsigned int c = 0; c < n_components; ++c)
-              adjust_for_face_orientation(
-                dim,
-                n_components,
-                evaluation_flag,
-                &fe_eval.get_shape_info().face_orientations_quad(
-                  fe_eval.get_face_orientation(), 0),
-                false,
-                Utilities::pow(n_q_points_1d, dim - 1),
-                temp,
-                fe_eval.begin_values(),
-                fe_eval.begin_gradients(),
-                fe_eval.begin_hessians());
+            adjust_for_face_orientation(
+              dim,
+              n_components,
+              evaluation_flag,
+              &fe_eval.get_shape_info().face_orientations_quad(
+                fe_eval.get_face_orientation(), 0),
+              false,
+              Utilities::pow(n_q_points_1d, dim - 1),
+              temp,
+              fe_eval.begin_values(),
+              fe_eval.begin_gradients(),
+              fe_eval.begin_hessians());
         }
 
       return false;
index bcfd049961e8ff7dbb326971eff6c8c2ee628abe..bdcc6516e61cee13a8306039ff606129a06dfe9c 100644 (file)
@@ -28,6 +28,7 @@
 #include <deal.II/grid/tria_accessor.h>
 
 #include <deal.II/matrix_free/face_info.h>
+#include <deal.II/matrix_free/shape_info.h>
 #include <deal.II/matrix_free/task_info.h>
 
 #include <fstream>
@@ -1041,6 +1042,20 @@ namespace internal
         }
       else
         info.face_orientation = exterior_face_orientation;
+
+      // make sure to select correct subface index in case of non-standard
+      // orientation of the coarser neighbor face
+      if (cell->level() > neighbor->level() && exterior_face_orientation > 0)
+        {
+          const Table<2, unsigned int> orientation =
+            ShapeInfo<double>::compute_orientation_table(2);
+          const std::array<unsigned int, 8> inverted_orientations{
+            {0, 1, 2, 3, 6, 5, 4, 7}};
+          info.subface_index =
+            orientation[inverted_orientations[exterior_face_orientation]]
+                       [info.subface_index];
+        }
+
       return info;
     }
 
index d7269738da66f57904ce21c3bbe16634441710de..1187d0708c3359224d955599ece5b9f73c0f1bf0 100644 (file)
@@ -375,6 +375,13 @@ namespace internal
       static bool
       is_supported(const FiniteElement<dim, spacedim> &fe);
 
+      /**
+       * Compute a table with numbers of re-orientation for all versions of
+       * face flips, orientation, and rotation (relating only to 3D elements).
+       */
+      static Table<2, unsigned int>
+      compute_orientation_table(const unsigned int n_points_per_dim);
+
       /**
        * Return data of univariate shape functions which defines the
        * dimension @p dimension of tensor product shape functions
index fd13f5fb0f692b199b7f9ea017dee3192218958f..9f1a084a81b8a6d8e942e4be31971571c1962c43 100644 (file)
@@ -854,41 +854,8 @@ namespace internal
           // (similar to MappingInfoStorage::QuadratureDescriptor::initialize)
           if (dim == 3)
             {
-              const auto compute_orientations =
-                [](const unsigned int      n,
-                   Table<2, unsigned int> &face_orientations) {
-                  face_orientations.reinit(8, n * n);
-                  for (unsigned int j = 0, i = 0; j < n; ++j)
-                    for (unsigned int k = 0; k < n; ++k, ++i)
-                      {
-                        // face_orientation=true,  face_flip=false,
-                        // face_rotation=false
-                        face_orientations[0][i] = i;
-                        // face_orientation=false, face_flip=false,
-                        // face_rotation=false
-                        face_orientations[1][i] = j + k * n;
-                        // face_orientation=true,  face_flip=true,
-                        // face_rotation=false
-                        face_orientations[2][i] = (n - 1 - k) + (n - 1 - j) * n;
-                        // face_orientation=false, face_flip=true,
-                        // face_rotation=false
-                        face_orientations[3][i] = (n - 1 - j) + (n - 1 - k) * n;
-                        // face_orientation=true,  face_flip=false,
-                        // face_rotation=true
-                        face_orientations[4][i] = j + (n - 1 - k) * n;
-                        // face_orientation=false, face_flip=false,
-                        // face_rotation=true
-                        face_orientations[5][i] = k + (n - 1 - j) * n;
-                        // face_orientation=true,  face_flip=true,
-                        // face_rotation=true
-                        face_orientations[6][i] = (n - 1 - j) + k * n;
-                        // face_orientation=false, face_flip=true,
-                        // face_rotation=true
-                        face_orientations[7][i] = (n - 1 - k) + j * n;
-                      }
-                };
-              compute_orientations(fe_degree + 1, face_orientations_dofs);
-              compute_orientations(n_q_points_1d, face_orientations_quad);
+              face_orientations_dofs = compute_orientation_table(fe_degree + 1);
+              face_orientations_quad = compute_orientation_table(n_q_points_1d);
             }
           else
             {
@@ -1163,6 +1130,36 @@ namespace internal
 
 
 
+    template <typename Number>
+    Table<2, unsigned int>
+    ShapeInfo<Number>::compute_orientation_table(const unsigned int n)
+    {
+      Table<2, unsigned int> face_orientations(8, n * n);
+      for (unsigned int j = 0, i = 0; j < n; ++j)
+        for (unsigned int k = 0; k < n; ++k, ++i)
+          {
+            // face_orientation=true,  face_flip=false, face_rotation=false
+            face_orientations[0][i] = i;
+            // face_orientation=false, face_flip=false, face_rotation=false
+            face_orientations[1][i] = j + k * n;
+            // face_orientation=true,  face_flip=true, face_rotation=false
+            face_orientations[2][i] = (n - 1 - k) + (n - 1 - j) * n;
+            // face_orientation=false, face_flip=true, face_rotation=false
+            face_orientations[3][i] = (n - 1 - j) + (n - 1 - k) * n;
+            // face_orientation=true,  face_flip=false, face_rotation=true
+            face_orientations[4][i] = j + (n - 1 - k) * n;
+            // face_orientation=false, face_flip=false, face_rotation=true
+            face_orientations[5][i] = k + (n - 1 - j) * n;
+            // face_orientation=true,  face_flip=true, face_rotation=true
+            face_orientations[6][i] = (n - 1 - j) + k * n;
+            // face_orientation=false, face_flip=true, face_rotation=true
+            face_orientations[7][i] = (n - 1 - k) + j * n;
+          }
+      return face_orientations;
+    }
+
+
+
     template <typename Number>
     std::size_t
     ShapeInfo<Number>::memory_consumption() const

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.