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

#include <PolycrystalEBSD.h>

Inheritance diagram for PolycrystalEBSD:
[legend]

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...
 
enum  BoundaryIntersection : unsigned char {
  BoundaryIntersection::NONE = 0x0, BoundaryIntersection::ANY_BOUNDARY = 0x1, BoundaryIntersection::PRIMARY_PERCOLATION_BOUNDARY = 0x2, BoundaryIntersection::SECONDARY_PERCOLATION_BOUNDARY = 0x4,
  BoundaryIntersection::SPECIFIED_BOUNDARY = 0x8
}
 This enumeration is used to inidacate status of boundary intersections. More...
 

Public Member Functions

 PolycrystalEBSD (const InputParameters &parameters)
 
virtual void getGrainsBasedOnPoint (const Point &point, std::vector< unsigned int > &grains) const override
 Method for retrieving active grain IDs based on some point in the mesh. More...
 
virtual Real getVariableValue (unsigned int op_index, const Point &p) const override
 Returns the variable value for a given op_index and mesh point. More...
 
virtual Real getNodalVariableValue (unsigned int op_index, const Node &n) const override
 Similarly to the getVariableValue method, this method also returns values but may be optimized for returning nodal values. More...
 
virtual unsigned int getNumGrains () const override
 Must be overridden by the deriving class to provide the number of grains in the polycrystal structure. More...
 
virtual void precomputeGrainStructure ()
 This callback is triggered after the object is initialized and may be optionally overridden to do precompute the element to grain identifiers ahead of time. More...
 
virtual void getGrainsBasedOnElem (const Elem &elem, std::vector< unsigned int > &grains) const
 This method may be defined in addition to the point based initialization to speed up lookups. More...
 
virtual const std::vector< unsigned int > & getGrainToOps () const
 Method for retrieving the initial grain OP assignments. More...
 
virtual void initialSetup () override
 UserObject interface overrides. More...
 
virtual void initialize () override
 
virtual void execute () override
 
virtual void finalize () override
 
virtual void meshChanged () 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 bool doesFeatureIntersectSpecifiedBoundary (unsigned int feature_id) const
 Returns a Boolean indicating whether this feature intersects boundaries in a user-supplied list. More...
 
virtual bool isFeaturePercolated (unsigned int feature_id) const
 Returns a Boolean indicating whether this feature is percolated (e.g. More...
 
virtual Point featureCentroid (unsigned int feature_id) const
 Returns the centroid of the designated feature (only supported 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 Member Functions

static MooseEnum coloringAlgorithms ()
 Returns all available coloring algorithms as an enumeration type for input files. More...
 
static std::string coloringAlgorithmDescriptions ()
 Returns corresponding descriptions of available coloring algorithms. 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

virtual bool areFeaturesMergeable (const FeatureData &f1, const FeatureData &f2) const override
 Method for determining whether two features are mergeable. More...
 
virtual bool isNewFeatureOrConnectedRegion (const DofObject *dof_object, std::size_t &current_index, FeatureData *&feature, Status &status, unsigned int &new_id) override
 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...
 
virtual void mergeSets () override
 This routine is called on the master rank only and stitches together the partial feature pieces seen on any processor. More...
 
void buildGrainAdjacencyMatrix ()
 Builds a dense adjacency matrix based on the discovery of grain neighbors and halos surrounding each grain. More...
 
void assignOpsToGrains ()
 Method that runs a coloring algorithm to assign OPs to grains. More...
 
bool colorGraph (unsigned int vertex)
 Built-in simple "back-tracking" algorithm to assign colors to a graph. More...
 
bool isGraphValid (unsigned int vertex, unsigned int color)
 Helper method for the back-tracking graph coloring algorithm. More...
 
void printGrainAdjacencyMatrix () const
 Prints out the adjacency matrix in a nicely spaced integer format. More...
 
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...
 
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...
 
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 updateBoundaryIntersections (FeatureData &feature) const
 Update the feature's attributes to indicate boundary intersections. 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

const unsigned int _phase
 
const EBSDReader_ebsd_reader
 
const std::map< dof_id_type, std::vector< Real > > & _node_to_grain_weight_map
 
std::unique_ptr< DenseMatrix< Real > > _adjacency_matrix
 The dense adjacency matrix. More...
 
const unsigned int _dim
 mesh dimension More...
 
const unsigned int _op_num
 The maximum number of order parameters (colors) available to assign to the grain structure. More...
 
std::vector< unsigned int > _grain_to_op
 A vector indicating which op is assigned to each grain. More...
 
const MooseEnum _coloring_algorithm
 The selected graph coloring algorithm used by this object. More...
 
bool _colors_assigned
 A Boolean indicating whether the object has assigned colors to grains (internal use) More...
 
const bool _output_adjacency_matrix
 A user controllable Boolean which can be used to print the adjacency matrix to the console. More...
 
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::unordered_set< dof_id_type > _all_boundary_entity_ids
 The set of entities on the boundary of the domain used for determining if features intersect any boundary. More...
 
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
 
std::vector< unsigned int > _empty_var_to_features
 
std::vector< BoundaryID > _primary_perc_bnds
 
std::vector< BoundaryID > _secondary_perc_bnds
 
std::vector< BoundaryID > _specified_bnds
 
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. More...
 
const bool _is_master
 Convenience variable for testing master rank. More...
 

Static Protected Attributes

static const unsigned int INVALID_COLOR
 Used to indicate an invalid coloring for the built-in back-tracking algorithm. More...
 
static const unsigned int HALO_THICKNESS = 4
 Used to hold the thickness of the halo that should be constructed for detecting adjacency. 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::vector< unsigned int > _prealloc_tmp_grains
 Temporary storage area for current grains at a point to avoid memory churn. More...
 
std::map< dof_id_type, std::vector< unsigned int > > _entity_to_grain_cache
 
const PerfID _execute_timer
 Timers. More...
 
const PerfID _finalize_timer
 
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 _merge_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

Definition at line 21 of file PolycrystalEBSD.h.

Member Enumeration Documentation

◆ BoundaryIntersection

enum FeatureFloodCount::BoundaryIntersection : unsigned char
stronginherited

This enumeration is used to inidacate status of boundary intersections.

Enumerator
NONE 
ANY_BOUNDARY 
PRIMARY_PERCOLATION_BOUNDARY 
SECONDARY_PERCOLATION_BOUNDARY 
SPECIFIED_BOUNDARY 

Definition at line 129 of file FeatureFloodCount.h.

129  : unsigned char
130  {
131  NONE = 0x0,
132  ANY_BOUNDARY = 0x1,
133  PRIMARY_PERCOLATION_BOUNDARY = 0x2,
134  SECONDARY_PERCOLATION_BOUNDARY = 0x4,
135  SPECIFIED_BOUNDARY = 0x8
136  };

◆ FieldType

enum FeatureFloodCount::FieldType
stronginherited
Enumerator
UNIQUE_REGION 
VARIABLE_COLORING 
GHOSTED_ENTITIES 
HALOS 
CENTROID 
ACTIVE_BOUNDS 

Definition at line 103 of file FeatureFloodCount.h.

104  {
105  UNIQUE_REGION,
106  VARIABLE_COLORING,
107  GHOSTED_ENTITIES,
108  HALOS,
109  CENTROID,
110  ACTIVE_BOUNDS,
111  };

◆ Status

enum FeatureFloodCount::Status : unsigned char
stronginherited

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

Enumerator
CLEAR 
MARKED 
DIRTY 
INACTIVE 

Definition at line 120 of file FeatureFloodCount.h.

120  : unsigned char
121  {
122  CLEAR = 0x0,
123  MARKED = 0x1,
124  DIRTY = 0x2,
125  INACTIVE = 0x4
126  };

Constructor & Destructor Documentation

◆ PolycrystalEBSD()

PolycrystalEBSD::PolycrystalEBSD ( const InputParameters &  parameters)

Definition at line 26 of file PolycrystalEBSD.C.

27  : PolycrystalUserObjectBase(parameters),
28  _phase(isParamValid("phase") ? getParam<unsigned int>("phase") : libMesh::invalid_uint),
29  _ebsd_reader(getUserObject<EBSDReader>("ebsd_reader")),
31 {
32 }

Member Function Documentation

◆ appendPeriodicNeighborNodes()

void FeatureFloodCount::appendPeriodicNeighborNodes ( FeatureData feature) const
protectedinherited

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 1771 of file FeatureFloodCount.C.

1772 {
1773  if (_is_elemental)
1774  {
1775  for (auto entity : feature._local_ids)
1776  {
1777  Elem * elem = _mesh.elemPtr(entity);
1778 
1779  for (MooseIndex(elem->n_nodes()) node_n = 0; node_n < elem->n_nodes(); ++node_n)
1780  {
1781  auto iters = _periodic_node_map.equal_range(elem->node_id(node_n));
1782 
1783  for (auto it = iters.first; it != iters.second; ++it)
1784  {
1785  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->first);
1786  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->second);
1787  }
1788  }
1789  }
1790  }
1791  else
1792  {
1793  for (auto entity : feature._local_ids)
1794  {
1795  auto iters = _periodic_node_map.equal_range(entity);
1796 
1797  for (auto it = iters.first; it != iters.second; ++it)
1798  {
1799  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->first);
1800  feature._periodic_nodes.insert(feature._periodic_nodes.end(), it->second);
1801  }
1802  }
1803  }
1804 
1805  // TODO: Remove duplicates
1806 }

Referenced by FeatureFloodCount::prepareDataForTransfer().

◆ areFeaturesMergeable()

bool PolycrystalUserObjectBase::areFeaturesMergeable ( const FeatureData f1,
const FeatureData f2 
) const
overrideprotectedvirtualinherited

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 from FeatureFloodCount.

Definition at line 380 of file PolycrystalUserObjectBase.C.

382 {
383  if (f1._id != f2._id)
384  return false;
385 
386  mooseAssert(f1._var_index == f2._var_index, "Feature should be mergeable but aren't");
387  return true;
388 }

Referenced by PolycrystalUserObjectBase::mergeSets().

◆ assignOpsToGrains()

void PolycrystalUserObjectBase::assignOpsToGrains ( )
protectedinherited

Method that runs a coloring algorithm to assign OPs to grains.

Definition at line 413 of file PolycrystalUserObjectBase.C.

414 {
415  mooseAssert(_is_master, "This routine should only be called on the master rank");
416 
417  Moose::perf_log.push("assignOpsToGrains()", "PolycrystalICTools");
418 
419  // Use a simple backtracking coloring algorithm
420  if (_coloring_algorithm == "bt")
421  {
422  paramInfo("coloring_algorithm",
423  "The backtracking algorithm has exponential complexity. If you are using very few "
424  "order parameters,\nor you have several hundred grains or more, you should use one "
425  "of the PETSc coloring algorithms such as \"jp\".");
426 
427  if (!colorGraph(0))
428  paramError("op_num",
429  "Unable to find a valid grain to op coloring, Make sure you have created enough "
430  "variables to hold a\nvalid polycrystal initial condition (no grains represented "
431  "by the same variable should be allowed to\ntouch, ~8 for 2D, ~25 for 3D)?");
432  }
433  else // PETSc Coloring algorithms
434  {
435 #ifdef LIBMESH_HAVE_PETSC
436  const std::string & ca_str = _coloring_algorithm;
437  Real * am_data = _adjacency_matrix->get_values().data();
438 
439  try
440  {
441  Moose::PetscSupport::colorAdjacencyMatrix(
442  am_data, _feature_count, _vars.size(), _grain_to_op, ca_str.c_str());
443  }
444  catch (std::runtime_error & e)
445  {
446  paramError("op_num",
447  "Unable to find a valid grain to op coloring, Make sure you have created enough "
448  "variables to hold a\nvalid polycrystal initial condition (no grains represented "
449  "by the same variable should be allowed to\ntouch, ~8 for 2D, ~25 for 3D)?");
450  }
451 #else
452  mooseError("Selected coloring algorithm requires PETSc");
453 #endif
454  }
455 
456  Moose::perf_log.pop("assignOpsToGrains()", "PolycrystalICTools");
457 }

Referenced by PolycrystalUserObjectBase::finalize().

◆ buildFeatureIdToLocalIndices()

void FeatureFloodCount::buildFeatureIdToLocalIndices ( unsigned int  max_id)
protectedinherited

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 665 of file FeatureFloodCount.C.

666 {
667  _feature_id_to_local_index.assign(max_id + 1, invalid_size_t);
668  for (MooseIndex(_feature_sets) feature_index = 0; feature_index < _feature_sets.size();
669  ++feature_index)
670  {
671  if (_feature_sets[feature_index]._status != Status::INACTIVE)
672  {
673  mooseAssert(_feature_sets[feature_index]._id <= max_id,
674  "Feature ID out of range(" << _feature_sets[feature_index]._id << ')');
675  _feature_id_to_local_index[_feature_sets[feature_index]._id] = feature_index;
676  }
677  }
678 }

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

◆ buildGrainAdjacencyMatrix()

void PolycrystalUserObjectBase::buildGrainAdjacencyMatrix ( )
protectedinherited

Builds a dense adjacency matrix based on the discovery of grain neighbors and halos surrounding each grain.

Definition at line 391 of file PolycrystalUserObjectBase.C.

392 {
393  mooseAssert(_is_master, "This routine should only be called on the master rank");
394 
395  _adjacency_matrix = libmesh_make_unique<DenseMatrix<Real>>(_feature_count, _feature_count);
396  for (auto & grain1 : _feature_sets)
397  {
398  for (auto & grain2 : _feature_sets)
399  {
400  if (&grain1 == &grain2)
401  continue;
402 
403  if (grain1.boundingBoxesIntersect(grain2) && grain1.halosIntersect(grain2))
404  {
405  (*_adjacency_matrix)(grain1._id, grain2._id) = 1.;
406  (*_adjacency_matrix)(grain1._id, grain2._id) = 1.;
407  }
408  }
409  }
410 }

Referenced by PolycrystalUserObjectBase::finalize().

◆ buildLocalToGlobalIndices()

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

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 619 of file FeatureFloodCount.C.

621 {
622  mooseAssert(_is_master, "This method must only be called on the root processor");
623 
624  counts.assign(_n_procs, 0);
625  // Now size the individual counts vectors based on the largest index seen per processor
626  for (const auto & feature : _feature_sets)
627  for (const auto & local_index_pair : feature._orig_ids)
628  {
629  // local_index_pair.first = ranks, local_index_pair.second = local_index
630  mooseAssert(local_index_pair.first < _n_procs, "Processor ID is out of range");
631  if (local_index_pair.second >= static_cast<std::size_t>(counts[local_index_pair.first]))
632  counts[local_index_pair.first] = local_index_pair.second + 1;
633  }
634 
635  // Build the offsets vector
636  unsigned int globalsize = 0;
637  std::vector<int> offsets(_n_procs); // Type is signed for use with the MPI API
638  for (MooseIndex(offsets) i = 0; i < offsets.size(); ++i)
639  {
640  offsets[i] = globalsize;
641  globalsize += counts[i];
642  }
643 
644  // Finally populate the master vector
645  local_to_global_all.resize(globalsize, FeatureFloodCount::invalid_size_t);
646  for (const auto & feature : _feature_sets)
647  {
648  // Get the local indices from the feature and build a map
649  for (const auto & local_index_pair : feature._orig_ids)
650  {
651  auto rank = local_index_pair.first;
652  mooseAssert(rank < _n_procs, rank << ", " << _n_procs);
653 
654  auto local_index = local_index_pair.second;
655  auto stacked_local_index = offsets[rank] + local_index;
656 
657  mooseAssert(stacked_local_index < globalsize,
658  "Global index: " << stacked_local_index << " is out of range");
659  local_to_global_all[stacked_local_index] = feature._id;
660  }
661  }
662 }

Referenced by FeatureFloodCount::scatterAndUpdateRanks().

◆ clearDataStructures()

void FeatureFloodCount::clearDataStructures ( )
protectedvirtualinherited

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

Definition at line 330 of file FeatureFloodCount.C.

331 {
332 }

Referenced by FeatureFloodCount::communicateAndMerge().

◆ colorGraph()

bool PolycrystalUserObjectBase::colorGraph ( unsigned int  vertex)
protectedinherited

Built-in simple "back-tracking" algorithm to assign colors to a graph.

Definition at line 460 of file PolycrystalUserObjectBase.C.

461 {
462  // Base case: All grains are assigned
463  if (vertex == _feature_count)
464  return true;
465 
466  // Consider this grain and try different ops
467  for (unsigned int color_idx = 0; color_idx < _op_num; ++color_idx)
468  {
469  // We'll try to spread these colors around a bit rather than
470  // packing them all on the first few colors if we have several colors.
471  unsigned int color = (vertex + color_idx) % _op_num;
472 
473  if (isGraphValid(vertex, color))
474  {
475  _grain_to_op[vertex] = color;
476 
477  if (colorGraph(vertex + 1))
478  return true;
479 
480  // Backtrack...
482  }
483  }
484 
485  return false;
486 }

Referenced by PolycrystalUserObjectBase::assignOpsToGrains().

◆ coloringAlgorithmDescriptions()

std::string PolycrystalUserObjectBase::coloringAlgorithmDescriptions ( )
staticinherited

Returns corresponding descriptions of available coloring algorithms.

Definition at line 522 of file PolycrystalUserObjectBase.C.

523 {
524  return "The grain neighbor graph coloring algorithm to use: \"jp\" (DEFAULT) Jones and "
525  "Plassmann, an efficient coloring algorithm, \"power\" an alternative stochastic "
526  "algorithm, \"greedy\", a greedy assignment algorithm with stochastic updates to "
527  "guarantee a valid coloring, \"bt\", a back tracking algorithm that produces good "
528  "distributions but may experience exponential run time in the worst case scenario "
529  "(works well on medium to large 2D problems)";
530 }

Referenced by validParams< PolycrystalUserObjectBase >().

◆ coloringAlgorithms()

MooseEnum PolycrystalUserObjectBase::coloringAlgorithms ( )
staticinherited

Returns all available coloring algorithms as an enumeration type for input files.

Definition at line 516 of file PolycrystalUserObjectBase.C.

517 {
518  return MooseEnum("jp power greedy bt", "jp");
519 }

Referenced by validParams< PolycrystalUserObjectBase >().

◆ communicateAndMerge()

void FeatureFloodCount::communicateAndMerge ( )
protectedinherited

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 412 of file FeatureFloodCount.C.

413 {
414  TIME_SECTION(_comm_and_merge);
415 
416  // First we need to transform the raw data into a usable data structure
418 
426  std::vector<std::string> send_buffers(1);
427 
434  std::vector<std::string> recv_buffers, deserialize_buffers;
435 
443  {
444  auto rank = processor_id();
445  bool is_merging_processor = rank < _n_vars;
446 
447  if (is_merging_processor)
448  recv_buffers.reserve(_app.n_processors());
449 
450  for (MooseIndex(_n_vars) i = 0; i < _n_vars; ++i)
451  {
452  serialize(send_buffers[0], i);
453 
458  _communicator.gather_packed_range(i,
459  (void *)(nullptr),
460  send_buffers.begin(),
461  send_buffers.end(),
462  std::back_inserter(recv_buffers));
463 
470  if (rank == i)
471  recv_buffers.swap(deserialize_buffers);
472  else
473  recv_buffers.clear();
474  }
475 
476  // Setup a new communicator for doing merging communication operations
477  Parallel::Communicator merge_comm;
478 
479  // TODO: Update to MPI_UNDEFINED when libMesh bug is fixed.
480  _communicator.split(is_merging_processor ? 0 : 1, rank, merge_comm);
481 
482  if (is_merging_processor)
483  {
491  std::vector<std::list<FeatureData>> tmp_data(_partial_feature_sets.size());
492  tmp_data.swap(_partial_feature_sets);
493 
494  deserialize(deserialize_buffers, processor_id());
495 
496  send_buffers[0].clear();
497  recv_buffers.clear();
498  deserialize_buffers.clear();
499 
500  // Merge one variable's worth of data
501  mergeSets();
502 
503  // Now we need to serialize again to send to the master (only the processors who did work)
504  serialize(send_buffers[0]);
505 
506  // Free up as much memory as possible here before we do global communication
508 
513  merge_comm.gather_packed_range(0,
514  (void *)(nullptr),
515  send_buffers.begin(),
516  send_buffers.end(),
517  std::back_inserter(recv_buffers));
518 
519  if (_is_master)
520  {
521  // The root process now needs to deserialize all of the data
522  deserialize(recv_buffers);
523 
524  send_buffers[0].clear();
525  recv_buffers.clear();
526 
527  consolidateMergedFeatures(&tmp_data);
528  }
529  else
530  // Restore our original data on non-zero ranks
531  tmp_data.swap(_partial_feature_sets);
532  }
533  }
534 
535  // Serialized merging (master does all the work)
536  else
537  {
538  if (_is_master)
539  recv_buffers.reserve(_app.n_processors());
540 
541  serialize(send_buffers[0]);
542 
543  // Free up as much memory as possible here before we do global communication
545 
550  _communicator.gather_packed_range(0,
551  (void *)(nullptr),
552  send_buffers.begin(),
553  send_buffers.end(),
554  std::back_inserter(recv_buffers));
555 
556  if (_is_master)
557  {
558  // The root process now needs to deserialize all of the data
559  deserialize(recv_buffers);
560  recv_buffers.clear();
561 
562  mergeSets();
563 
565  }
566  }
567 
568  // Make sure that feature count is communicated to all ranks
569  _communicator.broadcast(_feature_count);
570 }

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

◆ compareValueWithThreshold()

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

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 1418 of file FeatureFloodCount.C.

1419 {
1420  return ((_use_less_than_threshold_comparison && (entity_value >= threshold)) ||
1421  (!_use_less_than_threshold_comparison && (entity_value <= threshold)));
1422 }

Referenced by FeatureFloodCount::isNewFeatureOrConnectedRegion().

◆ consolidateMergedFeatures()

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

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 1176 of file FeatureFloodCount.C.

1177 {
1178  TIME_SECTION(_consolidate_merged_features);
1179 
1187  mooseAssert(_is_master, "cosolidateMergedFeatures() may only be called on the master processor");
1188 
1189  // Offset where the current set of features with the same variable id starts in the flat vector
1190  unsigned int feature_offset = 0;
1191  // Set the member feature count to zero and start counting the actual features
1192  _feature_count = 0;
1193 
1194  for (MooseIndex(_maps_size) map_num = 0; map_num < _maps_size; ++map_num)
1195  {
1196  for (auto & feature : _partial_feature_sets[map_num])
1197  {
1198  if (saved_data)
1199  {
1200  for (auto it = (*saved_data)[map_num].begin(); it != (*saved_data)[map_num].end();
1201  /* no increment */)
1202  {
1203  if (feature.canConsolidate(*it))
1204  {
1205  feature.consolidate(std::move(*it));
1206  it = (*saved_data)[map_num].erase(it); // increment
1207  }
1208  else
1209  ++it;
1210  }
1211  }
1212 
1213  // If after merging we still have an inactive feature, discard it
1214  if (feature._status == Status::CLEAR)
1215  {
1216  // First we need to calculate the centroid now that we are doing merging all partial
1217  // features
1218  if (feature._vol_count != 0)
1219  feature._centroid /= feature._vol_count;
1220 
1221  _feature_sets.emplace_back(std::move(feature));
1222  ++_feature_count;
1223  }
1224  }
1225 
1226  // Record the feature numbers just for the current map
1227  _feature_counts_per_map[map_num] = _feature_count - feature_offset;
1228 
1229  // Now update the running feature count so we can calculate the next map's contribution
1230  feature_offset = _feature_count;
1231 
1232  // Clean up the "moved" objects
1233  _partial_feature_sets[map_num].clear();
1234  }
1235 
1240 }

Referenced by FeatureFloodCount::communicateAndMerge().

◆ deserialize()

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

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 1086 of file FeatureFloodCount.C.

1087 {
1088  // The input string stream used for deserialization
1089  std::istringstream iss;
1090 
1091  auto rank = processor_id();
1092 
1093  for (MooseIndex(serialized_buffers) proc_id = 0; proc_id < serialized_buffers.size(); ++proc_id)
1094  {
1106  if (var_num == invalid_id && proc_id == rank)
1107  continue;
1108 
1109  iss.str(serialized_buffers[proc_id]); // populate the stream with a new buffer
1110  iss.clear(); // reset the string stream state
1111 
1112  // Load the gathered data into the data structure.
1113  if (var_num == invalid_id)
1114  dataLoad(iss, _partial_feature_sets, this);
1115  else
1116  dataLoad(iss, _partial_feature_sets[var_num], this);
1117  }
1118 }

Referenced by FeatureFloodCount::communicateAndMerge().

◆ doesFeatureIntersectBoundary()

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

Returns a Boolean indicating whether this feature intersects any boundary.

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 828 of file FeatureFloodCount.C.

829 {
830  // TODO: This information is not parallel consistent when using FeatureFloodCounter
831 
832  // Some processors don't contain the largest feature id, in that case we just return invalid_id
833  if (feature_id >= _feature_id_to_local_index.size())
834  return false;
835 
836  auto local_index = _feature_id_to_local_index[feature_id];
837 
838  if (local_index != invalid_size_t)
839  {
840  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
841  return _feature_sets[local_index]._status != Status::INACTIVE
842  ? _feature_sets[local_index]._boundary_intersection != BoundaryIntersection::NONE
843  : false;
844  }
845 
846  return false;
847 }

Referenced by FeatureVolumeVectorPostprocessor::execute().

◆ doesFeatureIntersectSpecifiedBoundary()

bool FeatureFloodCount::doesFeatureIntersectSpecifiedBoundary ( unsigned int  feature_id) const
virtualinherited

Returns a Boolean indicating whether this feature intersects boundaries in a user-supplied list.

Reimplemented in GrainTracker.

Definition at line 850 of file FeatureFloodCount.C.

851 {
852  // TODO: This information is not parallel consistent when using FeatureFloodCounter
853 
854  // Some processors don't contain the largest feature id, in that case we just return invalid_id
855  if (feature_id >= _feature_id_to_local_index.size())
856  return false;
857 
858  auto local_index = _feature_id_to_local_index[feature_id];
859 
860  if (local_index != invalid_size_t)
861  {
862  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
863  return _feature_sets[local_index]._status != Status::INACTIVE
864  ? ((_feature_sets[local_index]._boundary_intersection &
867  : false;
868  }
869 
870  return false;
871 }

Referenced by FeatureVolumeVectorPostprocessor::execute().

◆ execute()

void PolycrystalUserObjectBase::execute ( )
overridevirtualinherited

We need one map per grain when creating the initial condition to support overlapping features. Luckily, this is a fairly sparse structure.

This loop is similar to the one found in the base class however, there are two key differences between building up the initial condition and discovering features based on solution variables:

1) When building up the initial condition, we aren't inspecting the actual variable values so we don't need to loop over all of the coupled variables. 2) We want to discover all features on a single pass since there may be thousands of features in a simulation. However, we can only actively flood a single feature at a time. To make sure that we pick up all features that might start on a given entity, we'll keep retrying the flood routine on the same entity as long as new discoveries are being made. We know this information from the return value of flood.

Reimplemented from FeatureFloodCount.

Definition at line 116 of file PolycrystalUserObjectBase.C.

117 {
118  if (!_colors_assigned)
120  // No need to rerun the object if the mesh hasn't changed
121  else if (!_fe_problem.hasInitialAdaptivity())
122  return;
123 
124  TIME_SECTION(_execute_timer);
125  CONSOLE_TIMED_PRINT("Computing Polycrystal Initial Condition");
126 
132 
145  for (const auto & current_elem : _fe_problem.getEvaluableElementRange())
146  {
147  // Loop over elements or nodes
148  if (_is_elemental)
149  while (flood(current_elem, invalid_size_t))
150  ;
151  else
152  {
153  auto n_nodes = current_elem->n_vertices();
154  for (auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
155  {
156  const Node * current_node = current_elem->node_ptr(i);
157 
158  while (flood(current_node, invalid_size_t))
159  ;
160  }
161  }
162  }
163 }

◆ expandEdgeHalos()

void FeatureFloodCount::expandEdgeHalos ( unsigned int  num_layers_to_expand)
protectedinherited

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 1527 of file FeatureFloodCount.C.

1528 {
1529  if (num_layers_to_expand == 0)
1530  return;
1531 
1532  TIME_SECTION(_expand_halos);
1533 
1534  for (auto & list_ref : _partial_feature_sets)
1535  {
1536  for (auto & feature : list_ref)
1537  {
1538  for (MooseIndex(num_layers_to_expand) halo_level = 0; halo_level < num_layers_to_expand;
1539  ++halo_level)
1540  {
1545  FeatureData::container_type orig_halo_ids(feature._halo_ids);
1546  for (auto entity : orig_halo_ids)
1547  {
1548  if (_is_elemental)
1549  visitElementalNeighbors(_mesh.elemPtr(entity),
1550  &feature,
1551  /*expand_halos_only =*/true,
1552  /*disjoint_only =*/false);
1553  else
1554  visitNodalNeighbors(_mesh.nodePtr(entity),
1555  &feature,
1556  /*expand_halos_only =*/true);
1557  }
1558 
1563  FeatureData::container_type disjoint_orig_halo_ids(feature._disjoint_halo_ids);
1564  for (auto entity : disjoint_orig_halo_ids)
1565  {
1566  if (_is_elemental)
1567  visitElementalNeighbors(_mesh.elemPtr(entity),
1568 
1569  &feature,
1570  /*expand_halos_only =*/true,
1571  /*disjoint_only =*/true);
1572  else
1573  visitNodalNeighbors(_mesh.nodePtr(entity),
1574 
1575  &feature,
1576  /*expand_halos_only =*/true);
1577  }
1578  }
1579  }
1580  }
1581 }

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

◆ expandPointHalos()

void FeatureFloodCount::expandPointHalos ( )
protectedinherited

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 1465 of file FeatureFloodCount.C.

1466 {
1467  const auto & node_to_elem_map = _mesh.nodeToActiveSemilocalElemMap();
1468  FeatureData::container_type expanded_local_ids;
1469  auto my_processor_id = processor_id();
1470 
1477  for (auto & list_ref : _partial_feature_sets)
1478  {
1479  for (auto & feature : list_ref)
1480  {
1481  expanded_local_ids.clear();
1482 
1483  for (auto entity : feature._local_ids)
1484  {
1485  const Elem * elem = _mesh.elemPtr(entity);
1486  mooseAssert(elem, "elem pointer is NULL");
1487 
1488  // Get the nodes on a current element so that we can add in point neighbors
1489  auto n_nodes = elem->n_vertices();
1490  for (MooseIndex(n_nodes) i = 0; i < n_nodes; ++i)
1491  {
1492  const Node * current_node = elem->node_ptr(i);
1493 
1494  auto elem_vector_it = node_to_elem_map.find(current_node->id());
1495  if (elem_vector_it == node_to_elem_map.end())
1496  mooseError("Error in node to elem map");
1497 
1498  const auto & elem_vector = elem_vector_it->second;
1499 
1500  std::copy(elem_vector.begin(),
1501  elem_vector.end(),
1502  std::insert_iterator<FeatureData::container_type>(expanded_local_ids,
1503  expanded_local_ids.end()));
1504 
1505  // Now see which elements need to go into the ghosted set
1506  for (auto entity : elem_vector)
1507  {
1508  const Elem * neighbor = _mesh.elemPtr(entity);
1509  mooseAssert(neighbor, "neighbor pointer is NULL");
1510 
1511  if (neighbor->processor_id() != my_processor_id)
1512  feature._ghosted_ids.insert(feature._ghosted_ids.end(), elem->id());
1513  }
1514  }
1515  }
1516 
1517  // Replace the existing local ids with the expanded local ids
1518  feature._local_ids.swap(expanded_local_ids);
1519 
1520  // Copy the expanded local_ids into the halo_ids container
1521  feature._halo_ids = feature._local_ids;
1522  }
1523  }
1524 }

◆ featureCentroid()

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

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

Definition at line 900 of file FeatureFloodCount.C.

901 {
902  if (feature_id >= _feature_id_to_local_index.size())
903  return invalid_id;
904 
905  auto local_index = _feature_id_to_local_index[feature_id];
906 
907  Real invalid_coord = std::numeric_limits<Real>::max();
908  Point p(invalid_coord, invalid_coord, invalid_coord);
909  if (local_index != invalid_size_t)
910  {
911  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
912  p = _feature_sets[local_index]._centroid;
913  }
914  return p;
915 }

Referenced by FeatureVolumeVectorPostprocessor::execute().

◆ finalize()

void PolycrystalUserObjectBase::finalize ( )
overridevirtualinherited

All ranks: Update the variable indices based on the graph coloring algorithm. Here we index into the _grain_to_op vector based on the grain_id to obtain the right assignment.

Reimplemented from FeatureFloodCount.

Definition at line 166 of file PolycrystalUserObjectBase.C.

167 {
168  if (_colors_assigned && !_fe_problem.hasInitialAdaptivity())
169  return;
170 
171  TIME_SECTION(_finalize_timer);
172  CONSOLE_TIMED_PRINT("Finalizing Polycrystal Initial Condition");
173 
174  // TODO: Possibly retrieve the halo thickness from the active GrainTracker object?
175  constexpr unsigned int halo_thickness = 2;
176 
177  expandEdgeHalos(halo_thickness - 1);
178 
180 
181  if (!_colors_assigned)
182  {
183  // Resize the color assignment vector here. All ranks need a copy of this
185  if (_is_master)
186  {
188 
190 
193  }
194 
195  // Communicate the coloring with all ranks
196  _communicator.broadcast(_grain_to_op);
197 
202  for (auto & grain : _feature_sets)
203  grain._var_index = _grain_to_op[grain._id];
204  }
205 
206  _colors_assigned = true;
207 }

◆ flood()

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

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 1294 of file FeatureFloodCount.C.

1296 {
1297  // if (dof_object == nullptr || dof_object == libMesh::remote_elem)
1298  // return false;
1299  mooseAssert(dof_object, "DOF object is nullptr");
1300  mooseAssert(_entity_queue.empty(), "Entity queue is not empty when starting a feature");
1301 
1302  // Kick off the exploration of a new feature
1303  _entity_queue.push_front(dof_object);
1304 
1305  bool return_value = false;
1306  FeatureData * feature = nullptr;
1307  while (!_entity_queue.empty())
1308  {
1309  const DofObject * curr_dof_object = _entity_queue.back();
1310  const Elem * elem = _is_elemental ? static_cast<const Elem *>(curr_dof_object) : nullptr;
1311  _entity_queue.pop_back();
1312 
1313  // Retrieve the id of the current entity
1314  auto entity_id = curr_dof_object->id();
1315 
1316  // Has this entity already been marked? - if so move along
1317  if (current_index != invalid_size_t &&
1318  _entities_visited[current_index].find(entity_id) != _entities_visited[current_index].end())
1319  continue;
1320 
1321  // Are we outside of the range we should be working in?
1322  if (_is_elemental && !_dof_map.is_evaluable(*elem))
1323  continue;
1324 
1325  // See if the current entity either starts a new feature or continues an existing feature
1326  auto new_id = invalid_id; // Writable reference to hold an optional id;
1327  Status status =
1328  Status::INACTIVE; // Status is inactive until we find an entity above the starting threshold
1329 
1330  // Make sure that the Assembly object has the right element and subdomain information set
1331  // since we are moving through the mesh in a manual fashion.
1332  if (_is_elemental)
1333  _fe_problem.setCurrentSubdomainID(elem, 0);
1334 
1335  if (!isNewFeatureOrConnectedRegion(curr_dof_object, current_index, feature, status, new_id))
1336  {
1337  // If we have an active feature, we just found a halo entity
1338  if (feature)
1339  feature->_halo_ids.insert(feature->_halo_ids.end(), entity_id);
1340  continue;
1341  }
1342 
1343  mooseAssert(current_index != invalid_size_t, "current_index is invalid");
1344 
1353  return_value = true;
1354  _entities_visited[current_index].insert(entity_id);
1355 
1356  auto map_num = _single_map_mode ? decltype(current_index)(0) : current_index;
1357 
1358  // New Feature (we need to create it and add it to our data structure)
1359  if (!feature)
1360  {
1361  _partial_feature_sets[map_num].emplace_back(
1362  current_index, _feature_count++, processor_id(), status);
1363 
1364  // Get a handle to the feature we will update (always the last feature in the data structure)
1365  feature = &_partial_feature_sets[map_num].back();
1366 
1367  // If new_id is valid, we'll set it in the feature here.
1368  if (new_id != invalid_id)
1369  feature->_id = new_id;
1370  }
1371 
1372  // Insert the current entity into the local ids data structure
1373  feature->_local_ids.insert(feature->_local_ids.end(), entity_id);
1374 
1380  if (_is_elemental && processor_id() == curr_dof_object->processor_id())
1381  {
1382  // Keep track of how many elements participate in the centroid averaging
1383  feature->_vol_count++;
1384 
1385  // Sum the centroid values for now, we'll average them later
1386  feature->_centroid += elem->centroid();
1387 
1388  // // Does the volume intersect the boundary?
1389  // if (_all_boundary_entity_ids.find(elem->id()) != _all_boundary_entity_ids.end())
1390  // feature->_intersects_boundary = true;
1391  }
1392 
1393  if (_is_elemental)
1395  feature,
1396  /*expand_halos_only =*/false,
1397  /*disjoint_only =*/false);
1398  else
1399  visitNodalNeighbors(static_cast<const Node *>(curr_dof_object),
1400  feature,
1401  /*expand_halos_only =*/false);
1402  }
1403 
1404  return return_value;
1405 }

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

◆ getConnectingThreshold()

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

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

Definition at line 1412 of file FeatureFloodCount.C.

1413 {
1415 }

Referenced by FeatureFloodCount::isNewFeatureOrConnectedRegion().

◆ getCoupledVars()

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

Returns a const vector to the coupled variable pointers.

Definition at line 98 of file FeatureFloodCount.h.

98 { return _vars; }

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

◆ getEntityValue()

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

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 918 of file FeatureFloodCount.C.

921 {
922  auto use_default = false;
923  if (var_index == invalid_size_t)
924  {
925  use_default = true;
926  var_index = 0;
927  }
928 
929  mooseAssert(var_index < _maps_size, "Index out of range");
930 
931  switch (field_type)
932  {
934  {
935  const auto entity_it = _feature_maps[var_index].find(entity_id);
936 
937  if (entity_it != _feature_maps[var_index].end())
938  return entity_it->second; // + _region_offsets[var_index];
939  else
940  return -1;
941  }
942 
944  {
945  mooseAssert(
947  "\"enable_var_coloring\" must be set to true to pull back the VARIABLE_COLORING field");
948 
949  const auto entity_it = _var_index_maps[var_index].find(entity_id);
950 
951  if (entity_it != _var_index_maps[var_index].end())
952  return entity_it->second;
953  else
954  return -1;
955  }
956 
958  {
959  const auto entity_it = _ghosted_entity_ids.find(entity_id);
960 
961  if (entity_it != _ghosted_entity_ids.end())
962  return entity_it->second;
963  else
964  return -1;
965  }
966 
967  case FieldType::HALOS:
968  {
969  if (!use_default)
970  {
971  const auto entity_it = _halo_ids[var_index].find(entity_id);
972  if (entity_it != _halo_ids[var_index].end())
973  return entity_it->second;
974  }
975  else
976  {
977  // Showing halos in reverse order for backwards compatibility
978  for (auto map_num = _maps_size;
979  map_num-- /* don't compare greater than zero for unsigned */;)
980  {
981  const auto entity_it = _halo_ids[map_num].find(entity_id);
982 
983  if (entity_it != _halo_ids[map_num].end())
984  return entity_it->second;
985  }
986  }
987  return -1;
988  }
989 
990  case FieldType::CENTROID:
991  {
992  if (_periodic_node_map.size())
993  mooseDoOnce(mooseWarning(
994  "Centroids are not correct when using periodic boundaries, contact the MOOSE team"));
995 
996  // If this element contains the centroid of one of features, return one
997  const auto * elem_ptr = _mesh.elemPtr(entity_id);
998 
999  for (const auto & feature : _feature_sets)
1000  {
1001  if (feature._status == Status::INACTIVE)
1002  continue;
1003 
1004  if (elem_ptr->contains_point(feature._centroid))
1005  return 1;
1006  }
1007 
1008  return 0;
1009  }
1010 
1011  default:
1012  return 0;
1013  }
1014 }

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

◆ getFeatures()

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

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

Definition at line 340 of file FeatureFloodCount.h.

340 { return _feature_sets; }

Referenced by GrainTracker::prepopulateState().

◆ getFeatureVar()

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

Returns the variable representing the passed in feature.

Reimplemented in GrainTracker, and FauxGrainTracker.

Definition at line 809 of file FeatureFloodCount.C.

810 {
811  // Some processors don't contain the largest feature id, in that case we just return invalid_id
812  if (feature_id >= _feature_id_to_local_index.size())
813  return invalid_id;
814 
815  auto local_index = _feature_id_to_local_index[feature_id];
816  if (local_index != invalid_size_t)
817  {
818  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
819  return _feature_sets[local_index]._status != Status::INACTIVE
820  ? _feature_sets[local_index]._var_index
821  : invalid_id;
822  }
823 
824  return invalid_id;
825 }

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

◆ getFECoupledVars()

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

Returns a const vector to the coupled MooseVariableFEBase pointers.

Definition at line 101 of file FeatureFloodCount.h.

101 { return _fe_vars; }

Referenced by AverageGrainVolume::AverageGrainVolume().

◆ getGrainsBasedOnElem()

virtual void PolycrystalUserObjectBase::getGrainsBasedOnElem ( const Elem &  elem,
std::vector< unsigned int > &  grains 
) const
inlinevirtualinherited

This method may be defined in addition to the point based initialization to speed up lookups.

It returns grain IDs based on the current element. Note: If your simulation contains adaptivity the point based method may be used to retrieve grain information as well as this method.

Definition at line 52 of file PolycrystalUserObjectBase.h.

53  {
54  getGrainsBasedOnPoint(elem.centroid(), grains);
55  }

Referenced by VoronoiICAux::computeValue(), and PolycrystalUserObjectBase::isNewFeatureOrConnectedRegion().

◆ getGrainsBasedOnPoint()

void PolycrystalEBSD::getGrainsBasedOnPoint ( const Point &  point,
std::vector< unsigned int > &  grains 
) const
overridevirtual

Method for retrieving active grain IDs based on some point in the mesh.

Typically these are element centroids or nodes depending on the basis functions being initialized. ICs that have fixed resolution data (i.e. experimental datasets) may choose to implement the element based method as well for added convenience.

Implements PolycrystalUserObjectBase.

Definition at line 35 of file PolycrystalEBSD.C.

37 {
39 
40  // See if we are in a phase that we are actually tracking
41  if (_phase != libMesh::invalid_uint && _phase != d._phase)
42  {
43  grains.resize(0);
44  return;
45  }
46 
47  // Get the ids from the EBSD reader
48  const auto global_id = _ebsd_reader.getGlobalID(d._feature_id);
49  const auto local_id = _ebsd_reader.getAvgData(global_id)._local_id;
50 
51  grains.resize(1);
52  grains[0] = _phase != libMesh::invalid_uint ? local_id : global_id;
53 }

Referenced by getVariableValue().

◆ getGrainToOps()

virtual const std::vector<unsigned int>& PolycrystalUserObjectBase::getGrainToOps ( ) const
inlinevirtualinherited

Method for retrieving the initial grain OP assignments.

Definition at line 83 of file PolycrystalUserObjectBase.h.

83 { return _grain_to_op; }

◆ getNodalVariableValue()

Real PolycrystalEBSD::getNodalVariableValue ( unsigned int  op_index,
const Node &  n 
) const
overridevirtual

Similarly to the getVariableValue method, this method also returns values but may be optimized for returning nodal values.

Reimplemented from PolycrystalUserObjectBase.

Definition at line 65 of file PolycrystalEBSD.C.

66 {
67  // Make sure the _current_node is in the node_to_grain_weight_map (return error if not in map)
68  const auto it = _node_to_grain_weight_map.find(n.id());
69 
70  if (it == _node_to_grain_weight_map.end())
71  mooseError("The following node id is not in the node map: ", n.id());
72 
73  // Increment through all grains at node_index (these are global IDs if consider_phase is false and
74  // local IDs otherwise)
75  const auto num_grains = getNumGrains();
76  for (MooseIndex(num_grains) index = 0; index < num_grains; ++index)
77  {
78  // If the current order parameter index (_op_index) is equal to the assigned index
79  // (_assigned_op),
80  // set the value from node_to_grain_weight_map
81  auto grain_index =
82  _phase != libMesh::invalid_uint ? _ebsd_reader.getGlobalID(_phase, index) : index;
83  mooseAssert(grain_index < it->second.size(), "grain_index out of range");
84  auto value = (it->second)[grain_index];
85  if (_grain_to_op[index] == op_index && value > 0.0)
86  return value;
87  }
88 
89  return 0.0;
90 }

◆ getNumberActiveFeatures()

std::size_t FeatureFloodCount::getNumberActiveFeatures ( ) const
inherited

Return the number of active features.

Definition at line 791 of file FeatureFloodCount.C.

792 {
793  // Note: This value is parallel consistent, see FeatureFloodCount::communicateAndMerge()
794  return _feature_count;
795 }

Referenced by AverageGrainVolume::getValue().

◆ getNumGrains()

unsigned int PolycrystalEBSD::getNumGrains ( ) const
overridevirtual

Must be overridden by the deriving class to provide the number of grains in the polycrystal structure.

Implements PolycrystalUserObjectBase.

Definition at line 56 of file PolycrystalEBSD.C.

57 {
58  if (_phase != libMesh::invalid_uint)
60  else
61  return _ebsd_reader.getGrainNum();
62 }

Referenced by getNodalVariableValue().

◆ getThreshold()

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

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

Reimplemented in GrainTracker.

Definition at line 1407 of file FeatureFloodCount.C.

1408 {
1409  return _step_threshold;
1410 }

Referenced by FeatureFloodCount::isNewFeatureOrConnectedRegion().

◆ getTotalFeatureCount()

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

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 798 of file FeatureFloodCount.C.

799 {
805  return _feature_count;
806 }

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

◆ getValue()

Real FeatureFloodCount::getValue ( )
overridevirtualinherited

Reimplemented in FauxGrainTracker.

Definition at line 785 of file FeatureFloodCount.C.

786 {
787  return static_cast<Real>(_feature_count);
788 }

◆ getVariableValue()

Real PolycrystalEBSD::getVariableValue ( unsigned int  op_index,
const Point &  p 
) const
overridevirtual

Returns the variable value for a given op_index and mesh point.

This is the method used by the initial condition after the Polycrystal grain structure has be setup. Those grains are then distributed to the typically smaller number of order parameters by this class. This method is then used to return those values but it may be overridden in a derived class.

Implements PolycrystalUserObjectBase.

Definition at line 93 of file PolycrystalEBSD.C.

94 {
95  std::vector<unsigned int> grain_ids;
96  getGrainsBasedOnPoint(p, grain_ids);
97 
98  if (grain_ids.empty())
99  return -1.0;
100 
101  mooseAssert(grain_ids.size() == 1, "Expected only one grain at point in EBSDReader");
102  auto index = grain_ids[0];
103  mooseAssert(index < _grain_to_op.size(), "Index out of range");
104 
105  return _grain_to_op[index] == op_index ? 1.0 : 0.0;
106 }

◆ getVarToFeatureVector()

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

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 701 of file FeatureFloodCount.C.

702 {
703  mooseDoOnce(if (!_compute_var_to_feature_map) mooseError(
704  "Please set \"compute_var_to_feature_map = true\" to use this interface method"));
705 
706  const auto pos = _entity_var_to_features.find(elem_id);
707  if (pos != _entity_var_to_features.end())
708  {
709  mooseAssert(pos->second.size() == _n_vars, "Variable to feature vector not sized properly");
710  return pos->second;
711  }
712  else
713  return _empty_var_to_features;
714 }

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

◆ initialize()

void PolycrystalUserObjectBase::initialize ( )
overridevirtualinherited

Reimplemented from FeatureFloodCount.

Definition at line 105 of file PolycrystalUserObjectBase.C.

106 {
107  if (_colors_assigned && !_fe_problem.hasInitialAdaptivity())
108  return;
109 
110  _entity_to_grain_cache.clear();
111 
113 }

◆ initialSetup()

void PolycrystalUserObjectBase::initialSetup ( )
overridevirtualinherited

UserObject interface overrides.

Derived classes should not override any of these methods.

For polycrystal ICs we need to assume that each of the variables has the same periodicity. Since BCs are handled elsewhere in the system, we'll have to check this case explicitly.

Reimplemented from FeatureFloodCount.

Definition at line 83 of file PolycrystalUserObjectBase.C.

84 {
89  if (_op_num < 1)
90  mooseError("No coupled variables found");
91 
92  for (unsigned int dim = 0; dim < _dim; ++dim)
93  {
94  bool first_variable_value = _mesh.isTranslatedPeriodic(_vars[0]->number(), dim);
95 
96  for (unsigned int i = 1; i < _vars.size(); ++i)
97  if (_mesh.isTranslatedPeriodic(_vars[i]->number(), dim) != first_variable_value)
98  mooseError("Coupled polycrystal variables differ in periodicity");
99  }
100 
102 }

◆ isBoundaryEntity()

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

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

Definition at line 1810 of file FeatureFloodCount.C.

1811 {
1812  mooseAssert(_bnd_elem_range, "Boundary Element Range is nullptr");
1813 
1814  if (entity)
1815  for (const auto & belem : *_bnd_elem_range)
1816  // Only works for Elements
1817  if (belem->_elem->id() == entity->id() && hasBoundary(belem->_bnd_id))
1818  return true;
1819 
1820  return false;
1821 }

Referenced by FeatureFloodCount::visitNeighborsHelper().

◆ isElemental()

bool FeatureFloodCount::isElemental ( ) const
inlineinherited

Definition at line 117 of file FeatureFloodCount.h.

117 { return _is_elemental; }

Referenced by FeatureFloodCountAux::FeatureFloodCountAux().

◆ isFeaturePercolated()

bool FeatureFloodCount::isFeaturePercolated ( unsigned int  feature_id) const
virtualinherited

Returns a Boolean indicating whether this feature is percolated (e.g.

intersects at least two different boundaries from sets supplied by the user)

Reimplemented in GrainTracker.

Definition at line 874 of file FeatureFloodCount.C.

875 {
876  // TODO: This information is not parallel consistent when using FeatureFloodCounter
877 
878  // Some processors don't contain the largest feature id, in that case we just return invalid_id
879  if (feature_id >= _feature_id_to_local_index.size())
880  return false;
881 
882  auto local_index = _feature_id_to_local_index[feature_id];
883 
884  if (local_index != invalid_size_t)
885  {
886  mooseAssert(local_index < _feature_sets.size(), "local_index out of bounds");
887  bool primary = ((_feature_sets[local_index]._boundary_intersection &
890  bool secondary = ((_feature_sets[local_index]._boundary_intersection &
893  return _feature_sets[local_index]._status != Status::INACTIVE ? (primary && secondary) : false;
894  }
895 
896  return false;
897 }

Referenced by FeatureVolumeVectorPostprocessor::execute().

◆ isGraphValid()

bool PolycrystalUserObjectBase::isGraphValid ( unsigned int  vertex,
unsigned int  color 
)
protectedinherited

Helper method for the back-tracking graph coloring algorithm.

Definition at line 489 of file PolycrystalUserObjectBase.C.

490 {
491  // See if the proposed color is valid based on the current neighbor colors
492  for (unsigned int neighbor = 0; neighbor < _feature_count; ++neighbor)
493  if ((*_adjacency_matrix)(vertex, neighbor) && color == _grain_to_op[neighbor])
494  return false;
495  return true;
496 }

Referenced by PolycrystalUserObjectBase::colorGraph().

◆ isNewFeatureOrConnectedRegion()

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

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.

When building the IC, we can't use the _entities_visited data structure the same way as we do for the base class. We need to discover multiple overlapping grains in a single pass. However we don't know what grain we are working on when we enter the flood routine (when that check is normally made). Only after we've made the callback to the child class do we know which grains we are operating on (at least until we've triggered the recursion). We need to see if there is at least one active grain where we haven't already visited the current entity before continuing.

If we get here the current entity is not part of the active feature, however we now want to look at neighbors.

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.

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 from FeatureFloodCount.

Definition at line 238 of file PolycrystalUserObjectBase.C.

243 {
244  mooseAssert(_t_step == 0, "PolyIC only works if we begin in the initial condition");
245 
246  // Retrieve the id of the current entity
247  auto entity_id = dof_object->id();
248  auto grains_it = _entity_to_grain_cache.lower_bound(entity_id);
249 
250  if (grains_it == _entity_to_grain_cache.end() || grains_it->first != entity_id)
251  {
252  std::vector<unsigned int> grain_ids;
253 
254  if (_is_elemental)
255  getGrainsBasedOnElem(*static_cast<const Elem *>(dof_object), grain_ids);
256  else
257  getGrainsBasedOnPoint(*static_cast<const Node *>(dof_object), grain_ids);
258 
259  grains_it = _entity_to_grain_cache.emplace_hint(grains_it, entity_id, std::move(grain_ids));
260  }
261 
271  auto saved_grain_id = invalid_id;
272  if (current_index == invalid_size_t)
273  {
274  for (auto grain_id : grains_it->second)
275  {
276  mooseAssert(!_colors_assigned || grain_id < _grain_to_op.size(), "grain_id out of range");
277  auto map_num = _colors_assigned ? _grain_to_op[grain_id] : grain_id;
278  if (_entities_visited[map_num].find(entity_id) == _entities_visited[map_num].end())
279  {
280  saved_grain_id = grain_id;
281 
282  if (!_colors_assigned)
283  current_index = grain_id;
284  else
285  current_index = _grain_to_op[grain_id];
286 
287  break;
288  }
289  }
290 
291  if (current_index == invalid_size_t)
292  return false;
293  }
294  else if (_entities_visited[current_index].find(entity_id) !=
295  _entities_visited[current_index].end())
296  return false;
297 
298  if (!feature)
299  {
300  new_id = saved_grain_id;
301  status &= ~Status::INACTIVE;
302 
303  return true;
304  }
305  else
306  {
307  const auto & grain_ids = grains_it->second;
308  if (std::find(grain_ids.begin(), grain_ids.end(), feature->_id) != grain_ids.end())
309  return true;
310 
316  if (_is_elemental)
317  {
318  Elem * elem = _mesh.queryElemPtr(entity_id);
319  mooseAssert(elem, "Element is nullptr");
320 
321  std::vector<const Elem *> all_active_neighbors;
322  MeshBase & mesh = _mesh.getMesh();
323 
324  for (auto i = decltype(elem->n_neighbors())(0); i < elem->n_neighbors(); ++i)
325  {
326  const Elem * neighbor_ancestor = nullptr;
327 
332  neighbor_ancestor = elem->neighbor_ptr(i);
333  if (neighbor_ancestor)
334  neighbor_ancestor->active_family_tree_by_neighbor(all_active_neighbors, elem, false);
335  else // if (expand_halos_only /*&& feature->_periodic_nodes.empty()*/)
336  {
337  neighbor_ancestor = elem->topological_neighbor(i, mesh, *_point_locator, _pbs);
338 
346  if (neighbor_ancestor)
347  neighbor_ancestor->active_family_tree_by_topological_neighbor(
348  all_active_neighbors, elem, mesh, *_point_locator, _pbs, false);
349  }
350  }
351 
352  for (const auto neighbor : all_active_neighbors)
353  {
354  // Retrieve the id of the current entity
355  auto neighbor_id = neighbor->id();
356  auto neighbor_it = _entity_to_grain_cache.lower_bound(neighbor_id);
357 
358  if (neighbor_it == _entity_to_grain_cache.end() || neighbor_it->first != neighbor_id)
359  {
360  std::vector<unsigned int> more_grain_ids;
361 
362  getGrainsBasedOnElem(*static_cast<const Elem *>(neighbor), more_grain_ids);
363 
364  neighbor_it = _entity_to_grain_cache.emplace_hint(
365  neighbor_it, neighbor_id, std::move(more_grain_ids));
366  }
367 
368  const auto & more_grain_ids = neighbor_it->second;
369  if (std::find(more_grain_ids.begin(), more_grain_ids.end(), feature->_id) !=
370  more_grain_ids.end())
371  return true;
372  }
373  }
374 
375  return false;
376  }
377 }

◆ mergeSets()

void PolycrystalUserObjectBase::mergeSets ( )
overrideprotectedvirtualinherited

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

With initial conditions we know the grain IDs of every grain (even partial grains). We can use this information to put all mergeable features adjacent to one and other in the list so that merging is simply O(n).

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 from FeatureFloodCount.

Definition at line 210 of file PolycrystalUserObjectBase.C.

211 {
217  _partial_feature_sets[0].sort();
218 
219  auto it1 = _partial_feature_sets[0].begin();
220  auto it_end = _partial_feature_sets[0].end();
221  while (it1 != it_end)
222  {
223  auto it2 = it1;
224  if (++it2 == it_end)
225  break;
226 
227  if (areFeaturesMergeable(*it1, *it2))
228  {
229  it1->merge(std::move(*it2));
230  _partial_feature_sets[0].erase(it2);
231  }
232  else
233  ++it1; // Only increment if we have a mismatch
234  }
235 }

◆ meshChanged()

void FeatureFloodCount::meshChanged ( )
overridevirtualinherited

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 335 of file FeatureFloodCount.C.

336 {
337  _point_locator = _mesh.getMesh().sub_point_locator();
338 
339  _mesh.buildPeriodicNodeMap(_periodic_node_map, _var_number, _pbs);
340 
341  // Build a new node to element map
342  _nodes_to_elem_map.clear();
343  MeshTools::build_nodes_to_elem_map(_mesh.getMesh(), _nodes_to_elem_map);
344 
350  _all_boundary_entity_ids.clear();
351  if (_is_elemental)
352  for (auto elem_it = _mesh.bndElemsBegin(), elem_end = _mesh.bndElemsEnd(); elem_it != elem_end;
353  ++elem_it)
354  _all_boundary_entity_ids.insert((*elem_it)->_elem->id());
355 }

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

◆ numCoupledVars()

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

Returns the number of coupled varaibles.

Definition at line 89 of file FeatureFloodCount.h.

89 { return _n_vars; }

◆ precomputeGrainStructure()

virtual void PolycrystalUserObjectBase::precomputeGrainStructure ( )
inlinevirtualinherited

This callback is triggered after the object is initialized and may be optionally overridden to do precompute the element to grain identifiers ahead of time.

Reimplemented in PolycrystalCircles, PolycrystalVoronoi, and PolycrystalHex.

Definition at line 36 of file PolycrystalUserObjectBase.h.

36 {}

Referenced by PolycrystalUserObjectBase::execute().

◆ prepareDataForTransfer()

void FeatureFloodCount::prepareDataForTransfer ( )
protectedinherited

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 1017 of file FeatureFloodCount.C.

1018 {
1019  TIME_SECTION(_prepare_for_transfer);
1020 
1021  MeshBase & mesh = _mesh.getMesh();
1022 
1023  FeatureData::container_type local_ids_no_ghost, set_difference;
1024 
1025  for (auto & list_ref : _partial_feature_sets)
1026  {
1027  for (auto & feature : list_ref)
1028  {
1029  // See if the feature intersects a boundary or perhaps one of the percolation boundaries.
1030  updateBoundaryIntersections(feature);
1031 
1032  // Periodic node ids
1033  appendPeriodicNeighborNodes(feature);
1034 
1040  FeatureFloodCount::sort(feature._ghosted_ids);
1041  FeatureFloodCount::sort(feature._local_ids);
1042  FeatureFloodCount::sort(feature._halo_ids);
1043  FeatureFloodCount::sort(feature._disjoint_halo_ids);
1044  FeatureFloodCount::sort(feature._periodic_nodes);
1045 
1046  // Now extend the bounding box by the halo region
1047  if (_is_elemental)
1048  feature.updateBBoxExtremes(mesh);
1049  else
1050  {
1051  for (auto & halo_id : feature._halo_ids)
1052  updateBBoxExtremesHelper(feature._bboxes[0], mesh.point(halo_id));
1053  }
1054 
1055  mooseAssert(!feature._local_ids.empty(), "local entity ids cannot be empty");
1056 
1061  feature._min_entity_id = *feature._local_ids.begin();
1062  }
1063  }
1064 }

Referenced by FeatureFloodCount::communicateAndMerge().

◆ printGrainAdjacencyMatrix()

void PolycrystalUserObjectBase::printGrainAdjacencyMatrix ( ) const
protectedinherited

Prints out the adjacency matrix in a nicely spaced integer format.

Definition at line 499 of file PolycrystalUserObjectBase.C.

500 {
501  _console << "Grain Adjacency Matrix:\n";
502  for (unsigned int i = 0; i < _adjacency_matrix->m(); i++)
503  {
504  for (unsigned int j = 0; j < _adjacency_matrix->n(); j++)
505  _console << _adjacency_matrix->el(i, j) << " ";
506  _console << '\n';
507  }
508 
509  _console << "Grain to OP assignments:\n";
510  for (auto op : _grain_to_op)
511  _console << op << " ";
512  _console << '\n' << std::endl;
513 }

Referenced by PolycrystalUserObjectBase::finalize().

◆ reserve() [1/2]

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

Definition at line 748 of file FeatureFloodCount.h.

750  {
751  // Sets are trees, no reservations necessary

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

◆ reserve() [2/2]

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

Definition at line 754 of file FeatureFloodCount.h.

756  {
757  container.reserve(size);

◆ scatterAndUpdateRanks()

void FeatureFloodCount::scatterAndUpdateRanks ( )
protectedinherited

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 717 of file FeatureFloodCount.C.

718 {
719  // local to global map (one per processor)
720  std::vector<int> counts;
721  std::vector<std::size_t> local_to_global_all;
722  if (_is_master)
723  buildLocalToGlobalIndices(local_to_global_all, counts);
724 
725  // Scatter local_to_global indices to all processors and store in class member variable
726  _communicator.scatter(local_to_global_all, counts, _local_to_global_feature_map);
727 
728  std::size_t largest_global_index = std::numeric_limits<std::size_t>::lowest();
729  if (!_is_master)
730  {
732 
739  for (auto & list_ref : _partial_feature_sets)
740  {
741  for (auto & feature : list_ref)
742  {
743  mooseAssert(feature._orig_ids.size() == 1, "feature._orig_ids length doesn't make sense");
744 
745  auto global_index = FeatureFloodCount::invalid_size_t;
746  auto local_index = feature._orig_ids.begin()->second;
747 
748  if (local_index < _local_to_global_feature_map.size())
749  global_index = _local_to_global_feature_map[local_index];
750 
751  if (global_index != FeatureFloodCount::invalid_size_t)
752  {
753  if (global_index > largest_global_index)
754  largest_global_index = global_index;
755 
756  // Set the correct global index
757  feature._id = global_index;
758 
766  feature._status &= ~Status::INACTIVE;
767 
768  // Move the feature into the correct place
769  _feature_sets[local_index] = std::move(feature);
770  }
771  }
772  }
773  }
774  else
775  {
776  for (auto global_index : local_to_global_all)
777  if (global_index != FeatureFloodCount::invalid_size_t && global_index > largest_global_index)
778  largest_global_index = global_index;
779  }
780 
781  buildFeatureIdToLocalIndices(largest_global_index);
782 }

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

◆ serialize()

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

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

Definition at line 1067 of file FeatureFloodCount.C.

1068 {
1069  // stream for serializing the _partial_feature_sets data structure to a byte stream
1070  std::ostringstream oss;
1071 
1072  mooseAssert(var_num == invalid_id || var_num < _partial_feature_sets.size(),
1073  "var_num out of range");
1074 
1075  // Serialize everything
1076  if (var_num == invalid_id)
1077  dataStore(oss, _partial_feature_sets, this);
1078  else
1079  dataStore(oss, _partial_feature_sets[var_num], this);
1080 
1081  // Populate the passed in string pointer with the string stream's buffer contents
1082  serialized_buffer.assign(oss.str());
1083 }

Referenced by FeatureFloodCount::communicateAndMerge().

◆ setsIntersect()

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

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

It exits as soon as any intersection is detected.

Definition at line 543 of file FeatureFloodCount.h.

547  {
548  while (first1 != last1 && first2 != last2)
549  {
550  if (*first1 == *first2)
551  return true;
552 
553  if (*first1 < *first2)
554  ++first1;
555  else if (*first1 > *first2)
556  ++first2;
557  }
558  return false;
559  }

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

◆ sort() [1/2]

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

Definition at line 736 of file FeatureFloodCount.h.

738  {
739  // Sets are already sorted, do nothing

Referenced by FeatureFloodCount::prepareDataForTransfer().

◆ sort() [2/2]

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

Definition at line 742 of file FeatureFloodCount.h.

744  {
745  std::sort(container.begin(), container.end());

◆ sortAndLabel()

void FeatureFloodCount::sortAndLabel ( )
protectedinherited

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 573 of file FeatureFloodCount.C.

574 {
575  mooseAssert(_is_master, "sortAndLabel can only be called on the master");
576 
582  std::sort(_feature_sets.begin(), _feature_sets.end());
583 
584 #ifndef NDEBUG
585 
590  unsigned int feature_offset = 0;
591  for (MooseIndex(_maps_size) map_num = 0; map_num < _maps_size; ++map_num)
592  {
593  // Skip empty map checks
594  if (_feature_counts_per_map[map_num] == 0)
595  continue;
596 
597  // Check the begin and end of the current range
598  auto range_front = feature_offset;
599  auto range_back = feature_offset + _feature_counts_per_map[map_num] - 1;
600 
601  mooseAssert(range_front <= range_back && range_back < _feature_count,
602  "Indexing error in feature sets");
603 
604  if (!_single_map_mode && (_feature_sets[range_front]._var_index != map_num ||
605  _feature_sets[range_back]._var_index != map_num))
606  mooseError("Error in _feature_sets sorting, map index: ", map_num);
607 
608  feature_offset += _feature_counts_per_map[map_num];
609  }
610 #endif
611 
612  // Label the features with an ID based on the sorting (processor number independent value)
613  for (MooseIndex(_feature_sets) i = 0; i < _feature_sets.size(); ++i)
614  if (_feature_sets[i]._id == invalid_id)
615  _feature_sets[i]._id = i;
616 }

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

◆ updateBoundaryIntersections()

void FeatureFloodCount::updateBoundaryIntersections ( FeatureData feature) const
protectedinherited

Update the feature's attributes to indicate boundary intersections.

Definition at line 1724 of file FeatureFloodCount.C.

1725 {
1726  if (_is_elemental)
1727  {
1728  for (auto entity : feature._local_ids)
1729  {
1730  // See if this feature is on a boundary if we haven't already figured that out
1731  if ((feature._boundary_intersection & BoundaryIntersection::ANY_BOUNDARY) ==
1733  {
1734  Elem * elem = _mesh.elemPtr(entity);
1735  if (elem && elem->on_boundary())
1736  feature._boundary_intersection |= BoundaryIntersection::ANY_BOUNDARY;
1737  }
1738 
1739  // Now see if the feature touches the primary and/or secondary boundary IDs if we haven't
1740  // figured that out already
1741  if ((feature._boundary_intersection & BoundaryIntersection::PRIMARY_PERCOLATION_BOUNDARY) ==
1743  {
1744  for (auto primary_id : _primary_perc_bnds)
1745  if (_mesh.isBoundaryElem(entity, primary_id))
1746  feature._boundary_intersection |= BoundaryIntersection::PRIMARY_PERCOLATION_BOUNDARY;
1747  }
1748 
1749  if ((feature._boundary_intersection & BoundaryIntersection::SECONDARY_PERCOLATION_BOUNDARY) ==
1751  {
1752  for (auto secondary_id : _secondary_perc_bnds)
1753  if (_mesh.isBoundaryElem(entity, secondary_id))
1754  feature._boundary_intersection |= BoundaryIntersection::SECONDARY_PERCOLATION_BOUNDARY;
1755  }
1756 
1757  // See if the feature contacts any of the user-specified boundaries if we haven't
1758  // done so already
1759  if ((feature._boundary_intersection & BoundaryIntersection::SPECIFIED_BOUNDARY) ==
1761  {
1762  for (auto specified_id : _specified_bnds)
1763  if (_mesh.isBoundaryElem(entity, specified_id))
1764  feature._boundary_intersection |= BoundaryIntersection::SPECIFIED_BOUNDARY;
1765  }
1766  }
1767  }
1768 }

Referenced by FeatureFloodCount::prepareDataForTransfer().

◆ updateFieldInfo()

void FeatureFloodCount::updateFieldInfo ( )
protectedvirtualinherited

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 1249 of file FeatureFloodCount.C.

1250 {
1251  for (MooseIndex(_feature_sets) i = 0; i < _feature_sets.size(); ++i)
1252  {
1253  auto & feature = _feature_sets[i];
1254 
1255  // If the developer has requested _condense_map_info we'll make sure we only update the zeroth
1256  // map
1257  auto map_index = (_single_map_mode || _condense_map_info) ? decltype(feature._var_index)(0)
1258  : feature._var_index;
1259 
1260  // Loop over the entity ids of this feature and update our local map
1261  for (auto entity : feature._local_ids)
1262  {
1263  _feature_maps[map_index][entity] = static_cast<int>(feature._id);
1264 
1265  if (_var_index_mode)
1266  _var_index_maps[map_index][entity] = feature._var_index;
1267 
1268  // Fill in the data structure that keeps track of all features per elem
1270  {
1271  auto insert_pair = moose_try_emplace(
1272  _entity_var_to_features, entity, std::vector<unsigned int>(_n_vars, invalid_id));
1273  auto & vec_ref = insert_pair.first->second;
1274  vec_ref[feature._var_index] = feature._id;
1275  }
1276  }
1277 
1278  if (_compute_halo_maps)
1279  // Loop over the halo ids to update cells with halo information
1280  for (auto entity : feature._halo_ids)
1281  _halo_ids[map_index][entity] = static_cast<int>(feature._id);
1282 
1283  // Loop over the ghosted ids to update cells with ghost information
1284  for (auto entity : feature._ghosted_ids)
1285  _ghosted_entity_ids[entity] = 1;
1286 
1287  // TODO: Fixme
1288  if (!_global_numbering)
1289  mooseError("Local numbering currently disabled");
1290  }
1291 }

Referenced by FeatureFloodCount::finalize().

◆ updateRegionOffsets()

void FeatureFloodCount::updateRegionOffsets ( )
protectedinherited

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 
)
protectedinherited

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 1584 of file FeatureFloodCount.C.

1588 {
1589  mooseAssert(elem, "Elem is NULL");
1590 
1591  std::vector<const Elem *> all_active_neighbors;
1592  MeshBase & mesh = _mesh.getMesh();
1593 
1594  // Loop over all neighbors (at the the same level as the current element)
1595  for (MooseIndex(elem->n_neighbors()) i = 0; i < elem->n_neighbors(); ++i)
1596  {
1597  const Elem * neighbor_ancestor = nullptr;
1598  bool topological_neighbor = false;
1599 
1604  neighbor_ancestor = elem->neighbor_ptr(i);
1605  if (neighbor_ancestor)
1606  {
1607  if (neighbor_ancestor == libMesh::remote_elem)
1608  continue;
1609 
1610  neighbor_ancestor->active_family_tree_by_neighbor(all_active_neighbors, elem, false);
1611  }
1612  else
1613  {
1614  neighbor_ancestor = elem->topological_neighbor(i, mesh, *_point_locator, _pbs);
1615 
1623  if (neighbor_ancestor)
1624  {
1625  neighbor_ancestor->active_family_tree_by_topological_neighbor(
1626  all_active_neighbors, elem, mesh, *_point_locator, _pbs, false);
1627 
1628  topological_neighbor = true;
1629  }
1630  else
1631  {
1637  updateBBoxExtremesHelper(feature->_bboxes[0], *elem);
1638  }
1639  }
1640 
1641  visitNeighborsHelper(elem,
1642  all_active_neighbors,
1643  feature,
1644  expand_halos_only,
1645  topological_neighbor,
1646  disjoint_only);
1647 
1648  all_active_neighbors.clear();
1649  }
1650 }

Referenced by FeatureFloodCount::expandEdgeHalos(), and FeatureFloodCount::flood().

◆ 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 
)
protectedinherited

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 1667 of file FeatureFloodCount.C.

1673 {
1674  // Loop over all active element neighbors
1675  for (const auto neighbor : neighbor_entities)
1676  {
1677  if (neighbor && (!_is_boundary_restricted || isBoundaryEntity(neighbor)))
1678  {
1679  if (expand_halos_only)
1680  {
1681  auto entity_id = neighbor->id();
1682 
1683  if (topological_neighbor || disjoint_only)
1684  feature->_disjoint_halo_ids.insert(feature->_disjoint_halo_ids.end(), entity_id);
1685  else if (feature->_local_ids.find(entity_id) == feature->_local_ids.end())
1686  feature->_halo_ids.insert(feature->_halo_ids.end(), entity_id);
1687  }
1688  else
1689  {
1690  auto my_processor_id = processor_id();
1691 
1692  if (!topological_neighbor && neighbor->processor_id() != my_processor_id)
1693  feature->_ghosted_ids.insert(feature->_ghosted_ids.end(), curr_entity->id());
1694 
1704  if (curr_entity->processor_id() == my_processor_id ||
1705  neighbor->processor_id() == my_processor_id)
1706  {
1713  if (topological_neighbor || disjoint_only)
1714  feature->_disjoint_halo_ids.insert(feature->_disjoint_halo_ids.end(), neighbor->id());
1715  else
1716  _entity_queue.push_front(neighbor);
1717  }
1718  }
1719  }
1720  }
1721 }

Referenced by FeatureFloodCount::visitElementalNeighbors(), and FeatureFloodCount::visitNodalNeighbors().

◆ visitNodalNeighbors()

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

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 1653 of file FeatureFloodCount.C.

1656 {
1657  mooseAssert(node, "Node is NULL");
1658 
1659  std::vector<const Node *> all_active_neighbors;
1660  MeshTools::find_nodal_neighbors(_mesh.getMesh(), *node, _nodes_to_elem_map, all_active_neighbors);
1661 
1662  visitNeighborsHelper(node, all_active_neighbors, feature, expand_halos_only, false, false);
1663 }

Referenced by FeatureFloodCount::expandEdgeHalos(), and FeatureFloodCount::flood().

Member Data Documentation

◆ _adjacency_matrix

std::unique_ptr<DenseMatrix<Real> > PolycrystalUserObjectBase::_adjacency_matrix
protectedinherited

◆ _all_boundary_entity_ids

std::unordered_set<dof_id_type> FeatureFloodCount::_all_boundary_entity_ids
protectedinherited

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

Definition at line 711 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::meshChanged().

◆ _bnd_elem_range

ConstBndElemRange* FeatureFloodCount::_bnd_elem_range
protectedinherited

Boundary element range pointer.

Definition at line 729 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::execute(), and FeatureFloodCount::isBoundaryEntity().

◆ _coloring_algorithm

const MooseEnum PolycrystalUserObjectBase::_coloring_algorithm
protectedinherited

The selected graph coloring algorithm used by this object.

Definition at line 153 of file PolycrystalUserObjectBase.h.

Referenced by PolycrystalUserObjectBase::assignOpsToGrains().

◆ _colors_assigned

bool PolycrystalUserObjectBase::_colors_assigned
protectedinherited

A Boolean indicating whether the object has assigned colors to grains (internal use)

Definition at line 156 of file PolycrystalUserObjectBase.h.

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

◆ _comm_and_merge

const PerfID FeatureFloodCount::_comm_and_merge
privateinherited

Definition at line 775 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::communicateAndMerge().

◆ _compute_halo_maps

const bool FeatureFloodCount::_compute_halo_maps
protectedinherited

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

Definition at line 604 of file FeatureFloodCount.h.

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

◆ _compute_var_to_feature_map

const bool FeatureFloodCount::_compute_var_to_feature_map
protectedinherited

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

Definition at line 607 of file FeatureFloodCount.h.

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

◆ _condense_map_info

const bool FeatureFloodCount::_condense_map_info
protectedinherited

◆ _connecting_threshold

const Real FeatureFloodCount::_connecting_threshold
protectedinherited

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

Definition at line 577 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::initialize().

◆ _consolidate_merged_features

const PerfID FeatureFloodCount::_consolidate_merged_features
privateinherited

Definition at line 779 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::consolidateMergedFeatures().

◆ _dim

const unsigned int PolycrystalUserObjectBase::_dim
protectedinherited

◆ _distribute_merge_work

const bool FeatureFloodCount::_distribute_merge_work
privateinherited

Keeps track of whether we are distributing the merge work.

Definition at line 769 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::communicateAndMerge().

◆ _dof_map

const DofMap& FeatureFloodCount::_dof_map
protectedinherited

Reference to the dof_map containing the coupled variables.

Definition at line 569 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::flood().

◆ _ebsd_reader

const EBSDReader& PolycrystalEBSD::_ebsd_reader
protected

Definition at line 34 of file PolycrystalEBSD.h.

Referenced by getGrainsBasedOnPoint(), getNodalVariableValue(), and getNumGrains().

◆ _element_average_value

const PostprocessorValue& FeatureFloodCount::_element_average_value
protectedinherited

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

Definition at line 692 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::initialize().

◆ _empty_var_to_features

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

◆ _entities_visited

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

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 631 of file FeatureFloodCount.h.

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

◆ _entity_queue

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

The data structure for maintaining entities to flood during discovery.

Definition at line 766 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::flood(), and FeatureFloodCount::visitNeighborsHelper().

◆ _entity_to_grain_cache

std::map<dof_id_type, std::vector<unsigned int> > PolycrystalUserObjectBase::_entity_to_grain_cache
privateinherited

◆ _entity_var_to_features

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

◆ _execute_timer

const PerfID PolycrystalUserObjectBase::_execute_timer
privateinherited

Timers.

Definition at line 174 of file PolycrystalUserObjectBase.h.

Referenced by PolycrystalUserObjectBase::execute().

◆ _expand_halos

const PerfID FeatureFloodCount::_expand_halos
privateinherited

Definition at line 776 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::expandEdgeHalos().

◆ _fe_vars

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

The vector of coupled in variables.

Definition at line 564 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::FeatureFloodCount(), and FeatureFloodCount::getFECoupledVars().

◆ _feature_count

unsigned int FeatureFloodCount::_feature_count
protectedinherited

◆ _feature_counts_per_map

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

The number of features seen by this object per map.

Definition at line 645 of file FeatureFloodCount.h.

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

◆ _feature_id_to_local_index

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

◆ _feature_maps

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

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 678 of file FeatureFloodCount.h.

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

◆ _feature_sets

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

The data structure used to hold the globally unique features.

The sorting of the vector is implementation defined and may not correspond to anything useful. The ID of each feature should be queried from the FeatureData objects.

Definition at line 662 of file FeatureFloodCount.h.

Referenced by GrainTracker::assignGrains(), GrainTracker::attemptGrainRenumber(), GrainTracker::broadcastAndUpdateGrainData(), FeatureFloodCount::buildFeatureIdToLocalIndices(), PolycrystalUserObjectBase::buildGrainAdjacencyMatrix(), FeatureFloodCount::buildLocalToGlobalIndices(), GrainTracker::communicateHaloMap(), GrainTracker::computeMinDistancesFromGrain(), FeatureFloodCount::consolidateMergedFeatures(), FeatureFloodCount::doesFeatureIntersectBoundary(), GrainTracker::doesFeatureIntersectBoundary(), FeatureFloodCount::doesFeatureIntersectSpecifiedBoundary(), GrainTracker::doesFeatureIntersectSpecifiedBoundary(), FeatureFloodCount::featureCentroid(), PolycrystalUserObjectBase::finalize(), FeatureFloodCount::getEntityValue(), FeatureFloodCount::getFeatures(), FeatureFloodCount::getFeatureVar(), GrainTracker::getGrainCentroid(), GrainTracker::initialize(), FeatureFloodCount::initialize(), GrainTracker::isFeaturePercolated(), FeatureFloodCount::isFeaturePercolated(), GrainTracker::newGrainCreated(), GrainTracker::prepopulateState(), GrainTracker::remapGrains(), FeatureFloodCount::scatterAndUpdateRanks(), FeatureFloodCount::sortAndLabel(), GrainTracker::trackGrains(), GrainTracker::updateFieldInfo(), and FeatureFloodCount::updateFieldInfo().

◆ _finalize_timer

const PerfID PolycrystalUserObjectBase::_finalize_timer
privateinherited

Definition at line 175 of file PolycrystalUserObjectBase.h.

Referenced by PolycrystalUserObjectBase::finalize().

◆ _ghosted_entity_ids

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

The map for holding reconstructed ghosted element information.

Definition at line 695 of file FeatureFloodCount.h.

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

◆ _global_numbering

const bool FeatureFloodCount::_global_numbering
protectedinherited

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

Definition at line 597 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::updateFieldInfo().

◆ _grain_to_op

std::vector<unsigned int> PolycrystalUserObjectBase::_grain_to_op
protectedinherited

◆ _halo_ids

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

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 701 of file FeatureFloodCount.h.

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

◆ _is_boundary_restricted

bool FeatureFloodCount::_is_boundary_restricted
protectedinherited

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

Definition at line 726 of file FeatureFloodCount.h.

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

◆ _is_elemental

const bool FeatureFloodCount::_is_elemental
protectedinherited

◆ _is_master

const bool FeatureFloodCount::_is_master
protectedinherited

◆ _local_to_global_feature_map

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

The vector recording the local to global feature indices.

Definition at line 681 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::scatterAndUpdateRanks().

◆ _maps_size

const std::size_t FeatureFloodCount::_maps_size
protectedinherited

◆ _merge_timer

const PerfID FeatureFloodCount::_merge_timer
privateinherited

Definition at line 773 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::mergeSets().

◆ _mesh

MooseMesh& FeatureFloodCount::_mesh
protectedinherited

◆ _n_procs

const processor_id_type FeatureFloodCount::_n_procs
protectedinherited

Convenience variable holding the number of processors in this simulation.

Definition at line 623 of file FeatureFloodCount.h.

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

◆ _n_vars

const std::size_t FeatureFloodCount::_n_vars
protectedinherited

◆ _node_to_grain_weight_map

const std::map<dof_id_type, std::vector<Real> >& PolycrystalEBSD::_node_to_grain_weight_map
protected

Definition at line 35 of file PolycrystalEBSD.h.

Referenced by getNodalVariableValue().

◆ _nodes_to_elem_map

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

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

Definition at line 642 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::meshChanged(), and FeatureFloodCount::visitNodalNeighbors().

◆ _op_num

const unsigned int PolycrystalUserObjectBase::_op_num
protectedinherited

The maximum number of order parameters (colors) available to assign to the grain structure.

Definition at line 147 of file PolycrystalUserObjectBase.h.

Referenced by PolycrystalUserObjectBase::colorGraph(), and PolycrystalUserObjectBase::initialSetup().

◆ _output_adjacency_matrix

const bool PolycrystalUserObjectBase::_output_adjacency_matrix
protectedinherited

A user controllable Boolean which can be used to print the adjacency matrix to the console.

Definition at line 159 of file PolycrystalUserObjectBase.h.

Referenced by PolycrystalUserObjectBase::finalize().

◆ _partial_feature_sets

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

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 655 of file FeatureFloodCount.h.

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

◆ _pbs

PeriodicBoundaries* FeatureFloodCount::_pbs
protectedinherited

◆ _periodic_node_map

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

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 707 of file FeatureFloodCount.h.

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

◆ _phase

const unsigned int PolycrystalEBSD::_phase
protected

Definition at line 33 of file PolycrystalEBSD.h.

Referenced by getGrainsBasedOnPoint(), getNodalVariableValue(), and getNumGrains().

◆ _point_locator

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

◆ _prealloc_tmp_grains

std::vector<unsigned int> PolycrystalUserObjectBase::_prealloc_tmp_grains
privateinherited

Temporary storage area for current grains at a point to avoid memory churn.

Definition at line 169 of file PolycrystalUserObjectBase.h.

◆ _prepare_for_transfer

const PerfID FeatureFloodCount::_prepare_for_transfer
privateinherited

Definition at line 778 of file FeatureFloodCount.h.

Referenced by FeatureFloodCount::prepareDataForTransfer().

◆ _primary_perc_bnds

std::vector<BoundaryID> FeatureFloodCount::_primary_perc_bnds
protectedinherited

◆ _secondary_perc_bnds

std::vector<BoundaryID> FeatureFloodCount::_secondary_perc_bnds
protectedinherited

◆ _single_map_mode

const bool FeatureFloodCount::_single_map_mode
protectedinherited

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

Definition at line 591 of file FeatureFloodCount.h.

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

◆ _specified_bnds

std::vector<BoundaryID> FeatureFloodCount::_specified_bnds
protectedinherited

◆ _step_connecting_threshold

Real FeatureFloodCount::_step_connecting_threshold
protectedinherited

◆ _step_threshold

Real FeatureFloodCount::_step_threshold
protectedinherited

◆ _threshold

const Real FeatureFloodCount::_threshold
protectedinherited

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

Definition at line 572 of file FeatureFloodCount.h.

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

◆ _update_field_info

const PerfID FeatureFloodCount::_update_field_info
privateinherited

Definition at line 777 of file FeatureFloodCount.h.

◆ _use_less_than_threshold_comparison

const bool FeatureFloodCount::_use_less_than_threshold_comparison
protectedinherited

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 614 of file FeatureFloodCount.h.

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

◆ _var_index_maps

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

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 639 of file FeatureFloodCount.h.

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

◆ _var_index_mode

const bool FeatureFloodCount::_var_index_mode
protectedinherited

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 601 of file FeatureFloodCount.h.

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

◆ _var_number

unsigned long FeatureFloodCount::_var_number
protectedinherited

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 588 of file FeatureFloodCount.h.

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

◆ _vars

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

◆ _volatile_feature_sets

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

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 671 of file FeatureFloodCount.h.

◆ HALO_THICKNESS

const unsigned int PolycrystalUserObjectBase::HALO_THICKNESS = 4
staticprotectedinherited

Used to hold the thickness of the halo that should be constructed for detecting adjacency.

Definition at line 165 of file PolycrystalUserObjectBase.h.

◆ INVALID_COLOR

const unsigned int PolycrystalUserObjectBase::INVALID_COLOR
staticprotectedinherited
Initial value:
=
std::numeric_limits<unsigned int>::max()

Used to indicate an invalid coloring for the built-in back-tracking algorithm.

Definition at line 162 of file PolycrystalUserObjectBase.h.

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

◆ invalid_id

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

◆ invalid_size_t

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

The documentation for this class was generated from the following files:
FeatureFloodCount::expandEdgeHalos
void expandEdgeHalos(unsigned int num_layers_to_expand)
This method expands the existing halo set by some width determined by the passed in value.
Definition: FeatureFloodCount.C:1527
FeatureFloodCount::_var_index_mode
const bool _var_index_mode
This variable is used to indicate whether the maps will contain unique region information or just the...
Definition: FeatureFloodCount.h:601
FeatureFloodCount::_condense_map_info
const bool _condense_map_info
Definition: FeatureFloodCount.h:593
FeatureFloodCount::_secondary_perc_bnds
std::vector< BoundaryID > _secondary_perc_bnds
Definition: FeatureFloodCount.h:718
FeatureFloodCount::FieldType::UNIQUE_REGION
PolycrystalUserObjectBase::areFeaturesMergeable
virtual bool areFeaturesMergeable(const FeatureData &f1, const FeatureData &f2) const override
Method for determining whether two features are mergeable.
Definition: PolycrystalUserObjectBase.C:380
FeatureFloodCount::invalid_size_t
static const std::size_t invalid_size_t
Definition: FeatureFloodCount.h:93
FeatureFloodCount::_mesh
MooseMesh & _mesh
A reference to the mesh.
Definition: FeatureFloodCount.h:581
FeatureFloodCount::prepareDataForTransfer
void prepareDataForTransfer()
This routine uses the local flooded data to build up the local feature data structures (_feature_sets...
Definition: FeatureFloodCount.C:1017
FeatureFloodCount::BoundaryIntersection::SECONDARY_PERCOLATION_BOUNDARY
PolycrystalEBSD::getNumGrains
virtual unsigned int getNumGrains() const override
Must be overridden by the deriving class to provide the number of grains in the polycrystal structure...
Definition: PolycrystalEBSD.C:56
FeatureFloodCount::FeatureData::container_type
std::set< dof_id_type > container_type
The primary underlying container type used to hold the data in each FeatureData.
Definition: FeatureFloodCount.h:149
FeatureFloodCount::FieldType::CENTROID
FeatureFloodCount::_comm_and_merge
const PerfID _comm_and_merge
Definition: FeatureFloodCount.h:775
FeatureFloodCount::Status
Status
This enumeration is used to indicate status of the grains in the _unique_grains data structure.
Definition: FeatureFloodCount.h:120
FeatureFloodCount::_entities_visited
std::vector< std::set< dof_id_type > > _entities_visited
This variable keeps track of which nodes have been visited during execution.
Definition: FeatureFloodCount.h:631
EBSDReader::getGlobalID
virtual unsigned int getGlobalID(unsigned int phase, unsigned int local_id) const
Return the (global) grain id for a given phase and (local) grain number.
Definition: EBSDReader.h:95
PolycrystalUserObjectBase::_grain_to_op
std::vector< unsigned int > _grain_to_op
A vector indicating which op is assigned to each grain.
Definition: PolycrystalUserObjectBase.h:150
FeatureFloodCount::isBoundaryEntity
bool isBoundaryEntity(const T *entity) const
Returns a Boolean indicating whether the entity is on one of the desired boundaries.
Definition: FeatureFloodCount.C:1810
FeatureFloodCount::FieldType::GHOSTED_ENTITIES
FeatureFloodCount::visitNodalNeighbors
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...
Definition: FeatureFloodCount.C:1653
FeatureFloodCount::_is_master
const bool _is_master
Convenience variable for testing master rank.
Definition: FeatureFloodCount.h:732
PolycrystalUserObjectBase::_op_num
const unsigned int _op_num
The maximum number of order parameters (colors) available to assign to the grain structure.
Definition: PolycrystalUserObjectBase.h:147
PolycrystalUserObjectBase::colorGraph
bool colorGraph(unsigned int vertex)
Built-in simple "back-tracking" algorithm to assign colors to a graph.
Definition: PolycrystalUserObjectBase.C:460
PolycrystalEBSD::_node_to_grain_weight_map
const std::map< dof_id_type, std::vector< Real > > & _node_to_grain_weight_map
Definition: PolycrystalEBSD.h:35
FeatureFloodCount::buildLocalToGlobalIndices
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 ...
Definition: FeatureFloodCount.C:619
FeatureFloodCount::_specified_bnds
std::vector< BoundaryID > _specified_bnds
Definition: FeatureFloodCount.h:720
FeatureFloodCount::initialize
virtual void initialize() override
Definition: FeatureFloodCount.C:298
FeatureFloodCount::Status::CLEAR
FeatureFloodCount::BoundaryIntersection::SPECIFIED_BOUNDARY
PolycrystalUserObjectBase::PolycrystalUserObjectBase
PolycrystalUserObjectBase(const InputParameters &parameters)
Definition: PolycrystalUserObjectBase.C:69
dataLoad
void dataLoad(std::istream &stream, FeatureFloodCount::FeatureData &feature, void *context)
Definition: FeatureFloodCount.C:64
FeatureFloodCount::consolidateMergedFeatures
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...
Definition: FeatureFloodCount.C:1176
FeatureFloodCount::sort
static void sort(std::set< T > &)
Definition: FeatureFloodCount.h:736
FeatureFloodCount::appendPeriodicNeighborNodes
void appendPeriodicNeighborNodes(FeatureData &feature) const
This routine adds the periodic node information to our data structure prior to packing the data this ...
Definition: FeatureFloodCount.C:1771
FeatureFloodCount::finalize
virtual void finalize() override
Definition: FeatureFloodCount.C:681
EBSDReader::getNodeToGrainWeightMap
const std::map< dof_id_type, std::vector< Real > > & getNodeToGrainWeightMap() const
Returns a map consisting of the node index followd by a vector of all grain weights for that node.
Definition: EBSDReader.C:432
FeatureFloodCount::_step_connecting_threshold
Real _step_connecting_threshold
Definition: FeatureFloodCount.h:578
PolycrystalEBSD::_ebsd_reader
const EBSDReader & _ebsd_reader
Definition: PolycrystalEBSD.h:34
PolycrystalEBSD::getGrainsBasedOnPoint
virtual void getGrainsBasedOnPoint(const Point &point, std::vector< unsigned int > &grains) const override
Method for retrieving active grain IDs based on some point in the mesh.
Definition: PolycrystalEBSD.C:35
PolycrystalUserObjectBase::_entity_to_grain_cache
std::map< dof_id_type, std::vector< unsigned int > > _entity_to_grain_cache
Definition: PolycrystalUserObjectBase.h:171
PolycrystalUserObjectBase::assignOpsToGrains
void assignOpsToGrains()
Method that runs a coloring algorithm to assign OPs to grains.
Definition: PolycrystalUserObjectBase.C:413
FeatureFloodCount::_consolidate_merged_features
const PerfID _consolidate_merged_features
Definition: FeatureFloodCount.h:779
PolycrystalUserObjectBase::_finalize_timer
const PerfID _finalize_timer
Definition: PolycrystalUserObjectBase.h:175
PolycrystalUserObjectBase::_output_adjacency_matrix
const bool _output_adjacency_matrix
A user controllable Boolean which can be used to print the adjacency matrix to the console.
Definition: PolycrystalUserObjectBase.h:159
EBSDReader::getGrainNum
virtual unsigned int getGrainNum() const
Return the total number of grains.
Definition: EBSDReader.C:369
FeatureFloodCount::visitNeighborsHelper
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.
Definition: FeatureFloodCount.C:1667
FeatureFloodCount::_var_number
unsigned long _var_number
This variable is used to build the periodic node map.
Definition: FeatureFloodCount.h:588
PolycrystalUserObjectBase::getNumGrains
virtual unsigned int getNumGrains() const =0
Must be overridden by the deriving class to provide the number of grains in the polycrystal structure...
PolycrystalEBSD::_phase
const unsigned int _phase
Definition: PolycrystalEBSD.h:33
FeatureFloodCount::_feature_sets
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
Definition: FeatureFloodCount.h:662
PolycrystalUserObjectBase::_execute_timer
const PerfID _execute_timer
Timers.
Definition: PolycrystalUserObjectBase.h:174
FeatureFloodCount::_entity_var_to_features
std::map< dof_id_type, std::vector< unsigned int > > _entity_var_to_features
Definition: FeatureFloodCount.h:713
FeatureFloodCount::_global_numbering
const bool _global_numbering
This variable is used to indicate whether or not we identify features with unique numbers on multiple...
Definition: FeatureFloodCount.h:597
PolycrystalUserObjectBase::buildGrainAdjacencyMatrix
void buildGrainAdjacencyMatrix()
Builds a dense adjacency matrix based on the discovery of grain neighbors and halos surrounding each ...
Definition: PolycrystalUserObjectBase.C:391
FeatureFloodCount::_nodes_to_elem_map
std::vector< std::vector< const Elem * > > _nodes_to_elem_map
The data structure used to find neighboring elements give a node ID.
Definition: FeatureFloodCount.h:642
FeatureFloodCount::_single_map_mode
const bool _single_map_mode
This variable is used to indicate whether or not multiple maps are used during flooding.
Definition: FeatureFloodCount.h:591
PolycrystalUserObjectBase::getGrainsBasedOnElem
virtual void getGrainsBasedOnElem(const Elem &elem, std::vector< unsigned int > &grains) const
This method may be defined in addition to the point based initialization to speed up lookups.
Definition: PolycrystalUserObjectBase.h:52
FeatureFloodCount::_point_locator
std::unique_ptr< PointLocatorBase > _point_locator
Definition: FeatureFloodCount.h:689
FeatureFloodCount::_use_less_than_threshold_comparison
const bool _use_less_than_threshold_comparison
Use less-than when comparing values against the threshold value.
Definition: FeatureFloodCount.h:614
FeatureFloodCount::_ghosted_entity_ids
std::map< dof_id_type, int > _ghosted_entity_ids
The map for holding reconstructed ghosted element information.
Definition: FeatureFloodCount.h:695
FeatureFloodCount::_maps_size
const std::size_t _maps_size
Convenience variable holding the size of all the datastructures size by the number of maps.
Definition: FeatureFloodCount.h:620
FeatureFloodCount::_partial_feature_sets
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
Definition: FeatureFloodCount.h:655
FeatureFloodCount::_dof_map
const DofMap & _dof_map
Reference to the dof_map containing the coupled variables.
Definition: FeatureFloodCount.h:569
FeatureFloodCount::_fe_vars
std::vector< MooseVariableFEBase * > _fe_vars
The vector of coupled in variables.
Definition: FeatureFloodCount.h:564
FeatureFloodCount::_is_elemental
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
Definition: FeatureFloodCount.h:723
PolycrystalUserObjectBase::precomputeGrainStructure
virtual void precomputeGrainStructure()
This callback is triggered after the object is initialized and may be optionally overridden to do pre...
Definition: PolycrystalUserObjectBase.h:36
updateBBoxExtremesHelper
void updateBBoxExtremesHelper(BoundingBox &bbox, const Point &node)
Definition: FeatureFloodCount.C:2205
FeatureFloodCount::_empty_var_to_features
std::vector< unsigned int > _empty_var_to_features
Definition: FeatureFloodCount.h:715
FeatureFloodCount::visitElementalNeighbors
void visitElementalNeighbors(const Elem *elem, FeatureData *feature, bool expand_halos_only, bool disjoint_only)
Definition: FeatureFloodCount.C:1584
PolycrystalUserObjectBase::_coloring_algorithm
const MooseEnum _coloring_algorithm
The selected graph coloring algorithm used by this object.
Definition: PolycrystalUserObjectBase.h:153
FeatureFloodCount::_vars
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
Definition: FeatureFloodCount.h:566
FeatureFloodCount::_halo_ids
std::vector< std::map< dof_id_type, int > > _halo_ids
The data structure for looking up halos around features.
Definition: FeatureFloodCount.h:701
EBSDAccessFunctors::EBSDPointData::_feature_id
unsigned int _feature_id
EBSD feature id, (gklobal) grain number, symmetry, and phase data.
Definition: EBSDAccessFunctors.h:39
FeatureFloodCount::invalid_id
static const unsigned int invalid_id
Definition: FeatureFloodCount.h:94
FeatureFloodCount::mergeSets
virtual void mergeSets()
This routine is called on the master rank only and stitches together the partial feature pieces seen ...
Definition: FeatureFloodCount.C:1121
PolycrystalUserObjectBase::printGrainAdjacencyMatrix
void printGrainAdjacencyMatrix() const
Prints out the adjacency matrix in a nicely spaced integer format.
Definition: PolycrystalUserObjectBase.C:499
FeatureFloodCount::_pbs
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
Definition: FeatureFloodCount.h:687
FeatureFloodCount::clearDataStructures
virtual void clearDataStructures()
Helper routine for clearing up data structures during initialize and prior to parallel communication.
Definition: FeatureFloodCount.C:330
EBSDAccessFunctors::EBSDPointData
Per element EBSD data point.
Definition: EBSDAccessFunctors.h:27
FeatureFloodCount::Status::INACTIVE
FeatureFloodCount::_feature_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.
Definition: FeatureFloodCount.h:678
PolycrystalUserObjectBase::_adjacency_matrix
std::unique_ptr< DenseMatrix< Real > > _adjacency_matrix
The dense adjacency matrix.
Definition: PolycrystalUserObjectBase.h:141
FeatureFloodCount::initialSetup
virtual void initialSetup() override
Definition: FeatureFloodCount.C:277
PolycrystalUserObjectBase::INVALID_COLOR
static const unsigned int INVALID_COLOR
Used to indicate an invalid coloring for the built-in back-tracking algorithm.
Definition: PolycrystalUserObjectBase.h:162
EBSDReader::getAvgData
const EBSDAvgData & getAvgData(unsigned int i) const
Get the requested type of average data for (global) grain number i.
Definition: EBSDReader.C:351
PolycrystalUserObjectBase::_dim
const unsigned int _dim
mesh dimension
Definition: PolycrystalUserObjectBase.h:144
FeatureFloodCount::deserialize
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...
Definition: FeatureFloodCount.C:1086
PolycrystalUserObjectBase::isGraphValid
bool isGraphValid(unsigned int vertex, unsigned int color)
Helper method for the back-tracking graph coloring algorithm.
Definition: PolycrystalUserObjectBase.C:489
FeatureFloodCount::_feature_id_to_local_index
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)
Definition: FeatureFloodCount.h:684
FeatureFloodCount::_distribute_merge_work
const bool _distribute_merge_work
Keeps track of whether we are distributing the merge work.
Definition: FeatureFloodCount.h:769
FeatureFloodCount::_compute_halo_maps
const bool _compute_halo_maps
Indicates whether or not to communicate halo map information with all ranks.
Definition: FeatureFloodCount.h:604
FeatureFloodCount::BoundaryIntersection::ANY_BOUNDARY
EBSDReader::getData
const EBSDPointData & getData(const Point &p) const
Get the requested type of data at the point p.
Definition: EBSDReader.C:345
FeatureFloodCount::flood
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.
Definition: FeatureFloodCount.C:1294
FeatureFloodCount::_feature_count
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map)
Definition: FeatureFloodCount.h:648
PolycrystalUserObjectBase::_colors_assigned
bool _colors_assigned
A Boolean indicating whether the object has assigned colors to grains (internal use)
Definition: PolycrystalUserObjectBase.h:156
FeatureFloodCount::_is_boundary_restricted
bool _is_boundary_restricted
Indicates that this object should only run on one or more boundaries.
Definition: FeatureFloodCount.h:726
FeatureFloodCount::isNewFeatureOrConnectedRegion
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...
Definition: FeatureFloodCount.C:1425
FeatureFloodCount::FieldType::VARIABLE_COLORING
FeatureFloodCount::_bnd_elem_range
ConstBndElemRange * _bnd_elem_range
Boundary element range pointer.
Definition: FeatureFloodCount.h:729
FeatureFloodCount::buildFeatureIdToLocalIndices
void buildFeatureIdToLocalIndices(unsigned int max_id)
This method builds a lookup map for retrieving the right local feature (by index) given a global inde...
Definition: FeatureFloodCount.C:665
FeatureFloodCount::BoundaryIntersection::NONE
FeatureFloodCount::_entity_queue
std::deque< const DofObject * > _entity_queue
The data structure for maintaining entities to flood during discovery.
Definition: FeatureFloodCount.h:766
PolycrystalUserObjectBase::getGrainsBasedOnPoint
virtual void getGrainsBasedOnPoint(const Point &point, std::vector< unsigned int > &grains) const =0
Method for retrieving active grain IDs based on some point in the mesh.
EBSDAccessFunctors::EBSDPointData::_phase
unsigned int _phase
Definition: EBSDAccessFunctors.h:40
FeatureFloodCount::_compute_var_to_feature_map
const bool _compute_var_to_feature_map
Indicates whether or not the var to feature map is populated.
Definition: FeatureFloodCount.h:607
FeatureFloodCount::_periodic_node_map
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 ...
Definition: FeatureFloodCount.h:707
FeatureFloodCount::_all_boundary_entity_ids
std::unordered_set< dof_id_type > _all_boundary_entity_ids
The set of entities on the boundary of the domain used for determining if features intersect any boun...
Definition: FeatureFloodCount.h:711
FeatureFloodCount::_step_threshold
Real _step_threshold
Definition: FeatureFloodCount.h:573
FeatureFloodCount::_prepare_for_transfer
const PerfID _prepare_for_transfer
Definition: FeatureFloodCount.h:778
dataStore
void dataStore(std::ostream &stream, FeatureFloodCount::FeatureData &feature, void *context)
Definition: FeatureFloodCount.C:33
FeatureFloodCount::_n_procs
const processor_id_type _n_procs
Convenience variable holding the number of processors in this simulation.
Definition: FeatureFloodCount.h:623
FeatureFloodCount::_var_index_maps
std::vector< std::map< dof_id_type, int > > _var_index_maps
This map keeps track of which variables own which nodes.
Definition: FeatureFloodCount.h:639
FeatureFloodCount::_expand_halos
const PerfID _expand_halos
Definition: FeatureFloodCount.h:776
FeatureFloodCount::_n_vars
const std::size_t _n_vars
Definition: FeatureFloodCount.h:617
FeatureFloodCount::_local_to_global_feature_map
std::vector< std::size_t > _local_to_global_feature_map
The vector recording the local to global feature indices.
Definition: FeatureFloodCount.h:681
FeatureFloodCount::updateBoundaryIntersections
void updateBoundaryIntersections(FeatureData &feature) const
Update the feature's attributes to indicate boundary intersections.
Definition: FeatureFloodCount.C:1724
FeatureFloodCount::_feature_counts_per_map
std::vector< unsigned int > _feature_counts_per_map
The number of features seen by this object per map.
Definition: FeatureFloodCount.h:645
FeatureFloodCount::BoundaryIntersection::PRIMARY_PERCOLATION_BOUNDARY
FeatureFloodCount::_primary_perc_bnds
std::vector< BoundaryID > _primary_perc_bnds
Definition: FeatureFloodCount.h:717
EBSDAccessFunctors::EBSDAvgData::_local_id
unsigned int _local_id
Index in the per-phase list of global IDs.
Definition: EBSDAccessFunctors.h:61
FeatureFloodCount::FieldType::HALOS
FeatureFloodCount::serialize
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...
Definition: FeatureFloodCount.C:1067