]> https://gitweb.dealii.org/ - dealii.git/commitdiff
fix bug in parallel MG: need to import additional level ghost neighbors which are...
authorTimo Heister <timo.heister@gmail.com>
Wed, 4 Sep 2013 15:28:48 +0000 (15:28 +0000)
committerTimo Heister <timo.heister@gmail.com>
Wed, 4 Sep 2013 15:28:48 +0000 (15:28 +0000)
git-svn-id: https://svn.dealii.org/trunk@30595 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/source/distributed/tria.cc
deal.II/source/dofs/dof_handler_policy.cc

index d4b8767c964a3629e4eca1837294329ef8b881e3..4269403891bb531b60e89eb2c4b99bf4675f3a47 100644 (file)
@@ -2795,7 +2795,32 @@ namespace parallel
                 }
             }
 
+          //step 4: Special case: on each level we need all the face neighbors of our own level cells
+          // these are normally on the same level, unless the neighbor is active and coarser. It
+          // can end up on a different processor. Luckily, the level_subdomain_id can be figured out
+          // without communication, because the cell is active (and so level_subdomain_id=subdomain_id):
+          for (typename Triangulation<dim,spacedim>::cell_iterator cell = this->begin(); cell!=this->end(); ++cell)
+            {
+              if (cell->level_subdomain_id()!=this->locally_owned_subdomain())
+                continue;
 
+              for (unsigned int f=0; f<GeometryInfo<dim>::faces_per_cell; ++f)
+                {
+                  if (cell->face(f)->at_boundary())
+                    continue;
+                  if (cell->neighbor(f)->level() < cell->level()
+                      &&
+                      cell->neighbor(f)->level_subdomain_id()!=this->locally_owned_subdomain())
+                    {
+                      Assert(cell->neighbor(f)->active(), ExcInternalError());
+                      Assert(cell->neighbor(f)->subdomain_id() != numbers::artificial_subdomain_id, ExcInternalError());
+                      Assert(cell->neighbor(f)->level_subdomain_id() == numbers::artificial_subdomain_id
+                           || cell->neighbor(f)->level_subdomain_id() == cell->neighbor(f)->subdomain_id(), ExcInternalError());
+                      cell->neighbor(f)->set_level_subdomain_id(cell->neighbor(f)->subdomain_id());
+                    }
+                }
+
+            }
 
         }
 
index 30a9c96ecb4b3a00d25dad3d2d6469f78bd57050..496a9e16f41430c6394432d2d8912854d72525d6 100644 (file)
@@ -1212,6 +1212,40 @@ namespace internal
                     }
                 }
 
+              //additionally (multigrid only), we can have the case that children of our neighbor
+              //have us as a neighbor. In this case we and the children are active.
+              if (dealii_cell->active())
+                {
+                  for (unsigned int f=0;f<GeometryInfo<dim>::faces_per_cell;++f)
+                    {
+                      if (dealii_cell->at_boundary(f))
+                        continue;
+                      typename DoFHandler<dim,spacedim>::level_cell_iterator neighbor = dealii_cell->neighbor(f);
+                      if (!neighbor->has_children())
+                        continue;
+
+                      for (unsigned int subface=0; subface<GeometryInfo<dim>::max_children_per_face; ++subface)
+                        {
+                          typename DoFHandler<dim,spacedim>::level_cell_iterator child = dealii_cell->neighbor_child_on_subface(f,subface);
+                          dealii::types::subdomain_id dest = child->subdomain_id();
+                          Assert(dest != dealii::numbers::artificial_subdomain_id, ExcInternalError());
+                          if (dest != tria.locally_owned_subdomain())
+                            {
+                              if (send_to.find(dest) == send_to.end())
+                                {
+                                  std::cout << "********" << std::endl;
+                                }
+                              send_to.insert(dest);
+
+                            }
+                        }
+
+                    }
+
+                }
+
+
+              // send if we have something to send
               if (send_to.size() > 0)
                 {
                   // this cell's dof_indices
@@ -2320,7 +2354,8 @@ namespace internal
               for (typename DoFHandler<dim,spacedim>::level_cell_iterator
                    cell = dof_handler.begin(level);
                    cell != dof_handler.end(level); ++cell)
-                if (cell->level_subdomain_id() != dealii::numbers::artificial_subdomain_id && cell->level_subdomain_id() != tr->locally_owned_subdomain())
+                if (cell->level_subdomain_id() != dealii::numbers::artificial_subdomain_id
+                    && cell->level_subdomain_id() != tr->locally_owned_subdomain())
                   for (unsigned int v=0; v<GeometryInfo<dim>::vertices_per_cell; ++v)
                     if (locally_active_vertices[cell->vertex_index(v)])
                       vertices_with_ghost_neighbors[cell->vertex_index(v)]
@@ -2364,7 +2399,7 @@ namespace internal
                                      local_dof_indices.end(),
                                      DoFHandler<dim,spacedim>::invalid_dof_index))
                         {
-                          Assert(false, ExcMessage ("not all dofs got distributed!"));
+                          Assert(false, ExcMessage ("not all DoFs got distributed!"));
                         }
                     }
               }

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.