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"); }