]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Modified MGConstrainedDofs to not crash across periodic boundary refinement edge... 7050/head
authorAlexander Knieps <alexanderrobom@web.de>
Sun, 12 Aug 2018 00:30:19 +0000 (02:30 +0200)
committerAlexander Knieps <alexanderrobom@web.de>
Tue, 14 Aug 2018 23:11:25 +0000 (01:11 +0200)
Fixed incorrect generation of interface DoFs

Indentation fix

Modified to use extract_inner_interface_dofs instead of a new function

Removed MGTools::extract_inner_or_periodic_interface_dofs from source file

make indent

Re-added removed line (keeps diff smaller)

Addressed first part of requested changes

Addressed a few more change requests

More changes addressed

Renamed in tests/multigrid dof_06.* constrained_dofs_05.*

Added changelog entry

Updated MgTools::extract_non_interface_dofs

make indent

doc/news/changes/minor/20180813AlexanderKnieps [new file with mode: 0644]
include/deal.II/multigrid/mg_constrained_dofs.h
source/multigrid/mg_tools.cc
tests/multigrid/constrained_dofs_05.cc [new file with mode: 0644]
tests/multigrid/constrained_dofs_05.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20180813AlexanderKnieps b/doc/news/changes/minor/20180813AlexanderKnieps
new file mode 100644 (file)
index 0000000..7a324b2
--- /dev/null
@@ -0,0 +1,3 @@
+Fixed: MGConstrainedDofs::initialize(...) now handles refinement edges across periodic boundaries correctly.
+<br>
+(Alexander Knieps 2018/08/13)
index a0d130cbd86db75454ee4d5484450e349bcf6be5..b5b2956320e40bb464648b2cfdf4e78abf3387f2 100644 (file)
@@ -210,7 +210,8 @@ MGConstrainedDoFs::initialize(const DoFHandler<dim, spacedim> &dof)
         if (cell->level_subdomain_id() != numbers::artificial_subdomain_id)
           {
             for (unsigned int f = 0; f < GeometryInfo<dim>::faces_per_cell; ++f)
-              if (cell->has_periodic_neighbor(f))
+              if (cell->has_periodic_neighbor(f) &&
+                  cell->periodic_neighbor(f)->level() == cell->level())
                 {
                   if (cell->is_locally_owned_on_level())
                     {
index db1aee61e886efdcd41b67a21a018e42db98c903..d107f40bda0a59ccff1d00fc10dbb4169baf7332 100644 (file)
@@ -1495,11 +1495,11 @@ namespace MGTools
           {
             const typename DoFHandler<dim, spacedim>::face_iterator face =
               cell->face(face_nr);
-            if (!face->at_boundary())
+            if (!face->at_boundary() || cell->has_periodic_neighbor(face_nr))
               {
                 // interior face
                 const typename DoFHandler<dim>::cell_iterator neighbor =
-                  cell->neighbor(face_nr);
+                  cell->neighbor_or_periodic_neighbor(face_nr);
 
                 if ((neighbor->level() < cell->level()))
                   {
@@ -1576,11 +1576,11 @@ namespace MGTools
           {
             const typename DoFHandler<dim, spacedim>::face_iterator face =
               cell->face(face_nr);
-            if (!face->at_boundary())
+            if (!face->at_boundary() || cell->has_periodic_neighbor(face_nr))
               {
                 // interior face
                 const typename DoFHandler<dim>::cell_iterator neighbor =
-                  cell->neighbor(face_nr);
+                  cell->neighbor_or_periodic_neighbor(face_nr);
 
                 // only process cell pairs if one or both of them are owned by
                 // me (ignore if running in serial)
diff --git a/tests/multigrid/constrained_dofs_05.cc b/tests/multigrid/constrained_dofs_05.cc
new file mode 100644 (file)
index 0000000..d716f69
--- /dev/null
@@ -0,0 +1,186 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2018 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.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+#include <deal.II/base/exceptions.h>
+
+#include <deal.II/dofs/dof_handler.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/grid_tools.h>
+#include <deal.II/grid/tria.h>
+
+#include <deal.II/multigrid/mg_constrained_dofs.h>
+
+#include <vector>
+
+#include "../tests.h"
+
+template <typename FaceType>
+void
+print_face(const FaceType &face, const unsigned int level)
+{
+  AssertThrow(
+    face->get_fe(0).n_dofs_per_face() > 0,
+    ExcMessage(
+      "Please use a finite element with at least 1 DoF for this test"));
+
+  std::vector<types::global_dof_index> mg_dofs(
+    face->get_fe(0).n_dofs_per_face());
+  face->get_mg_dof_indices(level, mg_dofs);
+
+  // Print face DoFs
+  deallog << mg_dofs[0];
+  for (unsigned int i_dof = 1; i_dof < mg_dofs.size(); ++i_dof)
+    deallog << ", " << mg_dofs[i_dof];
+}
+
+template <int dim>
+void
+check()
+{
+  using Tria = Triangulation<dim>;
+  // Create triangulation
+  Tria tria(Tria::limit_level_difference_at_vertices);
+
+  // Create coarse grid
+  GridGenerator::hyper_cube(tria, -1, 1, true);
+
+  // Create periodic boundary along x axis
+  std::vector<GridTools::PeriodicFacePair<typename Tria::cell_iterator>>
+    face_pairs;
+
+  GridTools::collect_periodic_faces(tria, 0, 1, 0, face_pairs);
+
+  tria.add_periodicity(face_pairs);
+
+  // Refine once and then refine the corner again
+  tria.refine_global(1);
+
+  tria.begin_active()->set_refine_flag();
+  tria.prepare_coarsening_and_refinement();
+  tria.execute_coarsening_and_refinement();
+
+  // Assemble DoFs
+  DoFHandler<dim> dof_handler(tria);
+  FE_Q<dim>       fe_q(1);
+
+  dof_handler.distribute_dofs(fe_q);
+  dof_handler.distribute_mg_dofs();
+
+  // Try to assemble MGConstrainedDofs
+  MGConstrainedDoFs constrained_dofs;
+  constrained_dofs.initialize(dof_handler);
+
+  // Report which DIM is ok
+  deallog << "--- DIM " << dim << " OK ---" << std::endl;
+
+  // Debug printouts:
+  for (unsigned int level = 0; level < tria.n_global_levels(); ++level)
+    {
+      deallog << "Level " << level << ": " << std::endl;
+
+      // Print faces that connect to coarser DoF
+      deallog << "  Faces neighboring coarser cells:" << std::endl;
+      for (const auto level_cell : dof_handler.cell_iterators_on_level(level))
+        {
+          // Iterate over all faces
+          for (unsigned int i_face = 0;
+               i_face < GeometryInfo<dim>::faces_per_cell;
+               ++i_face)
+            {
+              if ((level_cell->at_boundary(i_face) &&
+                   !level_cell->has_periodic_neighbor(i_face)) ||
+                  level_cell->neighbor_or_periodic_neighbor(i_face)->level() ==
+                    level_cell->level())
+                continue;
+
+              // Get face
+              const auto face = level_cell->face(i_face);
+
+              deallog << "    ";
+              print_face(face, level);
+
+              // Print whether the neighbor is periodic
+              if (level_cell->has_periodic_neighbor(i_face))
+                deallog << " via periodic boundary" << std::endl;
+              else
+                deallog << " via internal face" << std::endl;
+            }
+        }
+
+      // Print hanging node DoFs
+      deallog << "  Refinement edge DoFs: ";
+      constrained_dofs.get_refinement_edge_indices(level).print(deallog);
+      deallog << std::endl;
+
+      // Print faces that have periodic neighbors
+      deallog << "  Faces having periodic neighbors of same level:"
+              << std::endl;
+      for (const auto level_cell : dof_handler.cell_iterators_on_level(level))
+        {
+          // Iterate over all faces
+          for (unsigned int i_face = 0;
+               i_face < GeometryInfo<dim>::faces_per_cell;
+               ++i_face)
+            {
+              if (!level_cell->has_periodic_neighbor(i_face) ||
+                  level_cell->periodic_neighbor(i_face)->level() !=
+                    level_cell->level())
+                continue;
+
+              typename DoFHandler<dim>::cell_iterator neighbor_cell =
+                level_cell->periodic_neighbor(i_face);
+
+              // Each side only once
+              if (level_cell->index() > neighbor_cell->index())
+                continue;
+
+              unsigned int neighbor_i_face =
+                level_cell->periodic_neighbor_face_no(i_face);
+
+              // Get face
+              const auto face          = level_cell->face(i_face);
+              const auto neighbor_face = neighbor_cell->face(neighbor_i_face);
+
+              deallog << "    ";
+              print_face(face, level);
+              deallog << " <-> ";
+              print_face(neighbor_face, level);
+
+              // Print whether the neighbor is periodic
+              if (level_cell->has_periodic_neighbor(i_face))
+                deallog << " via periodic boundary" << std::endl;
+              else
+                deallog << " via internal face" << std::endl;
+            }
+        }
+
+      // Print constraint matrix
+      deallog << "  Constraint matrix:" << std::endl;
+      constrained_dofs.get_level_constraint_matrix(level).print(
+        deallog.get_file_stream());
+    }
+}
+
+int
+main()
+{
+  initlog();
+
+  // check<1>();
+  check<2>();
+  check<3>();
+  return 0;
+}
diff --git a/tests/multigrid/constrained_dofs_05.output b/tests/multigrid/constrained_dofs_05.output
new file mode 100644 (file)
index 0000000..69c842b
--- /dev/null
@@ -0,0 +1,89 @@
+
+DEAL::--- DIM 2 OK ---
+DEAL::Level 0: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::  Refinement edge DoFs: {}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::    0, 2 <-> 1, 3 via periodic boundary
+DEAL::    1, 3 <-> 0, 2 via periodic boundary
+DEAL::  Constraint matrix:
+    0 1:  1.00000
+    2 3:  1.00000
+DEAL::Level 1: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::  Refinement edge DoFs: {}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::    0, 2 <-> 4, 5 via periodic boundary
+DEAL::    2, 6 <-> 5, 8 via periodic boundary
+DEAL::  Constraint matrix:
+    0 4:  1.00000
+    2 5:  1.00000
+    6 8:  1.00000
+DEAL::Level 2: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::    0, 2 via periodic boundary
+DEAL::    4, 5 via internal face
+DEAL::    2, 6 via periodic boundary
+DEAL::    6, 7 via internal face
+DEAL::    5, 8 via internal face
+DEAL::    7, 8 via internal face
+DEAL::  Refinement edge DoFs: {0, 2, [4,8]}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::  Constraint matrix:
+DEAL::--- DIM 3 OK ---
+DEAL::Level 0: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::  Refinement edge DoFs: {}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::    0, 2, 4, 6 <-> 1, 3, 5, 7 via periodic boundary
+DEAL::    1, 3, 5, 7 <-> 0, 2, 4, 6 via periodic boundary
+DEAL::  Constraint matrix:
+    0 1:  1.00000
+    2 3:  1.00000
+    4 5:  1.00000
+    6 7:  1.00000
+DEAL::Level 1: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::  Refinement edge DoFs: {}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::    0, 2, 4, 6 <-> 8, 9, 10, 11 via periodic boundary
+DEAL::    2, 12, 6, 14 <-> 9, 16, 11, 17 via periodic boundary
+DEAL::    4, 6, 18, 20 <-> 10, 11, 22, 23 via periodic boundary
+DEAL::    6, 14, 20, 24 <-> 11, 17, 23, 26 via periodic boundary
+DEAL::  Constraint matrix:
+    0 8:  1.00000
+    2 9:  1.00000
+    4 10:  1.00000
+    6 11:  1.00000
+    12 16:  1.00000
+    14 17:  1.00000
+    18 22:  1.00000
+    20 23:  1.00000
+    24 26:  1.00000
+DEAL::Level 2: 
+DEAL::  Faces neighboring coarser cells:
+DEAL::    0, 2, 4, 6 via periodic boundary
+DEAL::    8, 9, 10, 11 via internal face
+DEAL::    2, 12, 6, 14 via periodic boundary
+DEAL::    12, 14, 13, 15 via internal face
+DEAL::    9, 16, 11, 17 via internal face
+DEAL::    13, 15, 16, 17 via internal face
+DEAL::    4, 6, 18, 20 via periodic boundary
+DEAL::    18, 19, 20, 21 via internal face
+DEAL::    10, 11, 22, 23 via internal face
+DEAL::    19, 22, 21, 23 via internal face
+DEAL::    6, 14, 20, 24 via periodic boundary
+DEAL::    14, 24, 15, 25 via internal face
+DEAL::    20, 21, 24, 25 via internal face
+DEAL::    11, 17, 23, 26 via internal face
+DEAL::    15, 25, 17, 26 via internal face
+DEAL::    21, 23, 25, 26 via internal face
+DEAL::  Refinement edge DoFs: {0, 2, 4, 6, [8,26]}
+DEAL::
+DEAL::  Faces having periodic neighbors of same level:
+DEAL::  Constraint matrix:

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.