21 #include "libmesh/dof_map.h" 22 #include "libmesh/mesh_tools.h" 23 #include "libmesh/periodic_boundaries.h" 24 #include "libmesh/point_locator_base.h" 25 #include "libmesh/remote_elem.h" 55 dataStore(std::ostream & stream, BoundingBox & bbox,
void * context)
86 dataLoad(std::istream & stream, BoundingBox & bbox,
void * context)
106 "The variable(s) for which to find connected regions of interests, i.e. \"features\".");
108 "threshold", 0.5,
"The threshold value for which a new feature may be started");
110 "connecting_threshold",
111 "The threshold for which an existing feature may be extended (defaults to \"threshold\")");
112 params.
addParam<
bool>(
"use_single_map",
114 "Determine whether information is tracked per " 115 "coupled variable or consolidated into one " 120 "Determines whether we condense all the node values when in multimap mode (default: false)");
121 params.
addParam<
bool>(
"use_global_numbering",
123 "Determine whether or not global numbers are " 124 "used to label features on multiple maps " 126 params.
addParam<
bool>(
"enable_var_coloring",
128 "Instruct the Postprocessor to populate the variable index map.");
132 "Instruct the Postprocessor to communicate proper halo information to all ranks");
133 params.
addParam<
bool>(
"compute_var_to_feature_map",
135 "Instruct the Postprocessor to compute the active vars to features map");
137 "use_less_than_threshold_comparison",
139 "Controls whether features are defined to be less than or greater than the threshold value.");
141 params.
addParam<std::vector<BoundaryName>>(
142 "primary_percolation_boundaries",
143 "A list of boundaries used in conjunction with the corresponding " 144 "\"secondary_percolation_boundaries\" parameter for determining if a feature creates a path " 145 "connecting any pair of boundaries");
146 params.
addParam<std::vector<BoundaryName>>(
147 "secondary_percolation_boundaries",
148 "Paired boundaries with \"primaryary_percolation_boundaries\" parameter");
149 params.
addParam<std::vector<BoundaryName>>(
150 "specified_boundaries",
151 "An optional list of boundaries; if supplied, each feature is checked to determine whether " 152 "it intersects any of the specified boundaries in this list.");
161 params.
set<
bool>(
"use_displaced_mesh") =
false;
170 "use_single_map condense_map_info use_global_numbering primary_percolation_boundaries",
173 MooseEnum flood_type(
"NODAL ELEMENTAL",
"ELEMENTAL");
176 "Determines whether the flood algorithm runs on nodes or elements");
178 params.
addClassDescription(
"The object is able to find and count \"connected components\" in any " 179 "solution field or number of solution fields. A primary example would " 180 "be to count \"bubbles\".");
194 _fe_vars(getCoupledMooseVars()),
195 _vars(getCoupledStandardMooseVars()),
196 _dof_map(_vars[0]->dofMap()),
197 _threshold(getParam<
Real>(
"threshold")),
198 _connecting_threshold(isParamValid(
"connecting_threshold")
199 ? getParam<
Real>(
"connecting_threshold")
200 : getParam<
Real>(
"threshold")),
201 _mesh(_subproblem.
mesh()),
202 _var_number(_fe_vars[0]->number()),
203 _single_map_mode(getParam<bool>(
"use_single_map")),
204 _condense_map_info(getParam<bool>(
"condense_map_info")),
205 _global_numbering(getParam<bool>(
"use_global_numbering")),
206 _var_index_mode(getParam<bool>(
"enable_var_coloring")),
207 _compute_halo_maps(getParam<bool>(
"compute_halo_maps")),
208 _compute_var_to_feature_map(getParam<bool>(
"compute_var_to_feature_map")),
209 _use_less_than_threshold_comparison(getParam<bool>(
"use_less_than_threshold_comparison")),
210 _n_vars(_fe_vars.size()),
211 _maps_size(_single_map_mode ? 1 : _fe_vars.size()),
212 _n_procs(_app.n_processors()),
213 _feature_counts_per_map(_maps_size),
215 _partial_feature_sets(_maps_size),
216 _feature_sets(getParam<bool>(
"restartable_required")
217 ? declareRestartableData<
std::vector<
FeatureData>>(
"feature_sets")
218 : _volatile_feature_sets),
219 _feature_maps(_maps_size),
221 _element_average_value(parameters.isParamValid(
"elem_avg_value")
222 ? getPostprocessorValue(
"elem_avg_value")
224 _halo_ids(_maps_size),
225 _is_elemental(getParam<
MooseEnum>(
"flood_entity_type") ==
"ELEMENTAL"),
226 _is_primary(processor_id() == 0)
238 for (
auto & var :
_vars)
241 var->dofValuesOlder();
247 parameters.
get<std::vector<BoundaryName>>(
"primary_percolation_boundaries"));
250 parameters.
get<std::vector<BoundaryName>>(
"secondary_percolation_boundaries"));
254 "primary_percolation_boundaries and secondary_percolation_boundaries must both be " 255 "supplied when checking for percolation");
346 TIME_SECTION(
"execute", 3,
"Flooding Features");
351 mooseInfo(
"Using EXPERIMENTAL boundary restricted FeatureFloodCount object!\n");
360 const Elem * elem = belem->_elem;
363 if (elem->processor_id() == rank)
367 flood(elem, var_num);
373 for (
const auto & current_elem :
_mesh.
getMesh().active_local_element_ptr_range())
379 flood(current_elem, var_num);
383 auto n_nodes = current_elem->n_vertices();
386 const Node * current_node = current_elem->node_ptr(i);
389 flood(current_node, var_num);
405 TIME_SECTION(
"communicateAndMerge", 3,
"Communicating and Merging");
417 std::vector<std::string> send_buffers(1);
425 std::vector<std::string> recv_buffers, deserialize_buffers;
435 if (n_merging_procs > 1)
438 bool is_merging_processor = rank < n_merging_procs;
440 if (is_merging_processor)
443 for (
const auto i :
make_range(n_merging_procs))
453 send_buffers.begin(),
455 std::back_inserter(recv_buffers));
464 recv_buffers.swap(deserialize_buffers);
466 recv_buffers.clear();
470 Parallel::Communicator merge_comm;
474 if (is_merging_processor)
488 send_buffers[0].clear();
489 recv_buffers.clear();
490 deserialize_buffers.clear();
505 merge_comm.gather_packed_range(0,
507 send_buffers.begin(),
509 std::back_inserter(recv_buffers));
516 send_buffers[0].clear();
517 recv_buffers.clear();
544 send_buffers.begin(),
546 std::back_inserter(recv_buffers));
552 recv_buffers.clear();
570 mooseAssert(
_is_primary,
"sortAndLabel can only be called on the primary");
585 unsigned int feature_offset = 0;
593 auto range_front = feature_offset;
596 mooseAssert(range_front <= range_back && range_back <
_feature_count,
597 "Indexing error in feature sets");
601 mooseError(
"Error in _feature_sets sorting, map index: ", map_num);
615 std::vector<int> & counts)
const 617 mooseAssert(
_is_primary,
"This method must only be called on the root processor");
622 for (
const auto & local_index_pair : feature._orig_ids)
625 mooseAssert(local_index_pair.first <
_n_procs,
"Processor ID is out of range");
626 if (local_index_pair.second >= static_cast<std::size_t>(counts[local_index_pair.first]))
627 counts[local_index_pair.first] = local_index_pair.second + 1;
631 unsigned int globalsize = 0;
635 offsets[i] = globalsize;
636 globalsize += counts[i];
644 for (
const auto & local_index_pair : feature._orig_ids)
646 auto rank = local_index_pair.first;
649 auto local_index = local_index_pair.second;
650 auto stacked_local_index = offsets[rank] + local_index;
652 mooseAssert(stacked_local_index < globalsize,
653 "Global index: " << stacked_local_index <<
" is out of range");
654 local_to_global_all[stacked_local_index] = feature._id;
668 "Feature ID out of range(" <<
_feature_sets[feature_index]._id <<
')');
677 TIME_SECTION(
"finalize", 3,
"Finalizing Feature Identification");
693 const std::vector<unsigned int> &
697 "Please set \"compute_var_to_feature_map = true\" to use this interface method"));
702 mooseAssert(pos->second.size() ==
_n_vars,
"Variable to feature vector not sized properly");
713 std::vector<int> counts;
714 std::vector<std::size_t> local_to_global_all;
721 std::size_t largest_global_index = std::numeric_limits<std::size_t>::lowest();
734 for (
auto & feature : list_ref)
736 mooseAssert(feature._orig_ids.size() == 1,
"feature._orig_ids length doesn't make sense");
739 auto local_index = feature._orig_ids.begin()->second;
746 if (global_index > largest_global_index)
747 largest_global_index = global_index;
750 feature._id = global_index;
759 feature._status &= ~
Status::INACTIVE;
769 for (
auto global_index : local_to_global_all)
771 largest_global_index = global_index;
775 std::vector<std::pair<unsigned int, int>> intersection_state;
777 intersection_state.emplace_back(feature._id, static_cast<int>(feature._boundary_intersection));
783 std::map<unsigned int, int> consolidated_intersection_state;
785 for (
const auto & [
id, state] : intersection_state)
786 consolidated_intersection_state[id] |= state;
793 feature._boundary_intersection |=
833 mooseAssert(local_index <
_feature_sets.size(),
"local_index out of bounds");
853 mooseAssert(local_index <
_feature_sets.size(),
"local_index out of bounds");
873 mooseAssert(local_index <
_feature_sets.size(),
"local_index out of bounds");
895 mooseAssert(local_index <
_feature_sets.size(),
"local_index out of bounds");
896 bool primary = ((
_feature_sets[local_index]._boundary_intersection &
899 bool secondary = ((
_feature_sets[local_index]._boundary_intersection &
916 Real invalid_coord = std::numeric_limits<Real>::max();
917 Point p(invalid_coord, invalid_coord, invalid_coord);
920 mooseAssert(local_index <
_feature_sets.size(),
"local_index out of bounds");
929 std::size_t var_index)
const 931 auto use_default =
false;
938 mooseAssert(var_index <
_maps_size,
"Index out of range");
944 const auto entity_it =
_feature_maps[var_index].find(entity_id);
947 return entity_it->second;
956 "\"enable_var_coloring\" must be set to true to pull back the VARIABLE_COLORING field");
961 return entity_it->second;
971 return entity_it->second;
980 const auto entity_it =
_halo_ids[var_index].find(entity_id);
981 if (entity_it !=
_halo_ids[var_index].end())
982 return entity_it->second;
990 const auto entity_it =
_halo_ids[map_num].find(entity_id);
992 if (entity_it !=
_halo_ids[map_num].end())
993 return entity_it->second;
1003 "Centroids are not correct when using periodic boundaries, contact the MOOSE team"));
1013 if (elem_ptr->contains_point(feature._centroid))
1023 if (ids.size() != 0)
1036 TIME_SECTION(
"prepareDataForTransfer", 3,
"Preparing Data For Transfer");
1044 for (
auto & feature : list_ref)
1065 feature.updateBBoxExtremes(
mesh);
1068 for (
auto & halo_id : feature._halo_ids)
1072 mooseAssert(!feature._local_ids.empty(),
"local entity ids cannot be empty");
1078 feature._min_entity_id = *feature._local_ids.begin();
1087 std::ostringstream oss;
1090 "var_num out of range");
1099 serialized_buffer.assign(oss.str());
1106 std::istringstream iss;
1110 for (
const auto proc_id :
index_range(serialized_buffers))
1123 if (var_num ==
invalid_id && proc_id == rank)
1126 iss.str(serialized_buffers[proc_id]);
1140 TIME_SECTION(
"mergeSets", 3,
"Merging Sets");
1149 bool merge_occured =
false;
1156 it2->merge(std::move(*it1));
1178 merge_occured =
true;
1195 TIME_SECTION(
"consolidateMergedFeatures", 3,
"Consolidating Merged Features");
1206 "cosolidateMergedFeatures() may only be called on the primary processor");
1208 "Data structure size mismatch");
1211 unsigned int feature_offset = 0;
1220 for (
auto it = (*saved_data)[map_num].begin(); it != (*saved_data)[map_num].end();
1223 if (feature.canConsolidate(*it))
1225 feature.consolidate(std::move(*it));
1226 it = (*saved_data)[map_num].erase(it);
1238 if (feature._vol_count != 0)
1239 feature._centroid /= feature._vol_count;
1255 (*saved_data)[map_num].clear();
1291 : feature._var_index;
1294 for (
auto entity : feature._local_ids)
1296 _feature_maps[map_index][entity] =
static_cast<int>(feature._id);
1306 auto & vec_ref = insert_pair.first->second;
1307 vec_ref[feature._var_index] = feature._id;
1313 for (
auto entity : feature._halo_ids)
1314 _halo_ids[map_index][entity] =
static_cast<int>(feature._id);
1317 for (
auto entity : feature._ghosted_ids)
1322 mooseError(
"Local numbering currently disabled");
1332 mooseAssert(dof_object,
"DOF object is nullptr");
1333 mooseAssert(
_entity_queue.empty(),
"Entity queue is not empty when starting a feature");
1338 bool return_value =
false;
1343 const Elem * elem =
_is_elemental ?
static_cast<const Elem *
>(curr_dof_object) :
nullptr;
1347 auto entity_id = curr_dof_object->id();
1376 mooseAssert(current_index !=
invalid_size_t,
"current_index is invalid");
1386 return_value =
true;
1389 auto map_num =
_single_map_mode ? decltype(current_index)(0) : current_index;
1402 feature->
_id = new_id;
1419 feature->
_centroid += elem->vertex_average();
1437 return return_value;
1459 std::size_t & current_index,
1468 const Elem * elem =
static_cast<const Elem *
>(dof_object);
1469 std::vector<Point> centroid(1, elem->vertex_average());
1471 entity_value =
_vars[current_index]->sln()[0];
1474 entity_value =
_vars[current_index]->getNodalValue(*static_cast<const Node *>(dof_object));
1483 status_ptr = &feature->
_status;
1486 *status_ptr &= ~
Status::INACTIVE;
1512 for (
auto & feature : list_ref)
1514 expanded_local_ids.clear();
1516 for (
auto entity : feature._local_ids)
1519 mooseAssert(elem,
"elem pointer is NULL");
1522 auto n_nodes = elem->n_vertices();
1525 const Node * current_node = elem->node_ptr(i);
1527 auto elem_vector_it = node_to_elem_map.find(current_node->id());
1528 if (elem_vector_it == node_to_elem_map.end())
1531 const auto & elem_vector = elem_vector_it->second;
1533 std::copy(elem_vector.begin(),
1535 std::insert_iterator<FeatureData::container_type>(expanded_local_ids,
1536 expanded_local_ids.end()));
1539 for (
auto entity : elem_vector)
1542 mooseAssert(neighbor,
"neighbor pointer is NULL");
1544 if (neighbor->processor_id() != my_processor_id)
1545 feature._ghosted_ids.insert(feature._ghosted_ids.end(), elem->id());
1551 feature._local_ids.swap(expanded_local_ids);
1554 feature._halo_ids = feature._local_ids;
1562 if (num_layers_to_expand == 0)
1565 TIME_SECTION(
"expandEdgeHalos", 3,
"Expanding Edge Halos");
1569 for (
auto & feature : list_ref)
1571 for (
unsigned short halo_level = 0; halo_level < num_layers_to_expand; ++halo_level)
1578 for (
auto entity : orig_halo_ids)
1596 for (
auto entity : disjoint_orig_halo_ids)
1618 bool expand_halos_only,
1621 mooseAssert(elem,
"Elem is NULL");
1623 std::vector<const Elem *> all_active_neighbors;
1627 for (
const auto i :
make_range(elem->n_neighbors()))
1629 const Elem * neighbor_ancestor =
nullptr;
1630 bool topological_neighbor =
false;
1636 neighbor_ancestor = elem->neighbor_ptr(i);
1638 if (neighbor_ancestor)
1646 if (neighbor_ancestor->is_remote())
1649 neighbor_ancestor->active_family_tree_by_neighbor(all_active_neighbors, elem,
false);
1662 if (neighbor_ancestor)
1670 if (neighbor_ancestor->is_remote())
1673 neighbor_ancestor->active_family_tree_by_topological_neighbor(
1676 topological_neighbor =
true;
1690 all_active_neighbors,
1693 topological_neighbor,
1696 all_active_neighbors.clear();
1703 bool expand_halos_only)
1705 mooseAssert(node,
"Node is NULL");
1707 std::vector<const Node *> all_active_neighbors;
1713 template <
typename T>
1716 std::vector<const T *> neighbor_entities,
1718 bool expand_halos_only,
1719 bool topological_neighbor,
1723 for (
const auto neighbor : neighbor_entities)
1727 if (expand_halos_only)
1729 auto entity_id = neighbor->id();
1731 if (topological_neighbor || disjoint_only)
1740 if (!topological_neighbor && neighbor->processor_id() != my_processor_id)
1752 if (curr_entity->processor_id() == my_processor_id ||
1753 neighbor->processor_id() == my_processor_id)
1761 if (topological_neighbor || disjoint_only)
1783 if (elem && elem->on_boundary())
1827 for (
const auto node_n :
make_range(elem->n_nodes()))
1831 for (
auto it = iters.first; it != iters.second; ++it)
1845 for (
auto it = iters.first; it != iters.second; ++it)
1856 template <
typename T>
1865 if (belem->_elem->id() == entity->id() &&
hasBoundary(belem->_bnd_id))
1886 std::insert_iterator<FeatureData::container_type>(all_primary_region_ids,
1887 all_primary_region_ids.begin()));
1890 std::list<dof_id_type> disjoint_elem_id_list;
1893 all_primary_region_ids.begin(),
1894 all_primary_region_ids.end(),
1895 std::insert_iterator<std::list<dof_id_type>>(disjoint_elem_id_list,
1896 disjoint_elem_id_list.begin()));
1905 for (
auto elem_id : disjoint_elem_id_list)
1907 BoundingBox elem_bbox;
1910 bool found_match =
false;
1913 if (bbox.intersects(elem_bbox, TOLERANCE))
1937 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
1947 bbox.min()(i) = std::min(bbox.min()(i), rhs_bbox.min()(i));
1948 bbox.max()(i) = std::max(bbox.max()(i), rhs_bbox.max()(i));
1956 for (
const auto & bbox_lhs : _bboxes)
1957 for (
const auto & bbox_rhs : rhs.
_bboxes)
1986 ((boundingBoxesIntersect(rhs) &&
1987 ghostedIntersect(rhs))
1989 periodicBoundariesIntersect(rhs)));
1995 for (
const auto & orig_id_pair1 : _orig_ids)
1996 for (
const auto & orig_id_pair2 : rhs.
_orig_ids)
1997 if (orig_id_pair1 == orig_id_pair2)
2006 mooseAssert(_var_index == rhs._var_index,
"Mismatched variable index in merge");
2007 mooseAssert(_id == rhs._id,
"Mismatched auxiliary id in merge");
2012 std::set_union(_local_ids.begin(),
2014 rhs._local_ids.begin(),
2015 rhs._local_ids.end(),
2016 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2017 _local_ids.swap(set_union);
2021 std::set_union(_periodic_nodes.begin(),
2022 _periodic_nodes.end(),
2023 rhs._periodic_nodes.begin(),
2024 rhs._periodic_nodes.end(),
2025 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2026 _periodic_nodes.swap(set_union);
2030 std::set_union(_ghosted_ids.begin(),
2032 rhs._ghosted_ids.begin(),
2033 rhs._ghosted_ids.end(),
2034 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2043 bool physical_intersection = (_ghosted_ids.size() + rhs._ghosted_ids.size() > set_union.size());
2044 _ghosted_ids.swap(set_union);
2050 _bboxes.reserve(_bboxes.size() + rhs._bboxes.size());
2051 std::copy(rhs._bboxes.begin(), rhs._bboxes.end(), std::back_inserter(_bboxes));
2053 mergeBBoxes(_bboxes, physical_intersection);
2057 std::set_union(_disjoint_halo_ids.begin(),
2058 _disjoint_halo_ids.end(),
2059 rhs._disjoint_halo_ids.begin(),
2060 rhs._disjoint_halo_ids.end(),
2061 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2062 _disjoint_halo_ids.swap(set_union);
2068 rhs._halo_ids.begin(),
2069 rhs._halo_ids.end(),
2070 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2074 _orig_ids.splice(_orig_ids.end(), std::move(rhs._orig_ids));
2077 _min_entity_id = std::min(_min_entity_id, rhs._min_entity_id);
2085 "Flags in invalid state");
2088 _status &= rhs._status;
2091 _boundary_intersection |= rhs._boundary_intersection;
2093 _vol_count += rhs._vol_count;
2094 _centroid += rhs._centroid;
2100 mooseAssert(_var_index == rhs._var_index,
"Mismatched variable index in merge");
2101 mooseAssert(_id == rhs._id,
"Mismatched auxiliary id in merge");
2105 std::set_union(_local_ids.begin(),
2107 rhs._local_ids.begin(),
2108 rhs._local_ids.end(),
2109 std::insert_iterator<FeatureData::container_type>(set_union, set_union.begin()));
2110 _local_ids.swap(set_union);
2113 "Flags in invalid state");
2120 _periodic_nodes.clear();
2122 _disjoint_halo_ids.clear();
2123 _ghosted_ids.clear();
2130 bool physical_intersection)
2140 std::list<BoundingBox> box_list(bboxes.begin(), bboxes.end());
2142 auto box_expanded =
false;
2143 for (
auto it1 = box_list.begin(); it1 != box_list.end(); )
2145 auto merge_occured =
false;
2146 for (
auto it2 = box_list.begin(); it2 != box_list.end(); ++it2)
2148 if (it1 != it2 && it1->intersects(*it2, TOLERANCE))
2150 updateBBoxExtremes(*it2, *it1);
2151 box_list.emplace_back(std::move(*it2));
2153 box_list.erase(it2);
2154 it1 = box_list.erase(it1);
2156 box_expanded =
true;
2157 merge_occured =
true;
2170 bboxes.resize(box_list.size());
2171 std::copy(box_list.begin(), box_list.end(), bboxes.begin());
2174 if (physical_intersection && !box_expanded)
2176 std::ostringstream oss;
2177 oss <<
"LHS BBoxes:\n";
2179 oss <<
"Max: " << _bboxes[i].
max() <<
" Min: " << _bboxes[i].min() <<
'\n';
2181 ::mooseError(
"No Bounding Boxes Expanded - This is a catastrophic error!\n", oss.str());
2188 static const bool debug =
true;
2190 out <<
"Grain ID: ";
2198 out <<
"\nGhosted Entities: ";
2200 out << ghosted_id <<
" ";
2202 out <<
"\nLocal Entities: ";
2204 out << local_id <<
" ";
2206 out <<
"\nHalo Entities: ";
2208 out << halo_id <<
" ";
2210 out <<
"\nPeriodic Node IDs: ";
2212 out << periodic_node <<
" ";
2216 for (
const auto & bbox : feature.
_bboxes)
2218 out <<
"\nMax: " << bbox.max() <<
" Min: " << bbox.min();
2221 out <<
"\nStatus: ";
2233 out <<
"\nOrig IDs (rank, index): ";
2234 for (
const auto & orig_pair : feature.
_orig_ids)
2235 out <<
'(' << orig_pair.first <<
", " << orig_pair.second <<
") ";
2239 out <<
"\n" << std::endl;
2253 bbox.min()(i) = std::min(bbox.min()(i), node(i));
2254 bbox.max()(i) = std::max(bbox.max()(i), node(i));
2261 for (
const auto node_n :
make_range(elem.n_nodes()))
2269 std::numeric_limits<processor_id_type>::max();
virtual bnd_elem_iterator bndElemsEnd()
FeatureFloodCount(const InputParameters ¶meters)
void gather_packed_range(const unsigned int root_id, Context *context, Iter range_begin, const Iter range_end, OutputIter out, std::size_t approx_buffer_size=1000000) const
std::vector< BoundaryID > _primary_perc_bnds
Point _centroid
The centroid of the feature (average of coordinates from entities participating in the volume calcula...
std::size_t getNumberActiveFeatures() const
Return the number of active features.
bool halosIntersect(const FeatureData &rhs) const
Determine if one of this FeaturesData's member sets intersects the other FeatureData's corresponding ...
std::ostream & operator<<(std::ostream &out, const FeatureFloodCount::FeatureData &feature)
std::multimap< dof_id_type, dof_id_type > _periodic_node_map
The data structure which is a list of nodes that are constrained to other nodes based on the imposed ...
void visitNodalNeighbors(const Node *node, FeatureData *feature, bool expand_halos_only)
These two routines are utility routines used by the flood routine and by derived classes for visiting...
std::vector< BoundingBox > _bboxes
The vector of bounding boxes completely enclosing this feature (multiple used with periodic constrain...
const PostprocessorValue & _element_average_value
Average value of the domain which can optionally be used to find features in a field.
void expandEdgeHalos(unsigned int num_layers_to_expand)
This method expands the existing halo set by some width determined by the passed in value...
std::vector< BoundaryID > _specified_bnds
std::vector< BoundaryID > _secondary_perc_bnds
void expandPointHalos()
This method takes all of the partial features and expands the local, ghosted, and halo sets around th...
container_type _halo_ids
Holds the ids surrounding the feature.
void scatter(const std::vector< T, A > &data, T &recv, const unsigned int root_id=0) const
const std::size_t _n_vars
static const std::size_t invalid_size_t
virtual void updateFieldInfo()
This method is used to populate any of the data structures used for storing field data (nodal or elem...
static InputParameters validParams()
virtual bool boundaryRestricted() const
std::vector< dof_id_type > container_type
The primary underlying container type used to hold the data in each FeatureData.
void appendPeriodicNeighborNodes(FeatureData &feature) const
This routine adds the periodic node information to our data structure prior to packing the data this ...
virtual Elem * elemPtr(const dof_id_type i)
virtual const std::vector< unsigned int > & getVarToFeatureVector(dof_id_type elem_id) const
Returns a list of active unique feature ids for a particular element.
void serialize(std::string &serialized_buffer, unsigned int var_num=invalid_id)
This routines packs the _partial_feature_sets data into a structure suitable for parallel communicati...
const std::map< dof_id_type, std::vector< dof_id_type > > & nodeToActiveSemilocalElemMap()
static constexpr Real TOLERANCE
Real _step_connecting_threshold
const bool _condense_map_info
void mooseInfo(Args &&... args) const
void gather(const unsigned int root_id, const T &send_data, std::vector< T, A > &recv) const
container_type _ghosted_ids
Holds the ghosted ids for a feature (the ids which will be used for stitching.
Status
This enumeration is used to indicate status of the grains in the _unique_grains data structure...
std::vector< std::set< dof_id_type > > _entities_visited
This variable keeps track of which nodes have been visited during execution.
registerMooseObject("PhaseFieldApp", FeatureFloodCount)
void updateBBoxExtremes(MeshBase &mesh)
Update the minimum and maximum coordinates of a bounding box given a Point, Elem or BBox parameter...
bool mergeable(const FeatureData &rhs) const
The routine called to see if two features are mergeable:
bool boundingBoxesIntersect(const FeatureData &rhs) const
Determines if any of this FeatureData's bounding boxes overlap with the other FeatureData's bounding ...
static void sort(std::set< T > &)
virtual void finalize() override
bool setsIntersect(InputIterator first1, InputIterator last1, InputIterator first2, InputIterator last2)
container_type _disjoint_halo_ids
Holds halo ids that extend onto a non-topologically connected surface.
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
bool isBoundaryEntity(const T *entity) const
Returns a Boolean indicating whether the entity is on one of the desired boundaries.
const bool _is_primary
Convenience variable for testing primary rank.
static constexpr std::size_t dim
virtual bnd_elem_iterator bndElemsBegin()
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
virtual std::size_t getTotalFeatureCount() const
Returns the total feature count (active and inactive ids, useful for sizing vectors) ...
void communicateAndMerge()
This routine handles all of the serialization, communication and deserialization of the data structur...
virtual void initialize() override
const Parallel::Communicator & _communicator
std::pair< typename M::iterator, bool > moose_try_emplace(M &m, const typename M::key_type &k, Args &&... args)
virtual bool areFeaturesMergeable(const FeatureData &f1, const FeatureData &f2) const
Method for determining whether two features are mergeable.
void mooseWarning(Args &&... args) const
std::map< dof_id_type, int > _ghosted_entity_ids
The map for holding reconstructed ghosted element information.
auto max(const L &left, const R &right)
virtual bool isFeaturePercolated(unsigned int feature_id) const
Returns a Boolean indicating whether this feature is percolated (e.g.
virtual void buildLocalToGlobalIndices(std::vector< std::size_t > &local_to_global_all, std::vector< int > &counts) const
This routine populates a stacked vector of local to global indices per rank and the associated count ...
void storeHelper(std::ostream &stream, P &data, void *context)
void sortAndLabel()
Sort and assign ids to features based on their position in the container after sorting.
static InputParameters validParams()
virtual void consolidateMergedFeatures(std::vector< std::list< FeatureData >> *saved_data=nullptr)
This method consolidates all of the merged information from _partial_feature_sets into the _feature_s...
uint8_t processor_id_type
static bool contains(std::set< T > &container, const T &item)
virtual unsigned int getFeatureVar(unsigned int feature_id) const
Returns the variable representing the passed in feature.
processor_id_type n_processors() const
const dof_id_type n_nodes
dof_id_type _min_entity_id
The minimum entity seen in the _local_ids, used for sorting features.
std::vector< std::map< dof_id_type, int > > _halo_ids
The data structure for looking up halos around features.
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
const Real _connecting_threshold
The threshold above (or below) which neighboring entities are flooded (where regions can be extended ...
virtual void execute() override
void dataStore(std::ostream &stream, FeatureFloodCount::FeatureData &feature, void *context)
std::size_t _var_index
The Moose variable where this feature was found (often the "order parameter")
virtual void clearDataStructures()
Helper routine for clearing up data structures during initialize and prior to parallel communication...
boundary_id_type BoundaryID
virtual const Node * nodePtr(const dof_id_type i) const
virtual bool isTransient() const=0
BoundaryIntersection
This enumeration is used to inidacate status of boundary intersections.
unsigned long _var_number
This variable is used to build the periodic node map.
This object will mark nodes or elements of continuous regions all with a unique number for the purpos...
virtual processor_id_type numberOfDistributedMergeHelpers() const
Returns a number indicating the number of merge helpers when running in parallel based on certain imp...
container_type _periodic_nodes
Holds the nodes that belong to the feature on a periodic boundary.
void visitElementalNeighbors(const Elem *elem, FeatureData *feature, bool expand_halos_only, bool disjoint_only)
void split(int color, int key, Communicator &target) const
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
const bool _use_less_than_threshold_comparison
Use less-than when comparing values against the threshold value.
bool ghostedIntersect(const FeatureData &rhs) const
const bool _global_numbering
This variable is used to indicate whether or not we identify features with unique numbers on multiple...
void dataLoad(std::istream &stream, FeatureFloodCount::FeatureData &feature, void *context)
const DofMap & _dof_map
Reference to the dof_map containing the coupled variables.
static const unsigned int invalid_id
NonlinearSystemBase & getNonlinearSystemBase(const unsigned int sys_num)
void paramError(const std::string ¶m, Args... args) const
unsigned int number() const
bool canConsolidate(const FeatureData &rhs) const
This routine indicates whether two features can be consolidated, that is, one feature is reasonably e...
std::vector< std::map< dof_id_type, int > > _feature_maps
The feature maps contain the raw flooded node information and eventually the unique grain numbers...
virtual Real getConnectingThreshold(std::size_t current_index) const
Return the "connecting" comparison threshold to use when inspecting an entity during the flood stage...
const bool _single_map_mode
This variable is used to indicate whether or not multiple maps are used during flooding.
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...
virtual Real getValue() const override
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid) override
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
static InputParameters validParams()
virtual bool doesFeatureIntersectSpecifiedBoundary(unsigned int feature_id) const
Returns a Boolean indicating whether this feature intersects boundaries in a user-supplied list...
const Real _threshold
The threshold above (or below) where an entity may begin a new region (feature)
void consolidate(FeatureData &&rhs)
Consolidates features, i.e.
bool hasBoundary(const BoundaryName &name) const
std::unique_ptr< PointLocatorBase > _point_locator
virtual void mergeSets()
This routine is called on the primary rank only and stitches together the partial feature pieces seen...
bool _is_boundary_restricted
Indicates that this object should only run on one or more boundaries.
std::vector< MooseVariableFEBase * > _fe_vars
The vector of coupled in variables.
virtual bool isNewFeatureOrConnectedRegion(const DofObject *dof_object, std::size_t ¤t_index, FeatureData *&feature, Status &status, unsigned int &new_id)
Method called during the recursive flood routine that should return whether or not the current entity...
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
static void reserve(std::set< T > &, std::size_t)
virtual void reinitElemPhys(const Elem *elem, const std::vector< Point > &phys_points_in_elem, const THREAD_ID tid)=0
void merge(FeatureData &&rhs)
Merges another Feature Data into this one.
virtual void restoreOriginalDataStructures(std::vector< std::list< FeatureData >> &)
const bool _compute_halo_maps
Indicates whether or not to communicate halo map information with all ranks.
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
void addMooseVariableDependency(MooseVariableFieldBase *var)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::unordered_map< dof_id_type, std::vector< const Elem * > > _nodes_to_elem_map
The data structure used to find neighboring elements give a node ID.
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
std::vector< unsigned int > _empty_var_to_features
void visitNeighborsHelper(const T *curr_entity, std::vector< const T *> neighbor_entities, FeatureData *feature, bool expand_halos_only, bool topological_neighbor, bool disjoint_only)
The actual logic for visiting neighbors is abstracted out here.
bool flood(const DofObject *dof_object, std::size_t current_index)
This method will check if the current entity is above the supplied threshold and "mark" it...
container_type _local_ids
Holds the local ids in the interior of a feature.
FEProblemBase & _fe_problem
const processor_id_type _n_procs
Convenience variable holding the number of processors in this simulation.
IntRange< T > make_range(T beg, T end)
void updateBoundaryIntersections(FeatureData &feature) const
Update the feature's attributes to indicate boundary intersections.
virtual void meshChanged() override
std::vector< unsigned int > _feature_counts_per_map
The number of features seen by this object per map.
void mooseError(Args &&... args) const
std::vector< std::size_t > _feature_id_to_local_index
The vector recording the grain_id to local index (several indices will contain invalid_size_t) ...
ConstBndElemRange * _bnd_elem_range
Boundary element range pointer.
static const processor_id_type invalid_proc_id
const InputParameters & parameters() const
std::list< std::pair< processor_id_type, unsigned int > > _orig_ids
Original processor/local ids.
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
virtual void initialSetup() override
BoundaryIntersection _boundary_intersection
Enumeration indicating boundary intersection status.
void updateBBoxExtremesHelper(BoundingBox &bbox, const Point &node)
Status _status
The status of a feature (used mostly in derived classes like the GrainTracker)
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement *> * getBoundaryElementRange()
bool compareValueWithThreshold(Real entity_value, Real threshold) const
This method is used to determine whether the current entity value is part of a feature or not...
bool isBoundaryElem(dof_id_type elem_id) const
void deserialize(std::vector< std::string > &serialized_buffers, unsigned int var_num=invalid_id)
This routine takes the vector of byte buffers (one for each processor), deserializes them into a seri...
void mergeBBoxes(std::vector< BoundingBox > &bboxes, bool physical_intersection)
Located the overlapping bounding box between this Feature and the other Feature and expands that over...
MooseMesh & _mesh
A reference to the mesh.
processor_id_type processor_id() const
virtual Real getEntityValue(dof_id_type entity_id, FieldType field_type, std::size_t var_index=0) const
void buildFeatureIdToLocalIndices(unsigned int max_id)
This method builds a lookup map for retrieving the right local feature (by index) given a global inde...
void scatterAndUpdateRanks()
Calls buildLocalToGlobalIndices to build the individual local to global indicies for each rank and sc...
virtual bool doesFeatureIntersectBoundary(unsigned int feature_id) const
Returns a Boolean indicating whether this feature intersects any boundary.
std::deque< const DofObject * > _entity_queue
The data structure for maintaining entities to flood during discovery.
bool periodicBoundariesIntersect(const FeatureData &rhs) const
void loadHelper(std::istream &stream, P &data, void *context)
const bool _compute_var_to_feature_map
Indicates whether or not the var to feature map is populated.
auto index_range(const T &sizable)
void buildPeriodicNodeMap(std::multimap< dof_id_type, dof_id_type > &periodic_node_map, unsigned int var_number, PeriodicBoundaries *pbs) const
std::unordered_set< dof_id_type > _all_boundary_entity_ids
The set of entities on the boundary of the domain used for determining if features intersect any boun...
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
std::size_t _vol_count
The count of entities contributing to the volume calculation.
unsigned int _id
An ID for this feature.
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.
virtual Point featureCentroid(unsigned int feature_id) const
Returns the centroid of the designated feature (only supported without periodic boundaries) ...
virtual Real getThreshold(std::size_t current_index) const
Return the starting comparison threshold to use when inspecting an entity during the flood stage...
std::vector< std::size_t > _local_to_global_feature_map
The vector recording the local to global feature indices.
virtual void prepareDataForTransfer()
This routine uses the local flooded data to build up the local feature data structures (_partial feat...