Example #1
0
void DefaultCoupling::operator()
  (const MeshBase::const_element_iterator & range_begin,
   const MeshBase::const_element_iterator & range_end,
   processor_id_type p,
   map_type & coupled_elements)
{
  LOG_SCOPE("operator()", "DefaultCoupling");

#ifdef LIBMESH_ENABLE_PERIODIC
  bool check_periodic_bcs =
    (_periodic_bcs && !_periodic_bcs->empty());

  UniquePtr<PointLocatorBase> point_locator;
  if (check_periodic_bcs)
    {
      libmesh_assert(_mesh);
      point_locator = _mesh->sub_point_locator();
    }
#endif

  if (!this->_n_levels)
    {
      for (MeshBase::const_element_iterator elem_it = range_begin;
           elem_it != range_end; ++elem_it)
        {
          const Elem * const elem = *elem_it;

          if (elem->processor_id() != p)
            coupled_elements.insert (std::make_pair(elem,_dof_coupling));
        }
      return;
    }

  typedef LIBMESH_BEST_UNORDERED_SET<const Elem*> set_type;
  set_type next_elements_to_check(range_begin, range_end);
  set_type elements_to_check;
  set_type elements_checked;

  for (unsigned int i=0; i != this->_n_levels; ++i)
    {
      elements_to_check.swap(next_elements_to_check);
      next_elements_to_check.clear();
      elements_checked.insert(elements_to_check.begin(), elements_to_check.end());

      for (set_type::const_iterator elem_it  = elements_to_check.begin(),
                                    elem_end = elements_to_check.end();
           elem_it != elem_end; ++elem_it)
        {
          std::vector<const Elem *> active_neighbors;

          const Elem * const elem = *elem_it;

          if (elem->processor_id() != p)
            coupled_elements.insert (std::make_pair(elem,_dof_coupling));

          for (unsigned int s=0; s<elem->n_sides(); s++)
            {
              const Elem *neigh = elem->neighbor_ptr(s);

              // If we have a neighbor here
              if (neigh)
                {
                  // Mesh ghosting might ask us about what we want to
                  // distribute along with non-local elements, and those
                  // non-local elements might have remote neighbors, and
                  // if they do then we can't say anything about them.
                  if (neigh == remote_elem)
                    continue;
                }
#ifdef LIBMESH_ENABLE_PERIODIC
              // We might still have a periodic neighbor here
              else if (check_periodic_bcs)
                {
                  libmesh_assert(_mesh);

                  neigh = elem->topological_neighbor
                    (s, *_mesh, *point_locator, _periodic_bcs);
                }
#endif

              // With no regular *or* periodic neighbors we have nothing
              // to do.
              if (!neigh)
                continue;

              // With any kind of neighbor, we need to couple to all the
              // active descendants on our side.
#ifdef LIBMESH_ENABLE_AMR
              if (neigh == elem->neighbor_ptr(s))
                neigh->active_family_tree_by_neighbor(active_neighbors,elem);
#  ifdef LIBMESH_ENABLE_PERIODIC
              else
                neigh->active_family_tree_by_topological_neighbor
                  (active_neighbors,elem,*_mesh,*point_locator,_periodic_bcs);
#  endif
#else
              active_neighbors.clear();
              active_neighbors.push_back(neigh);
#endif

              for (std::size_t a=0; a != active_neighbors.size(); ++a)
                {
                  const Elem * neighbor = active_neighbors[a];

                  if (!elements_checked.count(neighbor))
                    next_elements_to_check.insert(neighbor);

                  if (neighbor->processor_id() != p)
                    coupled_elements.insert
                      (std::make_pair(neighbor, _dof_coupling));
                }
            }
        }
    }
}
void PointNeighborCoupling::operator()
  (const MeshBase::const_element_iterator & range_begin,
   const MeshBase::const_element_iterator & range_end,
   processor_id_type p,
   map_type & coupled_elements)
{
  LOG_SCOPE("operator()", "PointNeighborCoupling");

#ifdef LIBMESH_ENABLE_PERIODIC
  bool check_periodic_bcs =
    (_periodic_bcs && !_periodic_bcs->empty());
  UniquePtr<PointLocatorBase> point_locator;
  if (check_periodic_bcs)
    {
      libmesh_assert(_mesh);
      point_locator = _mesh->sub_point_locator();
    }
#endif

  if (!this->_n_levels)
    {
      for (MeshBase::const_element_iterator elem_it = range_begin;
           elem_it != range_end; ++elem_it)
        {
          const Elem * const elem = *elem_it;

          if (elem->processor_id() != p)
            coupled_elements.insert (std::make_pair(elem,_dof_coupling));
        }
      return;
    }

  typedef LIBMESH_BEST_UNORDERED_SET<const Elem*> set_type;
  set_type next_elements_to_check(range_begin, range_end);
  set_type elements_to_check;
  set_type elements_checked;

  for (unsigned int i=0; i != this->_n_levels; ++i)
    {
      elements_to_check.swap(next_elements_to_check);
      next_elements_to_check.clear();
      elements_checked.insert(elements_to_check.begin(), elements_to_check.end());

      for (set_type::const_iterator elem_it  = elements_to_check.begin(),
                                    elem_end = elements_to_check.end();
           elem_it != elem_end; ++elem_it)
        {
          std::set<const Elem *> point_neighbors;

          const Elem * const elem = *elem_it;

          if (elem->processor_id() != p)
            coupled_elements.insert (std::make_pair(elem,_dof_coupling));

#ifdef LIBMESH_ENABLE_PERIODIC
          // We might have a periodic neighbor here
          if (check_periodic_bcs)
            {
              libmesh_not_implemented();
            }
          else
#endif
            {
              elem->find_point_neighbors(point_neighbors);
            }

          for (std::set<const Elem *>::const_iterator
                 it = point_neighbors.begin(),
                 end_it = point_neighbors.end();
               it != end_it; ++it)
            {
              const Elem * neighbor = *it;

              if (!elements_checked.count(neighbor))
                next_elements_to_check.insert(neighbor);

              if (neighbor->processor_id() != p)
                coupled_elements.insert
                  (std::make_pair(neighbor, _dof_coupling));
            }
        }
    }
}