Go to the documentation of this file.
11 #include "NonlinearSystemBase.h"
12 #include "MooseMesh.h"
13 #include "MooseVariable.h"
14 #include "TimedPrint.h"
16 #include "libmesh/dense_matrix.h"
27 params.addClassDescription(
"This object provides the base capability for creating proper reduced "
28 "order parameter polycrystal initial conditions.");
29 params.addRequiredCoupledVarWithAutoBuild(
30 "variable",
"var_name_base",
"op_num",
"Array of coupled variables");
31 params.addParam<
bool>(
"output_adjacency_matrix",
33 "Output the Grain Adjacency Matrix used in the coloring algorithms. "
34 "Additionally, the grain to OP assignments will be printed");
35 params.addParam<MooseEnum>(
"coloring_algorithm",
40 params.clearRelationshipManagers();
42 params.addRelationshipManager(
43 "ElementSideNeighborLayers",
44 Moose::RelationshipManagerType::GEOMETRIC,
46 [](
const InputParameters & , InputParameters & rm_params) {
47 rm_params.set<
unsigned short>(
"layers") = 2;
52 params.addRelationshipManager(
"ElementSideNeighborLayers",
53 Moose::RelationshipManagerType::ALGEBRAIC);
56 params.set<std::vector<OutputName>>(
"outputs") = {
"none"};
59 params.set<
bool>(
"allow_duplicate_execution_on_initial") =
true;
62 ExecFlagEnum execute_options = MooseUtils::getDefaultExecFlagEnum();
63 execute_options = EXEC_INITIAL;
64 params.set<ExecFlagEnum>(
"execute_on") = execute_options;
71 _dim(_mesh.dimension()),
72 _op_num(_vars.size()),
73 _coloring_algorithm(getParam<MooseEnum>(
"coloring_algorithm")),
74 _colors_assigned(false),
75 _output_adjacency_matrix(getParam<bool>(
"output_adjacency_matrix")),
76 _execute_timer(registerTimedSection(
"execute", 1)),
77 _finalize_timer(registerTimedSection(
"finalize", 1))
79 mooseAssert(
_single_map_mode,
"Do not turn off single_map_mode with this class");
90 mooseError(
"No coupled variables found");
92 for (
unsigned int dim = 0; dim <
_dim; ++dim)
94 bool first_variable_value =
_mesh.isTranslatedPeriodic(
_vars[0]->number(), dim);
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");
121 else if (!_fe_problem.hasInitialAdaptivity())
125 CONSOLE_TIMED_PRINT(
"Computing Polycrystal Initial Condition");
145 for (
const auto & current_elem : _fe_problem.getEvaluableElementRange())
153 auto n_nodes = current_elem->n_vertices();
154 for (
auto i = decltype(n_nodes)(0); i < n_nodes; ++i)
156 const Node * current_node = current_elem->node_ptr(i);
172 CONSOLE_TIMED_PRINT(
"Finalizing Polycrystal Initial Condition");
175 constexpr
unsigned int halo_thickness = 2;
221 while (it1 != it_end)
229 it1->merge(std::move(*it2));
239 std::size_t & current_index,
242 unsigned int & new_id)
244 mooseAssert(_t_step == 0,
"PolyIC only works if we begin in the initial condition");
247 auto entity_id = dof_object->id();
252 std::vector<unsigned int> grain_ids;
274 for (
auto grain_id : grains_it->second)
280 saved_grain_id = grain_id;
283 current_index = grain_id;
300 new_id = saved_grain_id;
301 status &= ~
Status::INACTIVE;
307 const auto & grain_ids = grains_it->second;
308 if (std::find(grain_ids.begin(), grain_ids.end(), feature->
_id) != grain_ids.end())
318 Elem * elem =
_mesh.queryElemPtr(entity_id);
319 mooseAssert(elem,
"Element is nullptr");
321 std::vector<const Elem *> all_active_neighbors;
322 MeshBase & mesh =
_mesh.getMesh();
324 for (
auto i = decltype(elem->n_neighbors())(0); i < elem->n_neighbors(); ++i)
326 const Elem * neighbor_ancestor =
nullptr;
332 neighbor_ancestor = elem->neighbor_ptr(i);
333 if (neighbor_ancestor)
334 neighbor_ancestor->active_family_tree_by_neighbor(all_active_neighbors, elem,
false);
346 if (neighbor_ancestor)
347 neighbor_ancestor->active_family_tree_by_topological_neighbor(
352 for (
const auto neighbor : all_active_neighbors)
355 auto neighbor_id = neighbor->id();
360 std::vector<unsigned int> more_grain_ids;
365 neighbor_it, neighbor_id, std::move(more_grain_ids));
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())
393 mooseAssert(
_is_master,
"This routine should only be called on the master rank");
400 if (&grain1 == &grain2)
403 if (grain1.boundingBoxesIntersect(grain2) && grain1.halosIntersect(grain2))
405 (*_adjacency_matrix)(grain1._id, grain2._id) = 1.;
406 (*_adjacency_matrix)(grain1._id, grain2._id) = 1.;
415 mooseAssert(
_is_master,
"This routine should only be called on the master rank");
417 Moose::perf_log.push(
"assignOpsToGrains()",
"PolycrystalICTools");
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\".");
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)?");
435 #ifdef LIBMESH_HAVE_PETSC
441 Moose::PetscSupport::colorAdjacencyMatrix(
444 catch (std::runtime_error & e)
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)?");
452 mooseError(
"Selected coloring algorithm requires PETSc");
456 Moose::perf_log.pop(
"assignOpsToGrains()",
"PolycrystalICTools");
467 for (
unsigned int color_idx = 0; color_idx <
_op_num; ++color_idx)
471 unsigned int color = (vertex + color_idx) %
_op_num;
492 for (
unsigned int neighbor = 0; neighbor <
_feature_count; ++neighbor)
501 _console <<
"Grain Adjacency Matrix:\n";
509 _console <<
"Grain to OP assignments:\n";
511 _console << op <<
" ";
512 _console <<
'\n' << std::endl;
518 return MooseEnum(
"jp power greedy bt",
"jp");
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)";
533 std::numeric_limits<unsigned int>::max();
void expandEdgeHalos(unsigned int num_layers_to_expand)
This method expands the existing halo set by some width determined by the passed in value.
InputParameters validParams< FeatureFloodCount >()
InputParameters validParams< PolycrystalUserObjectBase >()
virtual bool areFeaturesMergeable(const FeatureData &f1, const FeatureData &f2) const override
Method for determining whether two features are mergeable.
static const std::size_t invalid_size_t
MooseMesh & _mesh
A reference to the mesh.
virtual bool isNewFeatureOrConnectedRegion(const DofObject *dof_object, std::size_t ¤t_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...
unsigned int _id
An ID for this feature.
virtual void mergeSets() override
This routine is called on the master rank only and stitches together the partial feature pieces seen ...
virtual void finalize() override
virtual void initialize() override
virtual void execute() override
static MooseEnum coloringAlgorithms()
Returns all available coloring algorithms as an enumeration type for input files.
Status
This enumeration is used to indicate status of the grains in the _unique_grains data structure.
std::vector< std::set< dof_id_type > > _entities_visited
This variable keeps track of which nodes have been visited during execution.
std::vector< unsigned int > _grain_to_op
A vector indicating which op is assigned to each grain.
const bool _is_master
Convenience variable for testing master rank.
const unsigned int _op_num
The maximum number of order parameters (colors) available to assign to the grain structure.
bool colorGraph(unsigned int vertex)
Built-in simple "back-tracking" algorithm to assign colors to a graph.
This object will mark nodes or elements of continuous regions all with a unique number for the purpos...
virtual void initialize() override
virtual void initialSetup() override
UserObject interface overrides.
PolycrystalUserObjectBase(const InputParameters ¶meters)
virtual void finalize() override
std::map< dof_id_type, std::vector< unsigned int > > _entity_to_grain_cache
void assignOpsToGrains()
Method that runs a coloring algorithm to assign OPs to grains.
const PerfID _finalize_timer
const bool _output_adjacency_matrix
A user controllable Boolean which can be used to print the adjacency matrix to the console.
virtual unsigned int getNumGrains() const =0
Must be overridden by the deriving class to provide the number of grains in the polycrystal structure...
std::vector< FeatureData > & _feature_sets
The data structure used to hold the globally unique features.
const PerfID _execute_timer
Timers.
void buildGrainAdjacencyMatrix()
Builds a dense adjacency matrix based on the discovery of grain neighbors and halos surrounding each ...
const bool _single_map_mode
This variable is used to indicate whether or not multiple maps are used during flooding.
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.
std::unique_ptr< PointLocatorBase > _point_locator
std::vector< std::list< FeatureData > > _partial_feature_sets
The data structure used to hold partial and communicated feature data, during the discovery and mergi...
const bool _is_elemental
Determines if the flood counter is elements or not (nodes)
virtual void precomputeGrainStructure()
This callback is triggered after the object is initialized and may be optionally overridden to do pre...
const MooseEnum _coloring_algorithm
The selected graph coloring algorithm used by this object.
std::vector< MooseVariable * > _vars
The vector of coupled in variables cast to MooseVariable.
static const unsigned int invalid_id
void printGrainAdjacencyMatrix() const
Prints out the adjacency matrix in a nicely spaced integer format.
PeriodicBoundaries * _pbs
A pointer to the periodic boundary constraints object.
std::unique_ptr< DenseMatrix< Real > > _adjacency_matrix
The dense adjacency matrix.
virtual void initialSetup() override
static const unsigned int INVALID_COLOR
Used to indicate an invalid coloring for the built-in back-tracking algorithm.
std::size_t _var_index
The Moose variable where this feature was found (often the "order parameter")
const unsigned int _dim
mesh dimension
bool isGraphValid(unsigned int vertex, unsigned int color)
Helper method for the back-tracking graph coloring algorithm.
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.
unsigned int _feature_count
The number of features seen by this object (same as summing _feature_counts_per_map)
bool _colors_assigned
A Boolean indicating whether the object has assigned colors to grains (internal use)
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.
static const unsigned int HALO_THICKNESS
Used to hold the thickness of the halo that should be constructed for detecting adjacency.
static std::string coloringAlgorithmDescriptions()
Returns corresponding descriptions of available coloring algorithms.