Beispiel #1
0
void
NodalFloodCount::mergeSets()
{
  Moose::perf_log.push("mergeSets()", "NodalFloodCount");
  std::set<unsigned int> set_union;
  std::insert_iterator<std::set<unsigned int> > set_union_inserter(set_union, set_union.begin());

  for (unsigned int map_num = 0; map_num < _maps_size; ++map_num)
  {
    std::list<BubbleData>::iterator end = _bubble_sets[map_num].end();
    for (std::list<BubbleData>::iterator it1 = _bubble_sets[map_num].begin(); it1 != end; /* No increment */)
    {
      bool need_it1_increment = true;

      for (std::list<BubbleData>::iterator it2 = it1; it2 != end; ++it2)
      {
        if (it1 != it2 &&                       // Make sure that these iterators aren't pointing at the same set
            it1->_var_idx == it2->_var_idx &&   // and that the sets have matching variable indices...
                                                // then See if they overlap
            setsIntersect(it1->_nodes.begin(), it1->_nodes.end(), it2->_nodes.begin(), it2->_nodes.end()))
        {
          // Merge these two sets and remove the duplicate set
          set_union.clear();
          std::set_union(it1->_nodes.begin(), it1->_nodes.end(), it2->_nodes.begin(), it2->_nodes.end(), set_union_inserter);

          // Put the merged set in the latter iterator so that we'll compare earlier sets to it again
          it2->_nodes = set_union;
          _bubble_sets[map_num].erase(it1++);

          // don't increment the outer loop since we just deleted it incremented
          need_it1_increment = false;
          // break out of the inner loop and move on
          break;
        }
      }

      if (need_it1_increment)
        ++it1;
    }
  }
  Moose::perf_log.pop("mergeSets()", "NodalFloodCount");
}
void
FeatureFloodCount::mergeSets(bool use_periodic_boundary_info)
{
  Moose::perf_log.push("mergeSets()", "FeatureFloodCount");
  std::set<dof_id_type> set_union;
  std::insert_iterator<std::set<dof_id_type> > set_union_inserter(set_union, set_union.begin());

  /**
   * If map_num <= n_processors (normal case), each processor up to map_num will handle one list
   * of nodes and receive the merged nodes from other processors for all other lists.
   */
  for (unsigned int map_num = 0; map_num < _maps_size; ++map_num)
  {
    unsigned int owner_id = map_num % _app.n_processors();
    if (_single_map_mode || owner_id == processor_id())
    {
      // Get an iterator pointing to the end of the list, we'll reuse it several times in the merge algorithm below
      std::list<BubbleData>::iterator end = _bubble_sets[map_num].end();

      // Next add periodic neighbor information if requested to the BubbleData objects
      if (use_periodic_boundary_info)
        for (std::list<BubbleData>::iterator it = _bubble_sets[map_num].begin(); it != end; ++it)
          appendPeriodicNeighborNodes(*it);

      // Finally start our merge loops
      for (std::list<BubbleData>::iterator it1 = _bubble_sets[map_num].begin(); it1 != end; /* No increment */)
      {
        bool need_it1_increment = true;

        for (std::list<BubbleData>::iterator it2 = it1; it2 != end; ++it2)
        {
          if (it1 != it2 &&                                                               // Make sure that these iterators aren't pointing at the same set
              it1->_var_idx == it2->_var_idx &&                                           // and that the sets have matching variable indices...
              (setsIntersect(it1->_entity_ids.begin(), it1->_entity_ids.end(),            // Do they overlap on the current entity type? OR..
                             it2->_entity_ids.begin(), it2->_entity_ids.end()) ||
                 (use_periodic_boundary_info &&                                           // Are we merging across periodic boundaries? AND
                 setsIntersect(it1->_periodic_nodes.begin(), it1->_periodic_nodes.end(),  // Do they overlap on periodic nodes?
                               it2->_periodic_nodes.begin(), it2->_periodic_nodes.end())
                 )
              )
            )
          {
            // Merge these two entity sets
            set_union.clear();
            std::set_union(it1->_entity_ids.begin(), it1->_entity_ids.end(), it2->_entity_ids.begin(), it2->_entity_ids.end(), set_union_inserter);
            // Put the merged set in the latter iterator so that we'll compare earlier sets to it again
            it2->_entity_ids = set_union;

            // If we are merging periodic boundaries we'll need to merge those nodes too
            if (use_periodic_boundary_info)
            {
              set_union.clear();
              std::set_union(it1->_periodic_nodes.begin(), it1->_periodic_nodes.end(), it2->_periodic_nodes.begin(), it2->_periodic_nodes.end(), set_union_inserter);
              it2->_periodic_nodes = set_union;
            }

            // Now remove the merged set, the one we didn't update (it1)
            _bubble_sets[map_num].erase(it1++);
            // don't increment the outer loop since we just deleted it incremented
            need_it1_increment = false;
            // break out of the inner loop and move on
            break;
          }
        }

        if (need_it1_increment)
          ++it1;
      }
    }
  }

  if (!_single_map_mode)
    for (unsigned int map_num = 0; map_num < _maps_size; ++map_num)
      // Now communicate this list with all the other processors
      communicateOneList(_bubble_sets[map_num], map_num % _app.n_processors(), map_num);

  Moose::perf_log.pop("mergeSets()", "FeatureFloodCount");
}