www.mooseframework.org
Classes | Public Types | Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
FeatureFloodCount Class Reference

This object will mark nodes or elements of continuous regions all with a unique number for the purpose of counting or "coloring" unique regions in a solution. More...

#include <FeatureFloodCount.h>

Inheritance diagram for FeatureFloodCount:
[legend]

Classes

class  FeatureData
 

Public Types

enum  FieldType {
  FieldType::UNIQUE_REGION, FieldType::VARIABLE_COLORING, FieldType::GHOSTED_ENTITIES, FieldType::HALOS,
  FieldType::CENTROID, FieldType::ACTIVE_BOUNDS
}
 
enum  Status : unsigned char { Status::CLEAR = 0x0, Status::MARKED = 0x1, Status::DIRTY = 0x2, Status::INACTIVE = 0x4 }
 This enumeration is used to indicate status of the grains in the _unique_grains data structure. More...
 

Public Member Functions

 FeatureFloodCount (const InputParameters &parameters)
 
 ~FeatureFloodCount ()
 
virtual void initialSetup () override
 
virtual void meshChanged () override
 
virtual void initialize () override
 
virtual void execute () override
 
virtual void finalize () override
 
virtual Real getValue () override
 
std::size_t getNumberActiveFeatures () const
 Return the number of active features. More...
 
virtual std::size_t getTotalFeatureCount () const
 Returns the total feature count (active and inactive ids, useful for sizing vectors) More...
 
virtual bool doesFeatureIntersectBoundary (unsigned int feature_id) const
 Returns a Boolean indicating whether this feature intersects any boundary. More...
 
virtual Point featureCentroid (unsigned int feature_id) const
 Returns the centroid of the designated feature (only suppored without periodic boundaries) More...
 
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. More...
 
virtual unsigned int getFeatureVar (unsigned int feature_id) const
 Returns the variable representing the passed in feature. More...
 
std::size_t numCoupledVars () const
 Returns the number of coupled varaibles. More...
 
const std::vector< MooseVariable * > & getCoupledVars () const
 Returns a const vector to the coupled variable pointers. More...
 
const std::vector< MooseVariableFEBase * > & getFECoupledVars () const
 Returns a const vector to the coupled MooseVariableFEBase pointers. More...
 
virtual Real getEntityValue (dof_id_type entity_id, FieldType field_type, std::size_t var_index=0) const
 
bool isElemental () const
 
const std::vector< FeatureData > & getFeatures () const
 Return a constant reference to the vector of all discovered features. More...
 

Static Public Attributes

static const std::size_t invalid_size_t = std::numeric_limits<std::size_t>::max()
 
static const unsigned int invalid_id = std::numeric_limits<unsigned int>::max()
 

Protected Member Functions

template<typename T >
bool isBoundaryEntity (const T *entity) const
 Returns a Boolean indicating whether the entity is on one of the desired boundaries. More...
 
virtual void updateFieldInfo ()
 This method is used to populate any of the data structures used for storing field data (nodal or elemental). More...
 
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. More...
 
virtual Real getThreshold (std::size_t current_index) const
 Return the starting comparison threshold to use when inspecting an entity during the flood stage. More...
 
virtual Real getConnectingThreshold (std::size_t current_index) const
 Return the "connecting" comparison threshold to use when inspecting an entity during the flood stage. More...
 
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. More...
 
virtual bool isNewFeatureOrConnectedRegion (const DofObject *dof_object, std::size_t &current_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 is part of the current feature (if one is being explored), or if it's the start of a new feature. More...
 
void expandPointHalos ()
 This method takes all of the partial features and expands the local, ghosted, and halo sets around those regions to account for the diffuse interface. More...
 
void expandEdgeHalos (unsigned int num_layers_to_expand)
 This method expands the existing halo set by some width determined by the passed in value. More...
 
template<typename T >
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. More...
 
void prepareDataForTransfer ()
 This routine uses the local flooded data to build up the local feature data structures (_feature_sets). More...
 
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 communication operations. More...
 
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 series of FeatureSet objects, and appends them to the _feature_sets data structure. More...
 
virtual void mergeSets ()
 This routine is called on the master rank only and stitches together the partial feature pieces seen on any processor. More...
 
virtual bool areFeaturesMergeable (const FeatureData &f1, const FeatureData &f2) const
 Method for determining whether two features are mergeable. More...
 
void communicateAndMerge ()
 This routine handles all of the serialization, communication and deserialization of the data structures containing FeatureData objects. More...
 
void sortAndLabel ()
 Sort and assign ids to features based on their position in the container after sorting. More...
 
void scatterAndUpdateRanks ()
 Calls buildLocalToGlobalIndices to build the individual local to global indicies for each rank and scatters that information to all ranks. More...
 
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 vector for scattering the vector to the ranks. More...
 
void buildFeatureIdToLocalIndices (unsigned int max_id)
 This method builds a lookup map for retrieving the right local feature (by index) given a global index or id. More...
 
virtual void clearDataStructures ()
 Helper routine for clearing up data structures during initialize and prior to parallel communication. More...
 
void appendPeriodicNeighborNodes (FeatureData &feature) const
 This routine adds the periodic node information to our data structure prior to packing the data this makes those periodic neighbors appear much like ghosted nodes in a multiprocessor setting. More...
 
void updateRegionOffsets ()
 This routine updates the _region_offsets variable which is useful for quickly determining the proper global number for a feature when using multimap mode. More...
 
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 neighbors. More...
 
void visitElementalNeighbors (const Elem *elem, FeatureData *feature, bool expand_halos_only, bool disjoint_only)
 

Static Protected Member Functions

template<class InputIterator >
static bool setsIntersect (InputIterator first1, InputIterator last1, InputIterator first2, InputIterator last2)
 This method detects whether two sets intersect without building a result set. More...
 

Protected Attributes

std::vector< MooseVariableFEBase * > _fe_vars
 The vector of coupled in variables. More...
 
std::vector< MooseVariable * > _vars
 The vector of coupled in variables cast to MooseVariable. More...
 
const DofMap & _dof_map
 Reference to the dof_map containing the coupled variables. More...
 
const Real _threshold
 The threshold above (or below) where an entity may begin a new region (feature) More...
 
Real _step_threshold
 
const Real _connecting_threshold
 The threshold above (or below) which neighboring entities are flooded (where regions can be extended but not started) More...
 
Real _step_connecting_threshold
 
MooseMesh & _mesh
 A reference to the mesh. More...
 
unsigned long _var_number
 This variable is used to build the periodic node map. More...
 
const bool _single_map_mode
 This variable is used to indicate whether or not multiple maps are used during flooding. More...
 
const bool _condense_map_info
 
const bool _global_numbering
 This variable is used to indicate whether or not we identify features with unique numbers on multiple maps. More...
 
const bool _var_index_mode
 This variable is used to indicate whether the maps will contain unique region information or just the variable numbers owning those regions. More...
 
const bool _compute_halo_maps
 Indicates whether or not to communicate halo map information with all ranks. More...
 
const bool _compute_var_to_feature_map
 Indicates whether or not the var to feature map is populated. More...
 
const bool _use_less_than_threshold_comparison
 Use less-than when comparing values against the threshold value. More...
 
const std::size_t _n_vars
 
const std::size_t _maps_size
 Convenience variable holding the size of all the datastructures size by the number of maps. More...
 
const processor_id_type _n_procs
 Convenience variable holding the number of processors in this simulation. More...
 
std::vector< std::set< dof_id_type > > _entities_visited
 This variable keeps track of which nodes have been visited during execution. More...
 
std::vector< std::map< dof_id_type, int > > _var_index_maps
 This map keeps track of which variables own which nodes. More...
 
std::vector< std::vector< const Elem * > > _nodes_to_elem_map
 The data structure used to find neighboring elements give a node ID. More...
 
std::vector< unsigned int > _feature_counts_per_map
 The number of features seen by this object per map. More...
 
unsigned int _feature_count
 The number of features seen by this object (same as summing _feature_counts_per_map) More...
 
std::vector< std::list< FeatureData > > _partial_feature_sets
 The data structure used to hold partial and communicated feature data, during the discovery and merging phases. More...
 
std::vector< FeatureData > & _feature_sets
 The data structure used to hold the globally unique features. More...
 
std::vector< FeatureData_volatile_feature_sets
 Derived objects (e.g. More...
 
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. More...
 
std::vector< std::size_t > _local_to_global_feature_map
 The vector recording the local to global feature indices. More...
 
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) More...
 
PeriodicBoundaries * _pbs
 A pointer to the periodic boundary constraints object. More...
 
std::unique_ptr< PointLocatorBase > _point_locator
 
const PostprocessorValue & _element_average_value
 Average value of the domain which can optionally be used to find features in a field. More...
 
std::map< dof_id_type, int > _ghosted_entity_ids
 The map for holding reconstructed ghosted element information. More...
 
std::vector< std::map< dof_id_type, int > > _halo_ids
 The data structure for looking up halos around features. More...
 
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 periodic boundary conditions. More...
 
std::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 boundary. More...
 
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
 
std::vector< unsigned int > _empty_var_to_features
 
const bool _is_elemental
 Determines if the flood counter is elements or not (nodes) More...
 
bool _is_boundary_restricted
 Indicates that this object should only run on one or more boundaries. More...
 
ConstBndElemRange * _bnd_elem_range
 Boundary element range pointer (used when boundary restricting this object. More...
 
const bool _is_master
 Convenience variable for testing master rank. More...
 

Private Member Functions

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_sets vectors. More...
 

Static Private Member Functions

template<class T >
static void sort (std::set< T > &)
 
template<class T >
static void sort (std::vector< T > &container)
 
template<class T >
static void reserve (std::set< T > &, std::size_t)
 
template<class T >
static void reserve (std::vector< T > &container, std::size_t size)
 

Private Attributes

std::deque< const DofObject * > _entity_queue
 The data structure for maintaining entities to flood during discovery. More...
 
const bool _distribute_merge_work
 Keeps track of whether we are distributing the merge work. More...
 
const PerfID _execute_timer
 Timers. More...
 
const PerfID _merge_timer
 
const PerfID _finalize_timer
 
const PerfID _comm_and_merge
 
const PerfID _expand_halos
 
const PerfID _update_field_info
 
const PerfID _prepare_for_transfer
 
const PerfID _consolidate_merged_features
 

Detailed Description

This object will mark nodes or elements of continuous regions all with a unique number for the purpose of counting or "coloring" unique regions in a solution.

It is designed to work with either a single variable, or multiple variables.

Note: When inspecting multiple variables, those variables must not have regions of interest that overlap or they will not be correctly colored.

Definition at line 45 of file FeatureFloodCount.h.

Member Enumeration Documentation

◆ FieldType

Enumerator
UNIQUE_REGION 
VARIABLE_COLORING 
GHOSTED_ENTITIES 
HALOS 
CENTROID 
ACTIVE_BOUNDS 

Definition at line 98 of file FeatureFloodCount.h.

99  {
100  UNIQUE_REGION,
101  VARIABLE_COLORING,
102  GHOSTED_ENTITIES,
103  HALOS,
104  CENTROID,
105  ACTIVE_BOUNDS,
106  };

◆ Status

enum FeatureFloodCount::Status : unsigned char
strong

This enumeration is used to indicate status of the grains in the _unique_grains data structure.

Enumerator
CLEAR 
MARKED 
DIRTY 
INACTIVE 

Definition at line 115 of file FeatureFloodCount.h.

115  : unsigned char
116  {
117  CLEAR = 0x0,
118  MARKED = 0x1,
119  DIRTY = 0x2,
120  INACTIVE = 0x4
121  };

Constructor & Destructor Documentation

◆ FeatureFloodCount()

FeatureFloodCount::FeatureFloodCount ( const InputParameters &  parameters)

Definition at line 172 of file FeatureFloodCount.C.

173  : GeneralPostprocessor(parameters),
174  Coupleable(this, false),
175  MooseVariableDependencyInterface(),
176  BoundaryRestrictable(this, false),
177  _fe_vars(getCoupledMooseVars()),
178  _vars(getCoupledStandardMooseVars()),
179  _dof_map(_vars[0]->dofMap()),
180  _threshold(getParam<Real>("threshold")),
181  _connecting_threshold(isParamValid("connecting_threshold")
182  ? getParam<Real>("connecting_threshold")
183  : getParam<Real>("threshold")),
184  _mesh(_subproblem.mesh()),
185  _var_number(_fe_vars[0]->number()),
186  _single_map_mode(getParam<bool>("use_single_map")),
187  _condense_map_info(getParam<bool>("condense_map_info")),
188  _global_numbering(getParam<bool>("use_global_numbering")),
189  _var_index_mode(getParam<bool>("enable_var_coloring")),
190  _compute_halo_maps(getParam<bool>("compute_halo_maps")),
191  _compute_var_to_feature_map(getParam<bool>("compute_var_to_feature_map")),
192  _use_less_than_threshold_comparison(getParam<bool>("use_less_than_threshold_comparison")),
193  _n_vars(_fe_vars.size()),
194  _maps_size(_single_map_mode ? 1 : _fe_vars.size()),
195  _n_procs(_app.n_processors()),
197  _feature_count(0),
199  _feature_sets(getParam<bool>("restartable_required")
200  ? declareRestartableData<std::vector<FeatureData>>("feature_sets")
203  _pbs(nullptr),
204  _element_average_value(parameters.isParamValid("elem_avg_value")
205  ? getPostprocessorValue("elem_avg_value")
206  : _real_zero),
208  _is_elemental(getParam<MooseEnum>("flood_entity_type") == "ELEMENTAL"),
209  _is_master(processor_id() == 0),
210  _distribute_merge_work(_app.n_processors() >= _maps_size && _maps_size > 1),
211  _execute_timer(registerTimedSection("execute", 1)),
212  _merge_timer(registerTimedSection("mergeFeatures", 2)),
213  _finalize_timer(registerTimedSection("finalize", 1)),
214  _comm_and_merge(registerTimedSection("communicateAndMerge", 2)),
215  _expand_halos(registerTimedSection("expandEdgeHalos", 2)),
216  _update_field_info(registerTimedSection("updateFieldInfo", 2)),
217  _prepare_for_transfer(registerTimedSection("prepareDataForTransfer", 2)),
218  _consolidate_merged_features(registerTimedSection("consolidateMergedFeatures", 2))
219 {
220  if (_var_index_mode)
221  _var_index_maps.resize(_maps_size);
222 
223  addMooseVariableDependency(_fe_vars);
224 
225  _is_boundary_restricted = boundaryRestricted();
226 }
const PerfID _finalize_timer
const PostprocessorValue & _element_average_value
Average value of the domain which can optionally be used to find features in a field.
const std::size_t _n_vars
const bool _condense_map_info
const PerfID _merge_timer
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const PerfID _comm_and_merge
const PerfID _consolidate_merged_features
const PerfID _execute_timer
Timers.
const bool _is_master
Convenience variable for testing master rank.
std::vector< FeatureData > _volatile_feature_sets
Derived objects (e.g.
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 ...
unsigned long _var_number
This variable is used to build the periodic node map.
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.
const bool _global_numbering
This variable is used to indicate whether or not we identify features with unique numbers on multiple...
const DofMap & _dof_map
Reference to the dof_map containing the coupled variables.
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...
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) ...
const Real _threshold
The threshold above (or below) where an entity may begin a new region (feature)
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.
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
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.
const bool _distribute_merge_work
Keeps track of whether we are distributing the merge work.
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
const processor_id_type _n_procs
Convenience variable holding the number of processors in this simulation.
const PerfID _update_field_info
std::vector< unsigned int > _feature_counts_per_map
The number of features seen by this object per map.
const PerfID _expand_halos
const PerfID _prepare_for_transfer
MooseMesh & _mesh
A reference to the mesh.
const bool _compute_var_to_feature_map
Indicates whether or not the var to feature map is populated.
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.

◆ ~FeatureFloodCount()

FeatureFloodCount::~FeatureFloodCount ( )

Definition at line 228 of file FeatureFloodCount.C.

228 {}

Member Function Documentation

◆ appendPeriodicNeighborNodes()

void FeatureFloodCount::appendPeriodicNeighborNodes ( FeatureData feature) const
protected

This routine adds the periodic node information to our data structure prior to packing the data this makes those periodic neighbors appear much like ghosted nodes in a multiprocessor setting.

Definition at line 1625 of file FeatureFloodCount.C.

Referenced by prepareDataForTransfer().

1626 {
1627  if (_is_elemental)
1628  {
1629  for (auto entity : feature._local_ids)
1630  {
1631  Elem * elem = _mesh.elemPtr(entity);
1632 
1633  for (auto node_n = decltype(elem->n_nodes())(0); node_n < elem->n_nodes(); ++node_n)
1634  {
1635  auto iters = _periodic_node_map.equal_range(elem->node(node_n));
1636 
1637  for (auto it = iters.first; it != iters.second; ++it)
1638  {
1639  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->first);
1640  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->second);
1641  }
1642  }
1643  }
1644  }
1645  else
1646  {
1647  for (auto entity : feature._local_ids)
1648  {
1649  auto iters = _periodic_node_map.equal_range(entity);
1650 
1651  for (auto it = iters.first; it != iters.second; ++it)
1652  {
1653  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->first);
1654  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->second);
1655  }
1656  }
1657  }
1658 
1659  // TODO: Remove duplicates
1660 }
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 ...
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
MooseMesh & _mesh
A reference to the mesh.

◆ areFeaturesMergeable()

bool FeatureFloodCount::areFeaturesMergeable ( const FeatureData f1,
const FeatureData f2 
) const
protectedvirtual

Method for determining whether two features are mergeable.

This routine exists because derived classes may need to override this function rather than use the mergeable method in the FeatureData object.

Reimplemented in PolycrystalUserObjectBase.

Definition at line 1143 of file FeatureFloodCount.C.

Referenced by mergeSets().

1144 {
1145  return f1.mergeable(f2);
1146 }

◆ buildFeatureIdToLocalIndices()

void FeatureFloodCount::buildFeatureIdToLocalIndices ( unsigned int  max_id)
protected

This method builds a lookup map for retrieving the right local feature (by index) given a global index or id.

max_id is passed to size the vector properly and may or may not be a globally consistent number. The assumption is that any id that is later queried from this object that is higher simply doesn't exist on the local processor.

Definition at line 618 of file FeatureFloodCount.C.

Referenced by GrainTracker::assignGrains(), scatterAndUpdateRanks(), and GrainTracker::trackGrains().

619 {
620  _feature_id_to_local_index.assign(max_id + 1, invalid_size_t);
621  for (auto feature_index = beginIndex(_feature_sets); feature_index < _feature_sets.size();
622  ++feature_index)
623  {
624  if (_feature_sets[feature_index]._status != Status::INACTIVE)
625  {
626  mooseAssert(_feature_sets[feature_index]._id <= max_id,
627  "Feature ID out of range(" << _feature_sets[feature_index]._id << ')');
628  _feature_id_to_local_index[_feature_sets[feature_index]._id] = feature_index;
629  }
630  }
631 }
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
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) ...

◆ buildLocalToGlobalIndices()

void FeatureFloodCount::buildLocalToGlobalIndices ( std::vector< std::size_t > &  local_to_global_all,
std::vector< int > &  counts 
) const
protectedvirtual

This routine populates a stacked vector of local to global indices per rank and the associated count vector for scattering the vector to the ranks.

The individual vectors can be different sizes. The ith vector will be distributed to the ith processor including the master rank. e.g. [ ... n_0 ] [ ... n_1 ] ... [ ... n_m ]

It is intended to be overridden in derived classes.

Definition at line 572 of file FeatureFloodCount.C.

Referenced by scatterAndUpdateRanks().

574 {
575  mooseAssert(_is_master, "This method must only be called on the root processor");
576 
577  counts.assign(_n_procs, 0);
578  // Now size the individual counts vectors based on the largest index seen per processor
579  for (const auto & feature : _feature_sets)
580  for (const auto & local_index_pair : feature._orig_ids)
581  {
582  // local_index_pair.first = ranks, local_index_pair.second = local_index
583  mooseAssert(local_index_pair.first < _n_procs, "Processor ID is out of range");
584  if (local_index_pair.second >= static_cast<std::size_t>(counts[local_index_pair.first]))
585  counts[local_index_pair.first] = local_index_pair.second + 1;
586  }
587 
588  // Build the offsets vector
589  unsigned int globalsize = 0;
590  std::vector<int> offsets(_n_procs); // Type is signed for use with the MPI API
591  for (auto i = beginIndex(offsets); i < offsets.size(); ++i)
592  {
593  offsets[i] = globalsize;
594  globalsize += counts[i];
595  }
596 
597  // Finally populate the master vector
598  local_to_global_all.resize(globalsize, FeatureFloodCount::invalid_size_t);
599  for (const auto & feature : _feature_sets)
600  {
601  // Get the local indices from the feature and build a map
602  for (const auto & local_index_pair : feature._orig_ids)
603  {
604  auto rank = local_index_pair.first;
605  mooseAssert(rank < _n_procs, rank << ", " << _n_procs);
606 
607  auto local_index = local_index_pair.second;
608  auto stacked_local_index = offsets[rank] + local_index;
609 
610  mooseAssert(stacked_local_index < globalsize,
611  "Global index: " << stacked_local_index << " is out of range");
612  local_to_global_all[stacked_local_index] = feature._id;
613  }
614  }
615 }
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const bool _is_master
Convenience variable for testing master rank.
const processor_id_type _n_procs
Convenience variable holding the number of processors in this simulation.

◆ clearDataStructures()

void FeatureFloodCount::clearDataStructures ( )
protectedvirtual

Helper routine for clearing up data structures during initialize and prior to parallel communication.

Definition at line 284 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

285 {
286 }

◆ communicateAndMerge()

void FeatureFloodCount::communicateAndMerge ( )
protected

This routine handles all of the serialization, communication and deserialization of the data structures containing FeatureData objects.

The libMesh packed range routines handle the communication of the individual string buffers. Here we need to create a container to hold our type to serialize. It'll always be size one because we are sending a single byte stream of all the data to other processors. The stream need not be the same size on all processors.

Additionally we need to create a different container to hold the received byte buffers. The container type need not match the send container type. However, We do know the number of incoming buffers (num processors) so we'll go ahead and use a vector.

When we distribute merge work, we are reducing computational work by adding more communication. Each of the first _n_vars processors will receive one variable worth of information to merge. After each of those processors has merged that information, it'll be sent to the master processor where final consolidation will occur.

Send the data from all processors to the first _n_vars processors to create a complete global feature maps for each variable.

A call to gather_packed_range seems to populate the receiving buffer on all processors, not just the receiving buffer on the actual receiving processor. If we plan to call this function repeatedly, we must clear the buffers each time on all non-receiving processors. On the actual receiving processor, we'll save off the buffer for use later.

The FeatureFloodCount and derived algorithms rely on having the data structures intact on all non-zero ranks. This is because local-only information (local entities) is never communicated and thus must remain intact. However, the distributed merging will destroy that information. The easiest thing to do is to swap out the data structure while we perform the distributed merge work.

Send the data from the merging processors to the root to create a complete global feature map.

Send the data from all processors to the root to create a complete global feature map.

Definition at line 365 of file FeatureFloodCount.C.

Referenced by GrainTracker::finalize(), and finalize().

366 {
367  TIME_SECTION(_comm_and_merge);
368 
369  // First we need to transform the raw data into a usable data structure
371 
379  std::vector<std::string> send_buffers(1);
380 
387  std::vector<std::string> recv_buffers, deserialize_buffers;
388 
396  {
397  auto rank = processor_id();
398  bool is_merging_processor = rank < _n_vars;
399 
400  if (is_merging_processor)
401  recv_buffers.reserve(_app.n_processors());
402 
403  for (auto i = decltype(_n_vars)(0); i < _n_vars; ++i)
404  {
405  serialize(send_buffers[0], i);
406 
411  _communicator.gather_packed_range(i,
412  (void *)(nullptr),
413  send_buffers.begin(),
414  send_buffers.end(),
415  std::back_inserter(recv_buffers));
416 
423  if (rank == i)
424  recv_buffers.swap(deserialize_buffers);
425  else
426  recv_buffers.clear();
427  }
428 
429  // Setup a new communicator for doing merging communication operations
430  Parallel::Communicator merge_comm;
431 
432  // TODO: Update to MPI_UNDEFINED when libMesh bug is fixed.
433  _communicator.split(is_merging_processor ? 0 : 1, rank, merge_comm);
434 
435  if (is_merging_processor)
436  {
444  std::vector<std::list<FeatureData>> tmp_data(_partial_feature_sets.size());
445  tmp_data.swap(_partial_feature_sets);
446 
447  deserialize(deserialize_buffers, processor_id());
448 
449  send_buffers[0].clear();
450  recv_buffers.clear();
451  deserialize_buffers.clear();
452 
453  // Merge one variable's worth of data
454  mergeSets();
455 
456  // Now we need to serialize again to send to the master (only the processors who did work)
457  serialize(send_buffers[0]);
458 
459  // Free up as much memory as possible here before we do global communication
461 
466  merge_comm.gather_packed_range(0,
467  (void *)(nullptr),
468  send_buffers.begin(),
469  send_buffers.end(),
470  std::back_inserter(recv_buffers));
471 
472  if (_is_master)
473  {
474  // The root process now needs to deserialize all of the data
475  deserialize(recv_buffers);
476 
477  send_buffers[0].clear();
478  recv_buffers.clear();
479 
480  consolidateMergedFeatures(&tmp_data);
481  }
482  else
483  // Restore our original data on non-zero ranks
484  tmp_data.swap(_partial_feature_sets);
485  }
486  }
487 
488  // Serialized merging (master does all the work)
489  else
490  {
491  if (_is_master)
492  recv_buffers.reserve(_app.n_processors());
493 
494  serialize(send_buffers[0]);
495 
496  // Free up as much memory as possible here before we do global communication
498 
503  _communicator.gather_packed_range(0,
504  (void *)(nullptr),
505  send_buffers.begin(),
506  send_buffers.end(),
507  std::back_inserter(recv_buffers));
508 
509  if (_is_master)
510  {
511  // The root process now needs to deserialize all of the data
512  deserialize(recv_buffers);
513  recv_buffers.clear();
514 
515  mergeSets();
516 
518  }
519  }
520 
521  // Make sure that feature count is communicated to all ranks
522  _communicator.broadcast(_feature_count);
523 }
const std::size_t _n_vars
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 PerfID _comm_and_merge
const bool _is_master
Convenience variable for testing master rank.
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...
virtual void clearDataStructures()
Helper routine for clearing up data structures during initialize and prior to parallel communication...
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...
virtual void mergeSets()
This routine is called on the master rank only and stitches together the partial feature pieces seen ...
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
const bool _distribute_merge_work
Keeps track of whether we are distributing the merge work.
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 prepareDataForTransfer()
This routine uses the local flooded data to build up the local feature data structures (_feature_sets...

◆ compareValueWithThreshold()

bool FeatureFloodCount::compareValueWithThreshold ( Real  entity_value,
Real  threshold 
) const
protected

This method is used to determine whether the current entity value is part of a feature or not.

Comparisons can either be greater than or less than the threshold which is controlled via input parameter.

Definition at line 1319 of file FeatureFloodCount.C.

Referenced by isNewFeatureOrConnectedRegion().

1320 {
1321  return ((_use_less_than_threshold_comparison && (entity_value >= threshold)) ||
1322  (!_use_less_than_threshold_comparison && (entity_value <= threshold)));
1323 }
const bool _use_less_than_threshold_comparison
Use less-than when comparing values against the threshold value.

◆ consolidateMergedFeatures()

void FeatureFloodCount::consolidateMergedFeatures ( std::vector< std::list< FeatureData >> *  saved_data = nullptr)
private

This method consolidates all of the merged information from _partial_feature_sets into the _feature_sets vectors.

Now that the merges are complete we need to adjust the centroid, and halos. Additionally, To make several of the sorting and tracking algorithms more straightforward, we will move the features into a flat vector. Finally we can count the final number of features and find the max local index seen on any processor Note: This is all occurring on rank 0 only!

IMPORTANT: FeatureFloodCount::_feature_count is set on rank 0 at this point but we can't broadcast it here because this routine is not collective.

Definition at line 1076 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

1077 {
1078  TIME_SECTION(_consolidate_merged_features);
1079 
1087  mooseAssert(_is_master, "cosolidateMergedFeatures() may only be called on the master processor");
1088 
1089  // Offset where the current set of features with the same variable id starts in the flat vector
1090  unsigned int feature_offset = 0;
1091  // Set the member feature count to zero and start counting the actual features
1092  _feature_count = 0;
1093 
1094  for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
1095  {
1096  for (auto & feature : _partial_feature_sets[map_num])
1097  {
1098  if (saved_data)
1099  {
1100  for (auto it = (*saved_data)[map_num].begin(); it != (*saved_data)[map_num].end();
1101  /* no increment */)
1102  {
1103  if (feature.canConsolidate(*it))
1104  {
1105  feature.consolidate(std::move(*it));
1106  it = (*saved_data)[map_num].erase(it); // increment
1107  }
1108  else
1109  ++it;
1110  }
1111  }
1112 
1113  // If after merging we still have an inactive feature, discard it
1114  if (feature._status == Status::CLEAR)
1115  {
1116  // First we need to calculate the centroid now that we are doing merging all partial
1117  // features
1118  if (feature._vol_count != 0)
1119  feature._centroid /= feature._vol_count;
1120 
1121  _feature_sets.emplace_back(std::move(feature));
1122  ++_feature_count;
1123  }
1124  }
1125 
1126  // Record the feature numbers just for the current map
1127  _feature_counts_per_map[map_num] = _feature_count - feature_offset;
1128 
1129  // Now update the running feature count so we can calculate the next map's contribution
1130  feature_offset = _feature_count;
1131 
1132  // Clean up the "moved" objects
1133  _partial_feature_sets[map_num].clear();
1134  }
1135 
1140 }
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const PerfID _consolidate_merged_features
const bool _is_master
Convenience variable for testing master rank.
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
std::vector< unsigned int > _feature_counts_per_map
The number of features seen by this object per map.

◆ deserialize()

void FeatureFloodCount::deserialize ( std::vector< std::string > &  serialized_buffers,
unsigned int  var_num = invalid_id 
)
protected

This routine takes the vector of byte buffers (one for each processor), deserializes them into a series of FeatureSet objects, and appends them to the _feature_sets data structure.

Note: It is assumed that local processor information may already be stored in the _feature_sets data structure so it is not cleared before insertion.

Usually we have the local processor data already in the _partial_feature_sets data structure. However, if we are doing distributed merge work, we also need to preserve all of the original data for use in later stages of the algorithm so it'll have been swapped out with clean buffers. This leaves us a choice, either we just duplicate the Features from the original data structure after we've swapped out the buffer, or we go ahead and unpack data that we would normally already have. So during distributed merging, that's exactly what we'll do. Later however when the master is doing the final consolidating, we'll opt to just skip the local unpacking. To tell the difference, between these two modes, we just need to see if a var_num was passed in.

Definition at line 985 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

986 {
987  // The input string stream used for deserialization
988  std::istringstream iss;
989 
990  auto rank = processor_id();
991 
992  for (auto proc_id = beginIndex(serialized_buffers); proc_id < serialized_buffers.size();
993  ++proc_id)
994  {
1006  if (var_num == invalid_id && proc_id == rank)
1007  continue;
1008 
1009  iss.str(serialized_buffers[proc_id]); // populate the stream with a new buffer
1010  iss.clear(); // reset the string stream state
1011 
1012  // Load the gathered data into the data structure.
1013  if (var_num == invalid_id)
1014  dataLoad(iss, _partial_feature_sets, this);
1015  else
1016  dataLoad(iss, _partial_feature_sets[var_num], this);
1017  }
1018 }
void dataLoad(std::istream &stream, FeatureFloodCount::FeatureData &feature, void *context)
static const unsigned int invalid_id
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...

◆ doesFeatureIntersectBoundary()

bool FeatureFloodCount::doesFeatureIntersectBoundary ( unsigned int  feature_id) const
virtual

Returns a Boolean indicating whether this feature intersects any boundary.

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 780 of file FeatureFloodCount.C.

Referenced by FeatureVolumeVectorPostprocessor::execute().

781 {
782  // TODO: This information is not parallel consistent when using FeatureFloodCounter
783 
784  // Some processors don't contain the largest feature id, in that case we just return invalid_id
785  if (feature_id >= _feature_id_to_local_index.size())
786  return false;
787 
788  auto local_index = _feature_id_to_local_index[feature_id];
789 
790  if (local_index != invalid_size_t)
791  {
792  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
793  return _feature_sets[local_index]._status != Status::INACTIVE
794  ? _feature_sets[local_index]._intersects_boundary
795  : invalid_id;
796  }
797 
798  return false;
799 }
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
static const unsigned int invalid_id
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) ...

◆ execute()

void FeatureFloodCount::execute ( )
overridevirtual

Reimplemented in PolycrystalUserObjectBase, FauxGrainTracker, and GrainTracker.

Definition at line 312 of file FeatureFloodCount.C.

Referenced by GrainTracker::execute().

313 {
314  TIME_SECTION(_execute_timer);
315 
316  // Iterate only over boundaries if restricted
318  {
319  mooseInfo("Using EXPERIMENTAL boundary restricted FeatureFloodCount object!\n");
320 
321  // Set the boundary range pointer for use during flooding
322  _bnd_elem_range = _mesh.getBoundaryElementRange();
323 
324  auto rank = processor_id();
325 
326  for (const auto & belem : *_bnd_elem_range)
327  {
328  const Elem * elem = belem->_elem;
329  BoundaryID boundary_id = belem->_bnd_id;
330 
331  if (elem->processor_id() == rank)
332  {
333  if (hasBoundary(boundary_id))
334  for (auto var_num = beginIndex(_vars); var_num < _vars.size(); ++var_num)
335  flood(elem, var_num);
336  }
337  }
338  }
339  else // Normal volumetric operation
340  {
341  for (const auto & current_elem : _mesh.getMesh().active_local_element_ptr_range())
342  {
343  // Loop over elements or nodes
344  if (_is_elemental)
345  {
346  for (auto var_num = beginIndex(_vars); var_num < _vars.size(); ++var_num)
347  flood(current_elem, var_num);
348  }
349  else
350  {
351  auto n_nodes = current_elem->n_vertices();
352  for (auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
353  {
354  const Node * current_node = current_elem->get_node(i);
355 
356  for (auto var_num = beginIndex(_vars); var_num < _vars.size(); ++var_num)
357  flood(current_node, var_num);
358  }
359  }
360  }
361  }
362 }
const PerfID _execute_timer
Timers.
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
bool _is_boundary_restricted
Indicates that this object should only run on one or more boundaries.
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
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...
ConstBndElemRange * _bnd_elem_range
Boundary element range pointer (used when boundary restricting this object.
MooseMesh & _mesh
A reference to the mesh.

◆ expandEdgeHalos()

void FeatureFloodCount::expandEdgeHalos ( unsigned int  num_layers_to_expand)
protected

This method expands the existing halo set by some width determined by the passed in value.

This method does NOT mask off any local IDs.

Create a copy of the halo set so that as we insert new ids into the set we don't continue to iterate on those new ids.

We have to handle disjoint halo IDs slightly differently. Once you are disjoint, you can't go back so make sure that we keep placing these IDs in the disjoint set.

Definition at line 1428 of file FeatureFloodCount.C.

Referenced by GrainTracker::finalize(), and PolycrystalUserObjectBase::finalize().

1429 {
1430  if (num_layers_to_expand == 0)
1431  return;
1432 
1433  TIME_SECTION(_expand_halos);
1434 
1435  for (auto & list_ref : _partial_feature_sets)
1436  {
1437  for (auto & feature : list_ref)
1438  {
1439  for (auto halo_level = decltype(num_layers_to_expand)(0); halo_level < num_layers_to_expand;
1440  ++halo_level)
1441  {
1446  FeatureData::container_type orig_halo_ids(feature._halo_ids);
1447  for (auto entity : orig_halo_ids)
1448  {
1449  if (_is_elemental)
1450  visitElementalNeighbors(_mesh.elemPtr(entity),
1451  &feature,
1452  /*expand_halos_only =*/true,
1453  /*disjoint_only =*/false);
1454  else
1455  visitNodalNeighbors(_mesh.nodePtr(entity),
1456  &feature,
1457  /*expand_halos_only =*/true);
1458  }
1459 
1464  FeatureData::container_type disjoint_orig_halo_ids(feature._disjoint_halo_ids);
1465  for (auto entity : disjoint_orig_halo_ids)
1466  {
1467  if (_is_elemental)
1468  visitElementalNeighbors(_mesh.elemPtr(entity),
1469 
1470  &feature,
1471  /*expand_halos_only =*/true,
1472  /*disjoint_only =*/true);
1473  else
1474  visitNodalNeighbors(_mesh.nodePtr(entity),
1475 
1476  &feature,
1477  /*expand_halos_only =*/true);
1478  }
1479  }
1480  }
1481  }
1482 }
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::set< dof_id_type > container_type
The primary underlying container type used to hold the data in each FeatureData.
void visitElementalNeighbors(const Elem *elem, FeatureData *feature, bool expand_halos_only, bool disjoint_only)
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
const PerfID _expand_halos
MooseMesh & _mesh
A reference to the mesh.

◆ expandPointHalos()

void FeatureFloodCount::expandPointHalos ( )
protected

This method takes all of the partial features and expands the local, ghosted, and halo sets around those regions to account for the diffuse interface.

Rather than using any kind of recursion here, we simply expand the region by all "point" neighbors from the actual grain cells since all point neighbors will contain contributions to the region.

To expand the feature element region to the actual flooded region (nodal basis) we need to add in all point neighbors of the current local region for each feature. This is because the elemental variable influence spreads from the elemental data out exactly one element from every mesh point.

Definition at line 1366 of file FeatureFloodCount.C.

1367 {
1368  const auto & node_to_elem_map = _mesh.nodeToActiveSemilocalElemMap();
1369  FeatureData::container_type expanded_local_ids;
1370  auto my_processor_id = processor_id();
1371 
1378  for (auto & list_ref : _partial_feature_sets)
1379  {
1380  for (auto & feature : list_ref)
1381  {
1382  expanded_local_ids.clear();
1383 
1384  for (auto entity : feature._local_ids)
1385  {
1386  const Elem * elem = _mesh.elemPtr(entity);
1387  mooseAssert(elem, "elem pointer is NULL");
1388 
1389  // Get the nodes on a current element so that we can add in point neighbors
1390  auto n_nodes = elem->n_vertices();
1391  for (auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
1392  {
1393  const Node * current_node = elem->get_node(i);
1394 
1395  auto elem_vector_it = node_to_elem_map.find(current_node->id());
1396  if (elem_vector_it == node_to_elem_map.end())
1397  mooseError("Error in node to elem map");
1398 
1399  const auto & elem_vector = elem_vector_it->second;
1400 
1401  std::copy(elem_vector.begin(),
1402  elem_vector.end(),
1403  std::insert_iterator<FeatureData::container_type>(expanded_local_ids,
1404  expanded_local_ids.end()));
1405 
1406  // Now see which elements need to go into the ghosted set
1407  for (auto entity : elem_vector)
1408  {
1409  const Elem * neighbor = _mesh.elemPtr(entity);
1410  mooseAssert(neighbor, "neighbor pointer is NULL");
1411 
1412  if (neighbor->processor_id() != my_processor_id)
1413  feature._ghosted_ids.insert(feature._ghosted_ids.end(), elem->id());
1414  }
1415  }
1416  }
1417 
1418  // Replace the existing local ids with the expanded local ids
1419  feature._local_ids.swap(expanded_local_ids);
1420 
1421  // Copy the expanded local_ids into the halo_ids container
1422  feature._halo_ids = feature._local_ids;
1423  }
1424  }
1425 }
std::set< dof_id_type > container_type
The primary underlying container type used to hold the data in each FeatureData.
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
MooseMesh & _mesh
A reference to the mesh.

◆ featureCentroid()

Point FeatureFloodCount::featureCentroid ( unsigned int  feature_id) const
virtual

Returns the centroid of the designated feature (only suppored without periodic boundaries)

Definition at line 802 of file FeatureFloodCount.C.

Referenced by FeatureVolumeVectorPostprocessor::execute().

803 {
804  if (feature_id >= _feature_id_to_local_index.size())
805  return invalid_id;
806 
807  auto local_index = _feature_id_to_local_index[feature_id];
808 
809  Real invalid_coord = std::numeric_limits<Real>::max();
810  Point p(invalid_coord, invalid_coord, invalid_coord);
811  if (local_index != invalid_size_t)
812  {
813  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
814  p = _feature_sets[local_index]._centroid;
815  }
816  return p;
817 }
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
static const unsigned int invalid_id
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) ...

◆ finalize()

void FeatureFloodCount::finalize ( )
overridevirtual

Reimplemented in PolycrystalUserObjectBase, FauxGrainTracker, and GrainTracker.

Definition at line 634 of file FeatureFloodCount.C.

Referenced by PolycrystalUserObjectBase::finalize().

635 {
636  TIME_SECTION(_finalize_timer);
637 
638  // Gather all information on processor zero and merge
640 
641  // Sort and label the features
642  if (_is_master)
643  sortAndLabel();
644 
645  // Send out the local to global mappings
647 
648  // Populate _feature_maps and _var_index_maps
649  updateFieldInfo();
650 }
const PerfID _finalize_timer
virtual void updateFieldInfo()
This method is used to populate any of the data structures used for storing field data (nodal or elem...
void communicateAndMerge()
This routine handles all of the serialization, communication and deserialization of the data structur...
const bool _is_master
Convenience variable for testing master rank.
void sortAndLabel()
Sort and assign ids to features based on their position in the container after sorting.
void scatterAndUpdateRanks()
Calls buildLocalToGlobalIndices to build the individual local to global indicies for each rank and sc...

◆ flood()

bool FeatureFloodCount::flood ( const DofObject *  dof_object,
std::size_t  current_index 
)
protected

This method will check if the current entity is above the supplied threshold and "mark" it.

It will then inspect neighboring entities that are above the connecting threshold and add them to the current feature.

Returns
Boolean indicating whether a new feature was found while exploring the current entity.

If we reach this point (i.e. we haven't continued to the next queue entry), we've found a new mesh entity that's part of a feature. We need to mark the entity as visited at this point (and not before!) to avoid infinite recursion. If you mark the node too early you risk not coloring in a whole feature any time a "connecting threshold" is used since we may have already visited this entity earlier but it was in-between two thresholds.

See if this particular entity cell contributes to the centroid calculation. We only deal with elemental floods and only count it if it's owned by the current processor to avoid skewing the result.

Definition at line 1194 of file FeatureFloodCount.C.

Referenced by execute(), and PolycrystalUserObjectBase::execute().

1196 {
1197  // if (dof_object == nullptr || dof_object == libMesh::remote_elem)
1198  // return false;
1199  mooseAssert(dof_object, "DOF object is nullptr");
1200  mooseAssert(_entity_queue.empty(), "Entity queue is not empty when starting a feature");
1201 
1202  // Kick off the exploration of a new feature
1203  _entity_queue.push_front(dof_object);
1204 
1205  bool return_value = false;
1206  FeatureData * feature = nullptr;
1207  while (!_entity_queue.empty())
1208  {
1209  const DofObject * curr_dof_object = _entity_queue.back();
1210  _entity_queue.pop_back();
1211 
1212  // Retrieve the id of the current entity
1213  auto entity_id = curr_dof_object->id();
1214 
1215  // Has this entity already been marked? - if so move along
1216  if (current_index != invalid_size_t &&
1217  _entities_visited[current_index].find(entity_id) != _entities_visited[current_index].end())
1218  continue;
1219 
1220  // Are we outside of the range we should be working in?
1221  if (_is_elemental)
1222  {
1223  const Elem & elem = static_cast<const Elem &>(*curr_dof_object);
1224 
1225  if (!_dof_map.is_evaluable(elem))
1226  continue;
1227  }
1228 
1229  // See if the current entity either starts a new feature or continues an existing feature
1230  auto new_id = invalid_id; // Writable reference to hold an optional id;
1231  Status status =
1232  Status::INACTIVE; // Status is inactive until we find an entity above the starting threshold
1233 
1234  if (!isNewFeatureOrConnectedRegion(curr_dof_object, current_index, feature, status, new_id))
1235  {
1236  // If we have an active feature, we just found a halo entity
1237  if (feature)
1238  feature->_halo_ids.insert(feature->_halo_ids.end(), entity_id);
1239  continue;
1240  }
1241 
1242  mooseAssert(current_index != invalid_size_t, "current_index is invalid");
1243 
1252  return_value = true;
1253  _entities_visited[current_index].insert(entity_id);
1254 
1255  auto map_num = _single_map_mode ? decltype(current_index)(0) : current_index;
1256 
1257  // New Feature (we need to create it and add it to our data structure)
1258  if (!feature)
1259  {
1260  _partial_feature_sets[map_num].emplace_back(
1261  current_index, _feature_count++, processor_id(), status);
1262 
1263  // Get a handle to the feature we will update (always the last feature in the data structure)
1264  feature = &_partial_feature_sets[map_num].back();
1265 
1266  // If new_id is valid, we'll set it in the feature here.
1267  if (new_id != invalid_id)
1268  feature->_id = new_id;
1269  }
1270 
1271  // Insert the current entity into the local ids data structure
1272  feature->_local_ids.insert(feature->_local_ids.end(), entity_id);
1273 
1279  if (_is_elemental && processor_id() == curr_dof_object->processor_id())
1280  {
1281  const Elem * elem = static_cast<const Elem *>(curr_dof_object);
1282 
1283  // Keep track of how many elements participate in the centroid averaging
1284  feature->_vol_count++;
1285 
1286  // Sum the centroid values for now, we'll average them later
1287  feature->_centroid += elem->centroid();
1288 
1289  // Does the volume intersect the boundary?
1290  if (_all_boundary_entity_ids.find(elem->id()) != _all_boundary_entity_ids.end())
1291  feature->_intersects_boundary = true;
1292  }
1293 
1294  if (_is_elemental)
1295  visitElementalNeighbors(static_cast<const Elem *>(curr_dof_object),
1296  feature,
1297  /*expand_halos_only =*/false,
1298  /*disjoint_only =*/false);
1299  else
1300  visitNodalNeighbors(static_cast<const Node *>(curr_dof_object),
1301  feature,
1302  /*expand_halos_only =*/false);
1303  }
1304 
1305  return return_value;
1306 }
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...
static const std::size_t invalid_size_t
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.
std::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...
void visitElementalNeighbors(const Elem *elem, FeatureData *feature, bool expand_halos_only, bool disjoint_only)
const DofMap & _dof_map
Reference to the dof_map containing the coupled variables.
static const unsigned int invalid_id
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 bool isNewFeatureOrConnectedRegion(const DofObject *dof_object, std::size_t &current_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...
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
std::deque< const DofObject * > _entity_queue
The data structure for maintaining entities to flood during discovery.

◆ getConnectingThreshold()

Real FeatureFloodCount::getConnectingThreshold ( std::size_t  current_index) const
protectedvirtual

Return the "connecting" comparison threshold to use when inspecting an entity during the flood stage.

Definition at line 1313 of file FeatureFloodCount.C.

Referenced by isNewFeatureOrConnectedRegion().

1314 {
1316 }

◆ getCoupledVars()

const std::vector<MooseVariable *>& FeatureFloodCount::getCoupledVars ( ) const
inline

Returns a const vector to the coupled variable pointers.

Definition at line 93 of file FeatureFloodCount.h.

Referenced by AverageGrainVolume::AverageGrainVolume(), and FeatureVolumeVectorPostprocessor::FeatureVolumeVectorPostprocessor().

93 { return _vars; }
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.

◆ getEntityValue()

Real FeatureFloodCount::getEntityValue ( dof_id_type  entity_id,
FieldType  field_type,
std::size_t  var_index = 0 
) const
virtual

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 820 of file FeatureFloodCount.C.

Referenced by GrainTracker::getEntityValue(), and FeatureFloodCountAux::precalculateValue().

823 {
824  auto use_default = false;
825  if (var_index == invalid_size_t)
826  {
827  use_default = true;
828  var_index = 0;
829  }
830 
831  mooseAssert(var_index < _maps_size, "Index out of range");
832 
833  switch (field_type)
834  {
836  {
837  const auto entity_it = _feature_maps[var_index].find(entity_id);
838 
839  if (entity_it != _feature_maps[var_index].end())
840  return entity_it->second; // + _region_offsets[var_index];
841  else
842  return -1;
843  }
844 
846  {
847  mooseAssert(
849  "\"enable_var_coloring\" must be set to true to pull back the VARIABLE_COLORING field");
850 
851  const auto entity_it = _var_index_maps[var_index].find(entity_id);
852 
853  if (entity_it != _var_index_maps[var_index].end())
854  return entity_it->second;
855  else
856  return -1;
857  }
858 
860  {
861  const auto entity_it = _ghosted_entity_ids.find(entity_id);
862 
863  if (entity_it != _ghosted_entity_ids.end())
864  return entity_it->second;
865  else
866  return -1;
867  }
868 
869  case FieldType::HALOS:
870  {
871  if (!use_default)
872  {
873  const auto entity_it = _halo_ids[var_index].find(entity_id);
874  if (entity_it != _halo_ids[var_index].end())
875  return entity_it->second;
876  }
877  else
878  {
879  // Showing halos in reverse order for backwards compatibility
880  for (auto map_num = _maps_size;
881  map_num-- /* don't compare greater than zero for unsigned */;)
882  {
883  const auto entity_it = _halo_ids[map_num].find(entity_id);
884 
885  if (entity_it != _halo_ids[map_num].end())
886  return entity_it->second;
887  }
888  }
889  return -1;
890  }
891 
892  case FieldType::CENTROID:
893  {
894  if (_periodic_node_map.size())
895  mooseDoOnce(mooseWarning(
896  "Centroids are not correct when using periodic boundaries, contact the MOOSE team"));
897 
898  // If this element contains the centroid of one of features, return one
899  const auto * elem_ptr = _mesh.elemPtr(entity_id);
900 
901  for (const auto & feature : _feature_sets)
902  {
903  if (feature._status == Status::INACTIVE)
904  continue;
905 
906  if (elem_ptr->contains_point(feature._centroid))
907  return 1;
908  }
909 
910  return 0;
911  }
912 
913  default:
914  return 0;
915  }
916 }
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 ...
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
std::map< dof_id_type, int > _ghosted_entity_ids
The map for holding reconstructed ghosted element information.
std::vector< std::map< dof_id_type, int > > _halo_ids
The data structure for looking up halos around features.
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
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...
MooseMesh & _mesh
A reference to the mesh.
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.

◆ getFeatures()

const std::vector<FeatureData>& FeatureFloodCount::getFeatures ( ) const
inline

Return a constant reference to the vector of all discovered features.

Definition at line 325 of file FeatureFloodCount.h.

Referenced by GrainTracker::prepopulateState().

325 { return _feature_sets; }
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.

◆ getFeatureVar()

unsigned int FeatureFloodCount::getFeatureVar ( unsigned int  feature_id) const
virtual

Returns the variable representing the passed in feature.

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 761 of file FeatureFloodCount.C.

Referenced by FeatureVolumeVectorPostprocessor::execute(), and GrainTracker::getFeatureVar().

762 {
763  // Some processors don't contain the largest feature id, in that case we just return invalid_id
764  if (feature_id >= _feature_id_to_local_index.size())
765  return invalid_id;
766 
767  auto local_index = _feature_id_to_local_index[feature_id];
768  if (local_index != invalid_size_t)
769  {
770  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
771  return _feature_sets[local_index]._status != Status::INACTIVE
772  ? _feature_sets[local_index]._var_index
773  : invalid_id;
774  }
775 
776  return invalid_id;
777 }
static const std::size_t invalid_size_t
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
static const unsigned int invalid_id
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) ...

◆ getFECoupledVars()

const std::vector<MooseVariableFEBase *>& FeatureFloodCount::getFECoupledVars ( ) const
inline

Returns a const vector to the coupled MooseVariableFEBase pointers.

Definition at line 96 of file FeatureFloodCount.h.

Referenced by AverageGrainVolume::AverageGrainVolume().

96 { return _fe_vars; }
std::vector< MooseVariableFEBase * > _fe_vars
The vector of coupled in variables.

◆ getNumberActiveFeatures()

std::size_t FeatureFloodCount::getNumberActiveFeatures ( ) const

Return the number of active features.

Definition at line 743 of file FeatureFloodCount.C.

Referenced by AverageGrainVolume::getValue().

744 {
745  // Note: This value is parallel consistent, see FeatureFloodCount::communicateAndMerge()
746  return _feature_count;
747 }
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...

◆ getThreshold()

Real FeatureFloodCount::getThreshold ( std::size_t  current_index) const
protectedvirtual

Return the starting comparison threshold to use when inspecting an entity during the flood stage.

Reimplemented in GrainTracker.

Definition at line 1308 of file FeatureFloodCount.C.

Referenced by isNewFeatureOrConnectedRegion().

1309 {
1310  return _step_threshold;
1311 }

◆ getTotalFeatureCount()

std::size_t FeatureFloodCount::getTotalFeatureCount ( ) const
virtual

Returns the total feature count (active and inactive ids, useful for sizing vectors)

Since the FeatureFloodCount object doesn't maintain any information about features between invocations. The maximum id in use is simply the number of features.

Reimplemented in FauxGrainTracker, and GrainTracker.

Definition at line 750 of file FeatureFloodCount.C.

Referenced by FeatureVolumeVectorPostprocessor::execute(), and AverageGrainVolume::initialize().

751 {
757  return _feature_count;
758 }
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...

◆ getValue()

Real FeatureFloodCount::getValue ( )
overridevirtual

Reimplemented in FauxGrainTracker.

Definition at line 737 of file FeatureFloodCount.C.

738 {
739  return static_cast<Real>(_feature_count);
740 }
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...

◆ getVarToFeatureVector()

const std::vector< unsigned int > & FeatureFloodCount::getVarToFeatureVector ( dof_id_type  elem_id) const
virtual

Returns a list of active unique feature ids for a particular element.

The vector is indexed by variable number with each entry containing either an invalid size_t type (no feature active at that location) or a feature id if the variable is non-zero at that location.

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 653 of file FeatureFloodCount.C.

Referenced by AverageGrainVolume::execute(), FeatureVolumeVectorPostprocessor::execute(), GrainTracker::getVarToFeatureVector(), and FeatureFloodCountAux::precalculateValue().

654 {
655  mooseDoOnce(if (!_compute_var_to_feature_map) mooseError(
656  "Please set \"compute_var_to_feature_map = true\" to use this interface method"));
657 
658  const auto pos = _entity_var_to_features.find(elem_id);
659  if (pos != _entity_var_to_features.end())
660  {
661  mooseAssert(pos->second.size() == _n_vars, "Variable to feature vector not sized properly");
662  return pos->second;
663  }
664  else
665  return _empty_var_to_features;
666 }
const std::size_t _n_vars
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
std::vector< unsigned int > _empty_var_to_features
const bool _compute_var_to_feature_map
Indicates whether or not the var to feature map is populated.

◆ initialize()

void FeatureFloodCount::initialize ( )
overridevirtual

Reimplemented in PolycrystalUserObjectBase, FauxGrainTracker, and GrainTracker.

Definition at line 252 of file FeatureFloodCount.C.

Referenced by GrainTracker::initialize(), and PolycrystalUserObjectBase::initialize().

253 {
254  // Clear the feature marking maps and region counters and other data structures
255  for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
256  {
257  _feature_maps[map_num].clear();
258  _partial_feature_sets[map_num].clear();
259 
260  if (_var_index_mode)
261  _var_index_maps[map_num].clear();
262 
263  _halo_ids[map_num].clear();
264  }
265 
266  _feature_sets.clear();
267 
268  // Calculate the thresholds for this iteration
271 
272  _ghosted_entity_ids.clear();
273 
274  // Reset the feature count and max local size
275  _feature_count = 0;
276 
277  _entity_var_to_features.clear();
278 
279  for (auto & map_ref : _entities_visited)
280  map_ref.clear();
281 }
const PostprocessorValue & _element_average_value
Average value of the domain which can optionally be used to find features in a field.
std::vector< std::set< dof_id_type > > _entities_visited
This variable keeps track of which nodes have been visited during execution.
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
std::map< dof_id_type, int > _ghosted_entity_ids
The map for holding reconstructed ghosted element information.
std::vector< std::map< dof_id_type, int > > _halo_ids
The data structure for looking up halos around features.
const Real _connecting_threshold
The threshold above (or below) which neighboring entities are flooded (where regions can be extended ...
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
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...
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map) ...
const Real _threshold
The threshold above (or below) where an entity may begin a new region (feature)
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.

◆ initialSetup()

void FeatureFloodCount::initialSetup ( )
overridevirtual

Size the empty var to features vector to the number of coupled variables. This empty vector (but properly sized) vector is returned for elements that are queried but are not in the structure (which also shouldn't happen). The user is warned in this case but this helps avoid extra bounds checking in user code and avoids segfaults.

Reimplemented in PolycrystalUserObjectBase.

Definition at line 231 of file FeatureFloodCount.C.

Referenced by PolycrystalUserObjectBase::initialSetup().

232 {
233  // We need one map per coupled variable for normal runs to support overlapping features
234  _entities_visited.resize(_vars.size());
235 
236  // Get a pointer to the PeriodicBoundaries buried in libMesh
237  _pbs = _fe_problem.getNonlinearSystemBase().dofMap().get_periodic_boundaries();
238 
239  meshChanged();
240 
249 }
const std::size_t _n_vars
std::vector< std::set< dof_id_type > > _entities_visited
This variable keeps track of which nodes have been visited during execution.
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
static const unsigned int invalid_id
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
std::vector< unsigned int > _empty_var_to_features
virtual void meshChanged() override

◆ isBoundaryEntity()

template<typename T >
bool FeatureFloodCount::isBoundaryEntity ( const T *  entity) const
protected

Returns a Boolean indicating whether the entity is on one of the desired boundaries.

Definition at line 1664 of file FeatureFloodCount.C.

Referenced by visitNeighborsHelper().

1665 {
1666  mooseAssert(_bnd_elem_range, "Boundary Element Range is nullptr");
1667 
1668  if (entity)
1669  for (const auto & belem : *_bnd_elem_range)
1670  // Only works for Elements
1671  if (belem->_elem->id() == entity->id() && hasBoundary(belem->_bnd_id))
1672  return true;
1673 
1674  return false;
1675 }
ConstBndElemRange * _bnd_elem_range
Boundary element range pointer (used when boundary restricting this object.

◆ isElemental()

bool FeatureFloodCount::isElemental ( ) const
inline

Definition at line 112 of file FeatureFloodCount.h.

Referenced by FeatureFloodCountAux::FeatureFloodCountAux().

112 { return _is_elemental; }
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)

◆ isNewFeatureOrConnectedRegion()

bool FeatureFloodCount::isNewFeatureOrConnectedRegion ( const DofObject *  dof_object,
std::size_t &  current_index,
FeatureData *&  feature,
Status status,
unsigned int &  new_id 
)
protectedvirtual

Method called during the recursive flood routine that should return whether or not the current entity is part of the current feature (if one is being explored), or if it's the start of a new feature.

If the value is only above the connecting threshold, it's still part of a feature but possibly part of one that we'll discard if there is never any starting threshold encountered.

Reimplemented in PolycrystalUserObjectBase.

Definition at line 1326 of file FeatureFloodCount.C.

Referenced by flood().

1331 {
1332  // Get the value of the current variable for the current entity
1333  Real entity_value;
1334  if (_is_elemental)
1335  {
1336  const Elem * elem = static_cast<const Elem *>(dof_object);
1337  std::vector<Point> centroid(1, elem->centroid());
1338  _subproblem.reinitElemPhys(elem, centroid, 0, /* suppress_displaced_init = */ true);
1339  entity_value = _vars[current_index]->sln()[0];
1340  }
1341  else
1342  entity_value = _vars[current_index]->getNodalValue(*static_cast<const Node *>(dof_object));
1343 
1344  // If the value compares against our starting threshold, this is definitely part of a feature
1345  // we'll keep
1346  if (compareValueWithThreshold(entity_value, getThreshold(current_index)))
1347  {
1348  Status * status_ptr = &status;
1349 
1350  if (feature)
1351  status_ptr = &feature->_status;
1352 
1353  // Update an existing feature's status or clear the flag on the passed in status
1354  *status_ptr &= ~Status::INACTIVE;
1355  return true;
1356  }
1357 
1362  return compareValueWithThreshold(entity_value, getConnectingThreshold(current_index));
1363 }
Status
This enumeration is used to indicate status of the grains in the _unique_grains data structure...
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
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 _is_elemental
Determines if the flood counter is elements or not (nodes)
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...
virtual Real getThreshold(std::size_t current_index) const
Return the starting comparison threshold to use when inspecting an entity during the flood stage...

◆ mergeSets()

void FeatureFloodCount::mergeSets ( )
protectedvirtual

This routine is called on the master rank only and stitches together the partial feature pieces seen on any processor.

Insert the new entity at the end of the list so that it may be checked against all other partial features again.

Now remove both halves the merged features: it2 contains the "moved" feature cell just inserted at the back of the list, it1 contains the mostly empty other half. We have to be careful about the order in which these two elements are deleted. We delete it2 first since we don't care where its iterator points after the deletion. We are going to break out of this loop anyway. If we delete it1 first, it may end up pointing at the same location as it2 which after the second deletion would cause both of the iterators to be invalidated.

Reimplemented in PolycrystalUserObjectBase.

Definition at line 1021 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

1022 {
1023  TIME_SECTION(_merge_timer);
1024 
1025  // When working with _distribute_merge_work all of the maps will be empty except for one
1026  for (auto map_num = decltype(_maps_size)(0); map_num < _maps_size; ++map_num)
1027  {
1028  for (auto it1 = _partial_feature_sets[map_num].begin();
1029  it1 != _partial_feature_sets[map_num].end();
1030  /* No increment on it1 */)
1031  {
1032  bool merge_occured = false;
1033  for (auto it2 = _partial_feature_sets[map_num].begin();
1034  it2 != _partial_feature_sets[map_num].end();
1035  ++it2)
1036  {
1037  if (it1 != it2 && areFeaturesMergeable(*it1, *it2))
1038  {
1039  it2->merge(std::move(*it1));
1040 
1045  _partial_feature_sets[map_num].emplace_back(std::move(*it2));
1046 
1056  _partial_feature_sets[map_num].erase(it2);
1057  it1 = _partial_feature_sets[map_num].erase(it1); // it1 is incremented here!
1058 
1059  // A merge occurred, this is used to determine whether or not we increment the outer
1060  // iterator
1061  merge_occured = true;
1062 
1063  // We need to start the list comparison over for the new it1 so break here
1064  break;
1065  }
1066  } // it2 loop
1067 
1068  if (!merge_occured) // No merges so we need to manually increment the outer iterator
1069  ++it1;
1070 
1071  } // it1 loop
1072  } // map loop
1073 }
const PerfID _merge_timer
virtual bool areFeaturesMergeable(const FeatureData &f1, const FeatureData &f2) const
Method for determining whether two features are mergeable.
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...

◆ meshChanged()

void FeatureFloodCount::meshChanged ( )
overridevirtual

We need to build a set containing all of the boundary entities to compare against. This will be elements for elemental flooding. Volumes for nodal flooding is not supported

Reimplemented in GrainTracker.

Definition at line 289 of file FeatureFloodCount.C.

Referenced by initialSetup(), and GrainTracker::meshChanged().

290 {
291  _point_locator = _mesh.getMesh().sub_point_locator();
292 
293  _mesh.buildPeriodicNodeMap(_periodic_node_map, _var_number, _pbs);
294 
295  // Build a new node to element map
296  _nodes_to_elem_map.clear();
297  MeshTools::build_nodes_to_elem_map(_mesh.getMesh(), _nodes_to_elem_map);
298 
304  _all_boundary_entity_ids.clear();
305  if (_is_elemental)
306  for (auto elem_it = _mesh.bndElemsBegin(), elem_end = _mesh.bndElemsEnd(); elem_it != elem_end;
307  ++elem_it)
308  _all_boundary_entity_ids.insert((*elem_it)->_elem->id());
309 }
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 ...
std::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...
unsigned long _var_number
This variable is used to build the periodic node map.
std::vector< std::vector< const Elem * > > _nodes_to_elem_map
The data structure used to find neighboring elements give a node ID.
std::unique_ptr< PointLocatorBase > _point_locator
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
MooseMesh & _mesh
A reference to the mesh.

◆ numCoupledVars()

std::size_t FeatureFloodCount::numCoupledVars ( ) const
inline

Returns the number of coupled varaibles.

Definition at line 84 of file FeatureFloodCount.h.

84 { return _n_vars; }
const std::size_t _n_vars

◆ prepareDataForTransfer()

void FeatureFloodCount::prepareDataForTransfer ( )
protected

This routine uses the local flooded data to build up the local feature data structures (_feature_sets).

This routine does not perform any communication so the _feature_sets data structure will only contain information from the local processor after calling this routine. Any existing data in the _feature_sets structure is destroyed by calling this routine.

_feature_sets layout: The outer vector is sized to one when _single_map_mode == true, otherwise it is sized for the number of coupled variables. The inner list represents the flooded regions (local only after this call but fully populated after parallel communication and stitching).

If using a vector container, we need to sort all of the data structures for later operations such as checking for intersection and merging. The following "sort" function does nothing when invoked on a std::set.

Save off the min entity id present in the feature to uniquely identify the feature regardless of n_procs

Definition at line 919 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

920 {
921  TIME_SECTION(_prepare_for_transfer);
922 
923  MeshBase & mesh = _mesh.getMesh();
924 
925  FeatureData::container_type local_ids_no_ghost, set_difference;
926 
927  for (auto & list_ref : _partial_feature_sets)
928  {
929  for (auto & feature : list_ref)
930  {
931  // Periodic node ids
933 
939  FeatureFloodCount::sort(feature._ghosted_ids);
940  FeatureFloodCount::sort(feature._local_ids);
941  FeatureFloodCount::sort(feature._halo_ids);
942  FeatureFloodCount::sort(feature._disjoint_halo_ids);
943  FeatureFloodCount::sort(feature._periodic_nodes);
944 
945  // Now extend the bounding box by the halo region
946  if (_is_elemental)
947  feature.updateBBoxExtremes(mesh);
948  else
949  {
950  for (auto & halo_id : feature._halo_ids)
951  updateBBoxExtremesHelper(feature._bboxes[0], mesh.node(halo_id));
952  }
953 
954  mooseAssert(!feature._local_ids.empty(), "local entity ids cannot be empty");
955 
960  feature._min_entity_id = *feature._local_ids.begin();
961  }
962  }
963 }
void appendPeriodicNeighborNodes(FeatureData &feature) const
This routine adds the periodic node information to our data structure prior to packing the data this ...
static void sort(std::set< T > &)
std::set< dof_id_type > container_type
The primary underlying container type used to hold the data in each FeatureData.
void updateBBoxExtremesHelper(MeshTools::BoundingBox &bbox, const Point &node)
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
const PerfID _prepare_for_transfer
MooseMesh & _mesh
A reference to the mesh.

◆ reserve() [1/2]

template<class T >
static void FeatureFloodCount::reserve ( std::set< T > &  ,
std::size_t   
)
inlinestaticprivate

Definition at line 724 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::FeatureData::consolidate(), FeatureFloodCount::FeatureData::merge(), and FeatureFloodCount::FeatureData::updateBBoxExtremes().

725  {
726  // Sets are trees, no reservations necessary
727  }

◆ reserve() [2/2]

template<class T >
static void FeatureFloodCount::reserve ( std::vector< T > &  container,
std::size_t  size 
)
inlinestaticprivate

Definition at line 730 of file FeatureFloodCount.h.

731  {
732  container.reserve(size);
733  }

◆ scatterAndUpdateRanks()

void FeatureFloodCount::scatterAndUpdateRanks ( )
protected

Calls buildLocalToGlobalIndices to build the individual local to global indicies for each rank and scatters that information to all ranks.

Finally, the non-master ranks update their own data structures to reflect the global mappings.

On non-root processors we can't maintain the full _feature_sets data structure since we don't have all of the global information. We'll move the items from the partial feature sets into a flat structure maintaining order and update the internal IDs with the proper global ID.

Important: Make sure we clear the local status if we received a valid global index for this feature. It's possible that we have a status of INVALID on the local processor because there was never any starting threshold found. However, the root processor wouldn't have sent an index if it didn't find a starting threshold connected to our local piece.

Definition at line 669 of file FeatureFloodCount.C.

Referenced by GrainTracker::assignGrains(), finalize(), and GrainTracker::trackGrains().

670 {
671  // local to global map (one per processor)
672  std::vector<int> counts;
673  std::vector<std::size_t> local_to_global_all;
674  if (_is_master)
675  buildLocalToGlobalIndices(local_to_global_all, counts);
676 
677  // Scatter local_to_global indices to all processors and store in class member variable
678  _communicator.scatter(local_to_global_all, counts, _local_to_global_feature_map);
679 
680  std::size_t largest_global_index = std::numeric_limits<std::size_t>::lowest();
681  if (!_is_master)
682  {
684 
691  for (auto & list_ref : _partial_feature_sets)
692  {
693  for (auto & feature : list_ref)
694  {
695  mooseAssert(feature._orig_ids.size() == 1, "feature._orig_ids length doesn't make sense");
696 
697  auto global_index = FeatureFloodCount::invalid_size_t;
698  auto local_index = feature._orig_ids.begin()->second;
699 
700  if (local_index < _local_to_global_feature_map.size())
701  global_index = _local_to_global_feature_map[local_index];
702 
703  if (global_index != FeatureFloodCount::invalid_size_t)
704  {
705  if (global_index > largest_global_index)
706  largest_global_index = global_index;
707 
708  // Set the correct global index
709  feature._id = global_index;
710 
718  feature._status &= ~Status::INACTIVE;
719 
720  // Move the feature into the correct place
721  _feature_sets[local_index] = std::move(feature);
722  }
723  }
724  }
725  }
726  else
727  {
728  for (auto global_index : local_to_global_all)
729  if (global_index != FeatureFloodCount::invalid_size_t && global_index > largest_global_index)
730  largest_global_index = global_index;
731  }
732 
733  buildFeatureIdToLocalIndices(largest_global_index);
734 }
static const std::size_t invalid_size_t
Status
This enumeration is used to indicate status of the grains in the _unique_grains data structure...
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const bool _is_master
Convenience variable for testing master rank.
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 ...
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
void buildFeatureIdToLocalIndices(unsigned int max_id)
This method builds a lookup map for retrieving the right local feature (by index) given a global inde...
std::vector< std::size_t > _local_to_global_feature_map
The vector recording the local to global feature indices.

◆ serialize()

void FeatureFloodCount::serialize ( std::string &  serialized_buffer,
unsigned int  var_num = invalid_id 
)
protected

This routines packs the _partial_feature_sets data into a structure suitable for parallel communication operations.

Definition at line 966 of file FeatureFloodCount.C.

Referenced by communicateAndMerge().

967 {
968  // stream for serializing the _partial_feature_sets data structure to a byte stream
969  std::ostringstream oss;
970 
971  mooseAssert(var_num == invalid_id || var_num < _partial_feature_sets.size(),
972  "var_num out of range");
973 
974  // Serialize everything
975  if (var_num == invalid_id)
976  dataStore(oss, _partial_feature_sets, this);
977  else
978  dataStore(oss, _partial_feature_sets[var_num], this);
979 
980  // Populate the passed in string pointer with the string stream's buffer contents
981  serialized_buffer.assign(oss.str());
982 }
void dataStore(std::ostream &stream, FeatureFloodCount::FeatureData &feature, void *context)
static const unsigned int invalid_id
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...

◆ setsIntersect()

template<class InputIterator >
static bool FeatureFloodCount::setsIntersect ( InputIterator  first1,
InputIterator  last1,
InputIterator  first2,
InputIterator  last2 
)
inlinestaticprotected

This method detects whether two sets intersect without building a result set.

It exits as soon as any intersection is detected.

Definition at line 523 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::FeatureData::ghostedIntersect(), FeatureFloodCount::FeatureData::halosIntersect(), and FeatureFloodCount::FeatureData::periodicBoundariesIntersect().

527  {
528  while (first1 != last1 && first2 != last2)
529  {
530  if (*first1 == *first2)
531  return true;
532 
533  if (*first1 < *first2)
534  ++first1;
535  else if (*first1 > *first2)
536  ++first2;
537  }
538  return false;
539  }

◆ sort() [1/2]

template<class T >
static void FeatureFloodCount::sort ( std::set< T > &  )
inlinestaticprivate

Definition at line 712 of file FeatureFloodCount.h.

Referenced by prepareDataForTransfer().

713  {
714  // Sets are already sorted, do nothing
715  }

◆ sort() [2/2]

template<class T >
static void FeatureFloodCount::sort ( std::vector< T > &  container)
inlinestaticprivate

Definition at line 718 of file FeatureFloodCount.h.

719  {
720  std::sort(container.begin(), container.end());
721  }

◆ sortAndLabel()

void FeatureFloodCount::sortAndLabel ( )
protected

Sort and assign ids to features based on their position in the container after sorting.

Perform a sort to give a parallel unique sorting to the identified features. We use the "min_entity_id" inside each feature to assign it's position in the sorted vector.

Sanity check. Now that we've sorted the flattened vector of features we need to make sure that the counts vector still lines up appropriately with each feature's _var_index.

Definition at line 526 of file FeatureFloodCount.C.

Referenced by GrainTracker::assignGrains(), and finalize().

527 {
528  mooseAssert(_is_master, "sortAndLabel can only be called on the master");
529 
535  std::sort(_feature_sets.begin(), _feature_sets.end());
536 
537 #ifndef NDEBUG
538 
543  unsigned int feature_offset = 0;
544  for (auto map_num = beginIndex(_feature_counts_per_map); map_num < _maps_size; ++map_num)
545  {
546  // Skip empty map checks
547  if (_feature_counts_per_map[map_num] == 0)
548  continue;
549 
550  // Check the begin and end of the current range
551  auto range_front = feature_offset;
552  auto range_back = feature_offset + _feature_counts_per_map[map_num] - 1;
553 
554  mooseAssert(range_front <= range_back && range_back < _feature_count,
555  "Indexing error in feature sets");
556 
557  if (!_single_map_mode && (_feature_sets[range_front]._var_index != map_num ||
558  _feature_sets[range_back]._var_index != map_num))
559  mooseError("Error in _feature_sets sorting, map index: ", map_num);
560 
561  feature_offset += _feature_counts_per_map[map_num];
562  }
563 #endif
564 
565  // Label the features with an ID based on the sorting (processor number independent value)
566  for (auto i = beginIndex(_feature_sets); i < _feature_sets.size(); ++i)
567  if (_feature_sets[i]._id == invalid_id)
568  _feature_sets[i]._id = i;
569 }
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const bool _is_master
Convenience variable for testing master rank.
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps...
static const unsigned int invalid_id
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) ...
std::vector< unsigned int > _feature_counts_per_map
The number of features seen by this object per map.

◆ updateFieldInfo()

void FeatureFloodCount::updateFieldInfo ( )
protectedvirtual

This method is used to populate any of the data structures used for storing field data (nodal or elemental).

It is called at the end of finalize and can make use of any of the data structures created during the execution of this postprocessor.

Reimplemented in GrainTracker.

Definition at line 1149 of file FeatureFloodCount.C.

Referenced by finalize().

1150 {
1151  for (auto i = beginIndex(_feature_sets); i < _feature_sets.size(); ++i)
1152  {
1153  auto & feature = _feature_sets[i];
1154 
1155  // If the developer has requested _condense_map_info we'll make sure we only update the zeroth
1156  // map
1157  auto map_index = (_single_map_mode || _condense_map_info) ? decltype(feature._var_index)(0)
1158  : feature._var_index;
1159 
1160  // Loop over the entity ids of this feature and update our local map
1161  for (auto entity : feature._local_ids)
1162  {
1163  _feature_maps[map_index][entity] = static_cast<int>(feature._id);
1164 
1165  if (_var_index_mode)
1166  _var_index_maps[map_index][entity] = feature._var_index;
1167 
1168  // Fill in the data structure that keeps track of all features per elem
1170  {
1171  auto insert_pair = moose_try_emplace(
1172  _entity_var_to_features, entity, std::vector<unsigned int>(_n_vars, invalid_id));
1173  auto & vec_ref = insert_pair.first->second;
1174  vec_ref[feature._var_index] = feature._id;
1175  }
1176  }
1177 
1178  if (_compute_halo_maps)
1179  // Loop over the halo ids to update cells with halo information
1180  for (auto entity : feature._halo_ids)
1181  _halo_ids[map_index][entity] = static_cast<int>(feature._id);
1182 
1183  // Loop over the ghosted ids to update cells with ghost information
1184  for (auto entity : feature._ghosted_ids)
1185  _ghosted_entity_ids[entity] = 1;
1186 
1187  // TODO: Fixme
1188  if (!_global_numbering)
1189  mooseError("Local numbering currently disabled");
1190  }
1191 }
const std::size_t _n_vars
const bool _condense_map_info
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
std::map< dof_id_type, int > _ghosted_entity_ids
The map for holding reconstructed ghosted element information.
std::vector< std::map< dof_id_type, int > > _halo_ids
The data structure for looking up halos around features.
const bool _global_numbering
This variable is used to indicate whether or not we identify features with unique numbers on multiple...
static const unsigned int invalid_id
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...
const bool _single_map_mode
This variable is used to indicate whether or not multiple maps are used during flooding.
const bool _compute_halo_maps
Indicates whether or not to communicate halo map information with all ranks.
const bool _compute_var_to_feature_map
Indicates whether or not the var to feature map is populated.
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.

◆ updateRegionOffsets()

void FeatureFloodCount::updateRegionOffsets ( )
protected

This routine updates the _region_offsets variable which is useful for quickly determining the proper global number for a feature when using multimap mode.

◆ visitElementalNeighbors()

void FeatureFloodCount::visitElementalNeighbors ( const Elem *  elem,
FeatureData feature,
bool  expand_halos_only,
bool  disjoint_only 
)
protected

Retrieve only the active neighbors for each side of this element, append them to the list of active neighbors

If the current element (passed into this method) doesn't have a connected neighbor but does have a topological neighbor, this might be a new disjoint region that we'll need to represent with a separate bounding box. To find out for sure, we'll need see if the new neighbors are present in any of the halo or disjoint halo sets. If they are not present, this is a new region.

This neighbor is NULL which means we need to expand the bounding box here in case this grain is up against multiple domain edges so we don't end up with a degenerate bounding box.

Definition at line 1485 of file FeatureFloodCount.C.

Referenced by expandEdgeHalos(), and flood().

1489 {
1490  mooseAssert(elem, "Elem is NULL");
1491 
1492  std::vector<const Elem *> all_active_neighbors;
1493  MeshBase & mesh = _mesh.getMesh();
1494 
1495  // Loop over all neighbors (at the the same level as the current element)
1496  for (auto i = decltype(elem->n_neighbors())(0); i < elem->n_neighbors(); ++i)
1497  {
1498  const Elem * neighbor_ancestor = nullptr;
1499  bool topological_neighbor = false;
1500 
1505  neighbor_ancestor = elem->neighbor(i);
1506  if (neighbor_ancestor)
1507  {
1508  if (neighbor_ancestor == libMesh::remote_elem)
1509  continue;
1510 
1511  neighbor_ancestor->active_family_tree_by_neighbor(all_active_neighbors, elem, false);
1512  }
1513  else
1514  {
1515  neighbor_ancestor = elem->topological_neighbor(i, mesh, *_point_locator, _pbs);
1516 
1524  if (neighbor_ancestor)
1525  {
1526  neighbor_ancestor->active_family_tree_by_topological_neighbor(
1527  all_active_neighbors, elem, mesh, *_point_locator, _pbs, false);
1528 
1529  topological_neighbor = true;
1530  }
1531  else
1532  {
1538  updateBBoxExtremesHelper(feature->_bboxes[0], *elem);
1539  }
1540  }
1541 
1542  visitNeighborsHelper(elem,
1543  all_active_neighbors,
1544  feature,
1545  expand_halos_only,
1546  topological_neighbor,
1547  disjoint_only);
1548 
1549  all_active_neighbors.clear();
1550  }
1551 }
void updateBBoxExtremesHelper(MeshTools::BoundingBox &bbox, const Point &node)
std::unique_ptr< PointLocatorBase > _point_locator
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
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.
MooseMesh & _mesh
A reference to the mesh.

◆ visitNeighborsHelper()

template<typename T >
void FeatureFloodCount::visitNeighborsHelper ( const T *  curr_entity,
std::vector< const T *>  neighbor_entities,
FeatureData feature,
bool  expand_halos_only,
bool  topological_neighbor,
bool  disjoint_only 
)
protected

The actual logic for visiting neighbors is abstracted out here.

This method is templated to handle the Nodal and Elemental cases together.

Only recurse where we own this entity and it's a topologically connected entity. We shouldn't even attempt to flood to the periodic boundary because we won't have solution information and if we are using DistributedMesh we probably won't have geometric information either.

When we only recurse on entities we own, we can never get more than one away from a local entity which should be in the ghosted zone.

Premark neighboring entities with a halo mark. These entities may or may not end up being part of the feature. We will not update the _entities_visited data structure here.

Definition at line 1568 of file FeatureFloodCount.C.

Referenced by visitElementalNeighbors(), and visitNodalNeighbors().

1574 {
1575  // Loop over all active element neighbors
1576  for (const auto neighbor : neighbor_entities)
1577  {
1578  if (neighbor && (!_is_boundary_restricted || isBoundaryEntity(neighbor)))
1579  {
1580  if (expand_halos_only)
1581  {
1582  auto entity_id = neighbor->id();
1583 
1584  if (topological_neighbor || disjoint_only)
1585  feature->_disjoint_halo_ids.insert(feature->_disjoint_halo_ids.end(), entity_id);
1586  else if (feature->_local_ids.find(entity_id) == feature->_local_ids.end())
1587  feature->_halo_ids.insert(feature->_halo_ids.end(), entity_id);
1588  }
1589  else
1590  {
1591  auto my_processor_id = processor_id();
1592 
1593  if (!topological_neighbor && neighbor->processor_id() != my_processor_id)
1594  feature->_ghosted_ids.insert(feature->_ghosted_ids.end(), curr_entity->id());
1595 
1605  if (curr_entity->processor_id() == my_processor_id ||
1606  neighbor->processor_id() == my_processor_id)
1607  {
1614  if (topological_neighbor || disjoint_only)
1615  feature->_disjoint_halo_ids.insert(feature->_disjoint_halo_ids.end(), neighbor->id());
1616  else
1617  _entity_queue.push_front(neighbor);
1618  }
1619  }
1620  }
1621  }
1622 }
bool isBoundaryEntity(const T *entity) const
Returns a Boolean indicating whether the entity is on one of the desired boundaries.
bool _is_boundary_restricted
Indicates that this object should only run on one or more boundaries.
std::deque< const DofObject * > _entity_queue
The data structure for maintaining entities to flood during discovery.

◆ visitNodalNeighbors()

void FeatureFloodCount::visitNodalNeighbors ( const Node *  node,
FeatureData feature,
bool  expand_halos_only 
)
protected

These two routines are utility routines used by the flood routine and by derived classes for visiting neighbors.

Since the logic is different for the elemental versus nodal case it's easier to split them up.

Definition at line 1554 of file FeatureFloodCount.C.

Referenced by expandEdgeHalos(), and flood().

1557 {
1558  mooseAssert(node, "Node is NULL");
1559 
1560  std::vector<const Node *> all_active_neighbors;
1561  MeshTools::find_nodal_neighbors(_mesh.getMesh(), *node, _nodes_to_elem_map, all_active_neighbors);
1562 
1563  visitNeighborsHelper(node, all_active_neighbors, feature, expand_halos_only, false, false);
1564 }
std::vector< std::vector< const Elem * > > _nodes_to_elem_map
The data structure used to find neighboring elements give a node ID.
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.
MooseMesh & _mesh
A reference to the mesh.

Member Data Documentation

◆ _all_boundary_entity_ids

std::set<dof_id_type> FeatureFloodCount::_all_boundary_entity_ids
protected

The set of entities on the boundary of the domain used for determining if features intersect any boundary.

Definition at line 692 of file FeatureFloodCount.h.

Referenced by flood(), and meshChanged().

◆ _bnd_elem_range

ConstBndElemRange* FeatureFloodCount::_bnd_elem_range
protected

Boundary element range pointer (used when boundary restricting this object.

Definition at line 705 of file FeatureFloodCount.h.

Referenced by execute(), and isBoundaryEntity().

◆ _comm_and_merge

const PerfID FeatureFloodCount::_comm_and_merge
private

Definition at line 751 of file FeatureFloodCount.h.

Referenced by communicateAndMerge().

◆ _compute_halo_maps

const bool FeatureFloodCount::_compute_halo_maps
protected

Indicates whether or not to communicate halo map information with all ranks.

Definition at line 585 of file FeatureFloodCount.h.

Referenced by GrainTracker::communicateHaloMap(), GrainTracker::meshChanged(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _compute_var_to_feature_map

const bool FeatureFloodCount::_compute_var_to_feature_map
protected

Indicates whether or not the var to feature map is populated.

Definition at line 588 of file FeatureFloodCount.h.

Referenced by getVarToFeatureVector(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _condense_map_info

const bool FeatureFloodCount::_condense_map_info
protected

Definition at line 574 of file FeatureFloodCount.h.

Referenced by GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _connecting_threshold

const Real FeatureFloodCount::_connecting_threshold
protected

The threshold above (or below) which neighboring entities are flooded (where regions can be extended but not started)

Definition at line 558 of file FeatureFloodCount.h.

Referenced by initialize().

◆ _consolidate_merged_features

const PerfID FeatureFloodCount::_consolidate_merged_features
private

Definition at line 755 of file FeatureFloodCount.h.

Referenced by consolidateMergedFeatures().

◆ _distribute_merge_work

const bool FeatureFloodCount::_distribute_merge_work
private

Keeps track of whether we are distributing the merge work.

Definition at line 745 of file FeatureFloodCount.h.

Referenced by communicateAndMerge().

◆ _dof_map

const DofMap& FeatureFloodCount::_dof_map
protected

Reference to the dof_map containing the coupled variables.

Definition at line 550 of file FeatureFloodCount.h.

Referenced by flood().

◆ _element_average_value

const PostprocessorValue& FeatureFloodCount::_element_average_value
protected

Average value of the domain which can optionally be used to find features in a field.

Definition at line 673 of file FeatureFloodCount.h.

Referenced by initialize().

◆ _empty_var_to_features

std::vector<unsigned int> FeatureFloodCount::_empty_var_to_features
protected

Definition at line 696 of file FeatureFloodCount.h.

Referenced by getVarToFeatureVector(), and initialSetup().

◆ _entities_visited

std::vector<std::set<dof_id_type> > FeatureFloodCount::_entities_visited
protected

This variable keeps track of which nodes have been visited during execution.

We don't use the _feature_map for this since we don't want to explicitly store data for all the unmarked nodes in a serialized datastructures. This keeps our overhead down since this variable never needs to be communicated.

Definition at line 612 of file FeatureFloodCount.h.

Referenced by PolycrystalUserObjectBase::execute(), flood(), initialize(), initialSetup(), and PolycrystalUserObjectBase::isNewFeatureOrConnectedRegion().

◆ _entity_queue

std::deque<const DofObject *> FeatureFloodCount::_entity_queue
private

The data structure for maintaining entities to flood during discovery.

Definition at line 742 of file FeatureFloodCount.h.

Referenced by flood(), and visitNeighborsHelper().

◆ _entity_var_to_features

std::map<dof_id_type, std::vector<unsigned int> > FeatureFloodCount::_entity_var_to_features
protected

◆ _execute_timer

const PerfID FeatureFloodCount::_execute_timer
private

Timers.

Definition at line 748 of file FeatureFloodCount.h.

Referenced by execute().

◆ _expand_halos

const PerfID FeatureFloodCount::_expand_halos
private

Definition at line 752 of file FeatureFloodCount.h.

Referenced by expandEdgeHalos().

◆ _fe_vars

std::vector<MooseVariableFEBase *> FeatureFloodCount::_fe_vars
protected

The vector of coupled in variables.

Definition at line 545 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount(), and getFECoupledVars().

◆ _feature_count

unsigned int FeatureFloodCount::_feature_count
protected

◆ _feature_counts_per_map

std::vector<unsigned int> FeatureFloodCount::_feature_counts_per_map
protected

The number of features seen by this object per map.

Definition at line 626 of file FeatureFloodCount.h.

Referenced by consolidateMergedFeatures(), sortAndLabel(), and GrainTracker::trackGrains().

◆ _feature_id_to_local_index

std::vector<std::size_t> FeatureFloodCount::_feature_id_to_local_index
protected

◆ _feature_maps

std::vector<std::map<dof_id_type, int> > FeatureFloodCount::_feature_maps
protected

The feature maps contain the raw flooded node information and eventually the unique grain numbers.

We have a vector of them so we can create one per variable if that level of detail is desired.

Definition at line 659 of file FeatureFloodCount.h.

Referenced by getEntityValue(), initialize(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _feature_sets

std::vector<FeatureData>& FeatureFloodCount::_feature_sets
protected

◆ _finalize_timer

const PerfID FeatureFloodCount::_finalize_timer
private

Definition at line 750 of file FeatureFloodCount.h.

Referenced by finalize().

◆ _ghosted_entity_ids

std::map<dof_id_type, int> FeatureFloodCount::_ghosted_entity_ids
protected

The map for holding reconstructed ghosted element information.

Definition at line 676 of file FeatureFloodCount.h.

Referenced by getEntityValue(), initialize(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _global_numbering

const bool FeatureFloodCount::_global_numbering
protected

This variable is used to indicate whether or not we identify features with unique numbers on multiple maps.

Definition at line 578 of file FeatureFloodCount.h.

Referenced by updateFieldInfo().

◆ _halo_ids

std::vector<std::map<dof_id_type, int> > FeatureFloodCount::_halo_ids
protected

The data structure for looking up halos around features.

The outer vector is for splitting out the information per variable. The inner map holds the actual halo information

Definition at line 682 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::FeatureData::clear(), GrainTracker::communicateHaloMap(), getEntityValue(), FeatureFloodCount::FeatureData::halosIntersect(), initialize(), FeatureFloodCount::FeatureData::merge(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _is_boundary_restricted

bool FeatureFloodCount::_is_boundary_restricted
protected

Indicates that this object should only run on one or more boundaries.

Definition at line 702 of file FeatureFloodCount.h.

Referenced by execute(), FeatureFloodCount(), and visitNeighborsHelper().

◆ _is_elemental

const bool FeatureFloodCount::_is_elemental
protected

◆ _is_master

const bool FeatureFloodCount::_is_master
protected

◆ _local_to_global_feature_map

std::vector<std::size_t> FeatureFloodCount::_local_to_global_feature_map
protected

The vector recording the local to global feature indices.

Definition at line 662 of file FeatureFloodCount.h.

Referenced by scatterAndUpdateRanks().

◆ _maps_size

const std::size_t FeatureFloodCount::_maps_size
protected

Convenience variable holding the size of all the datastructures size by the number of maps.

Definition at line 601 of file FeatureFloodCount.h.

Referenced by consolidateMergedFeatures(), FeatureFloodCount(), getEntityValue(), initialize(), mergeSets(), sortAndLabel(), GrainTracker::trackGrains(), and GrainTracker::updateFieldInfo().

◆ _merge_timer

const PerfID FeatureFloodCount::_merge_timer
private

Definition at line 749 of file FeatureFloodCount.h.

Referenced by mergeSets().

◆ _mesh

MooseMesh& FeatureFloodCount::_mesh
protected

◆ _n_procs

const processor_id_type FeatureFloodCount::_n_procs
protected

Convenience variable holding the number of processors in this simulation.

Definition at line 604 of file FeatureFloodCount.h.

Referenced by buildLocalToGlobalIndices(), and GrainTracker::communicateHaloMap().

◆ _n_vars

const std::size_t FeatureFloodCount::_n_vars
protected

◆ _nodes_to_elem_map

std::vector<std::vector<const Elem *> > FeatureFloodCount::_nodes_to_elem_map
protected

The data structure used to find neighboring elements give a node ID.

Definition at line 623 of file FeatureFloodCount.h.

Referenced by meshChanged(), and visitNodalNeighbors().

◆ _partial_feature_sets

std::vector<std::list<FeatureData> > FeatureFloodCount::_partial_feature_sets
protected

The data structure used to hold partial and communicated feature data, during the discovery and merging phases.

The outer vector is indexed by map number (often variable number). The inner list is an unordered list of partially discovered features.

Definition at line 636 of file FeatureFloodCount.h.

Referenced by communicateAndMerge(), consolidateMergedFeatures(), deserialize(), expandEdgeHalos(), expandPointHalos(), flood(), initialize(), PolycrystalUserObjectBase::mergeSets(), mergeSets(), prepareDataForTransfer(), GrainTracker::prepopulateState(), scatterAndUpdateRanks(), and serialize().

◆ _pbs

PeriodicBoundaries* FeatureFloodCount::_pbs
protected

A pointer to the periodic boundary constraints object.

Definition at line 668 of file FeatureFloodCount.h.

Referenced by initialSetup(), PolycrystalUserObjectBase::isNewFeatureOrConnectedRegion(), meshChanged(), and visitElementalNeighbors().

◆ _periodic_node_map

std::multimap<dof_id_type, dof_id_type> FeatureFloodCount::_periodic_node_map
protected

The data structure which is a list of nodes that are constrained to other nodes based on the imposed periodic boundary conditions.

Definition at line 688 of file FeatureFloodCount.h.

Referenced by appendPeriodicNeighborNodes(), FauxGrainTracker::getEntityValue(), getEntityValue(), and meshChanged().

◆ _point_locator

std::unique_ptr<PointLocatorBase> FeatureFloodCount::_point_locator
protected

◆ _prepare_for_transfer

const PerfID FeatureFloodCount::_prepare_for_transfer
private

Definition at line 754 of file FeatureFloodCount.h.

Referenced by prepareDataForTransfer().

◆ _single_map_mode

const bool FeatureFloodCount::_single_map_mode
protected

This variable is used to indicate whether or not multiple maps are used during flooding.

Definition at line 572 of file FeatureFloodCount.h.

Referenced by flood(), PolycrystalUserObjectBase::PolycrystalUserObjectBase(), sortAndLabel(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _step_connecting_threshold

Real FeatureFloodCount::_step_connecting_threshold
protected

Definition at line 559 of file FeatureFloodCount.h.

Referenced by getConnectingThreshold(), and initialize().

◆ _step_threshold

Real FeatureFloodCount::_step_threshold
protected

Definition at line 554 of file FeatureFloodCount.h.

Referenced by GrainTracker::getThreshold(), getThreshold(), and initialize().

◆ _threshold

const Real FeatureFloodCount::_threshold
protected

The threshold above (or below) where an entity may begin a new region (feature)

Definition at line 553 of file FeatureFloodCount.h.

Referenced by FauxGrainTracker::execute(), and initialize().

◆ _update_field_info

const PerfID FeatureFloodCount::_update_field_info
private

Definition at line 753 of file FeatureFloodCount.h.

◆ _use_less_than_threshold_comparison

const bool FeatureFloodCount::_use_less_than_threshold_comparison
protected

Use less-than when comparing values against the threshold value.

True by default. If false, then greater-than comparison is used instead.

Definition at line 595 of file FeatureFloodCount.h.

Referenced by compareValueWithThreshold(), and FauxGrainTracker::execute().

◆ _var_index_maps

std::vector<std::map<dof_id_type, int> > FeatureFloodCount::_var_index_maps
protected

This map keeps track of which variables own which nodes.

We need a vector of them for multimap mode where multiple variables can own a single mode.

Note: This map is only populated when "show_var_coloring" is set to true.

Definition at line 620 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount(), getEntityValue(), initialize(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _var_index_mode

const bool FeatureFloodCount::_var_index_mode
protected

This variable is used to indicate whether the maps will contain unique region information or just the variable numbers owning those regions.

Definition at line 582 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount(), getEntityValue(), initialize(), GrainTracker::updateFieldInfo(), and updateFieldInfo().

◆ _var_number

unsigned long FeatureFloodCount::_var_number
protected

This variable is used to build the periodic node map.

Assumption: We are going to assume that either all variables are periodic or none are. This assumption can be relaxed at a later time if necessary.

Definition at line 569 of file FeatureFloodCount.h.

Referenced by GrainTracker::centroidRegionDistance(), and meshChanged().

◆ _vars

std::vector<MooseVariable *> FeatureFloodCount::_vars
protected

◆ _volatile_feature_sets

std::vector<FeatureData> FeatureFloodCount::_volatile_feature_sets
protected

Derived objects (e.g.

the GrainTracker) may require restartable data to track information across time steps. The FeatureFloodCounter however does not. This container is here so that we have the flexabilty to switch between volatile and non-volatile storage. The _feature_sets data structure can conditionally refer to this structure or a MOOSE-provided structure, which is backed up.

Definition at line 652 of file FeatureFloodCount.h.

◆ invalid_id

const unsigned int FeatureFloodCount::invalid_id = std::numeric_limits<unsigned int>::max()
static

◆ invalid_size_t

const std::size_t FeatureFloodCount::invalid_size_t = std::numeric_limits<std::size_t>::max()
static

The documentation for this class was generated from the following files: