https://mooseframework.inl.gov
Classes | Functions | Variables
PolycrystalICTools Namespace Reference

Classes

class  AdjacencyMatrix
 Simple 2D block matrix indicating graph adjacency. More...
 

Functions

std::vector< unsigned intassignPointsToVariables (const std::vector< Point > &centerpoints, const Real op_num, const MooseMesh &mesh, const MooseVariable &var)
 
unsigned int assignPointToGrain (const Point &p, const std::vector< Point > &centerpoints, const MooseMesh &mesh, const MooseVariable &var, const Real maxsize)
 
AdjacencyMatrix< RealbuildGrainAdjacencyMatrix (const std::map< dof_id_type, unsigned int > &entity_to_grain, MooseMesh &mesh, const libMesh::PeriodicBoundaries *pb, unsigned int n_grains, bool is_elemental)
 
AdjacencyMatrix< RealbuildElementalGrainAdjacencyMatrix (const std::map< dof_id_type, unsigned int > &element_to_grain, MooseMesh &mesh, const libMesh::PeriodicBoundaries *pb, unsigned int n_grains)
 
AdjacencyMatrix< RealbuildNodalGrainAdjacencyMatrix (const std::map< dof_id_type, unsigned int > &node_to_grain, MooseMesh &mesh, const libMesh::PeriodicBoundaries *pb, unsigned int n_grains)
 
std::vector< unsigned intassignOpsToGrains (AdjacencyMatrix< Real > &adjacency_matrix, unsigned int n_grains, unsigned int n_ops, const MooseEnum &coloring_algorithm)
 
MooseEnum coloringAlgorithms ()
 
std::string coloringAlgorithmDescriptions ()
 

Variables

const unsigned int HALO_THICKNESS = 4
 

Function Documentation

◆ assignOpsToGrains()

std::vector< unsigned int > PolycrystalICTools::assignOpsToGrains ( AdjacencyMatrix< Real > &  adjacency_matrix,
unsigned int  n_grains,
unsigned int  n_ops,
const MooseEnum coloring_algorithm 
)

Definition at line 322 of file PolycrystalICTools.C.

326 {
327  std::vector<unsigned int> grain_to_op(n_grains, GraphColoring::INVALID_COLOR);
328 
329  // Use a simple backtracking coloring algorithm
330  if (coloring_algorithm == "bt")
331  {
332  if (!colorGraph(adjacency_matrix, grain_to_op, n_grains, n_ops, 0))
333  mooseError(
334  "Unable to find a valid Grain to op configuration, do you have enough op variables?");
335  }
336  else // PETSc Coloring algorithms
337  {
338  const std::string & ca_str = coloring_algorithm;
339  Real * am_data = adjacency_matrix.rawDataPtr();
341  am_data, n_grains, n_ops, grain_to_op, ca_str.c_str());
342  }
343 
344  return grain_to_op;
345 }
void mooseError(Args &&... args)
const unsigned int INVALID_COLOR
bool colorGraph(const PolycrystalICTools::AdjacencyMatrix< Real > &adjacency_matrix, std::vector< unsigned int > &colors, unsigned int n_vertices, unsigned int n_ops, unsigned int vertex)
Backtracking graph coloring routines.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void colorAdjacencyMatrix(PetscScalar *adjacency_matrix, unsigned int size, unsigned int colors, std::vector< unsigned int > &vertex_colors, const char *coloring_algorithm)

◆ assignPointsToVariables()

std::vector<unsigned int> PolycrystalICTools::assignPointsToVariables ( const std::vector< Point > &  centerpoints,
const Real  op_num,
const MooseMesh mesh,
const MooseVariable var 
)

◆ assignPointToGrain()

unsigned int PolycrystalICTools::assignPointToGrain ( const Point &  p,
const std::vector< Point > &  centerpoints,
const MooseMesh mesh,
const MooseVariable var,
const Real  maxsize 
)

◆ buildElementalGrainAdjacencyMatrix()

PolycrystalICTools::AdjacencyMatrix< Real > PolycrystalICTools::buildElementalGrainAdjacencyMatrix ( const std::map< dof_id_type, unsigned int > &  element_to_grain,
MooseMesh mesh,
const libMesh::PeriodicBoundaries pb,
unsigned int  n_grains 
)

We've found a grain neighbor interface. In order to assign order parameters though, we need to make sure that we build out a small buffer region to avoid literal "corner cases" where nodes on opposite corners of a QUAD end up with the same OP because those nodes are not nodal neighbors. To do that we'll build a halo region based on these interface nodes. For now, we need to record the nodes inside of the grain and those outside of the grain.

Definition at line 150 of file PolycrystalICTools.C.

Referenced by buildGrainAdjacencyMatrix().

155 {
156  AdjacencyMatrix<Real> adjacency_matrix(n_grains);
157 
158  // We can't call this in the constructor, it appears that _mesh_ptr is always NULL there.
159  mesh.errorIfDistributedMesh("advanced_op_assignment = true");
160 
161  std::vector<const Elem *> all_active_neighbors;
162 
163  std::vector<std::set<dof_id_type>> local_ids(n_grains);
164  std::vector<std::set<dof_id_type>> halo_ids(n_grains);
165 
166  std::unique_ptr<PointLocatorBase> point_locator = mesh.getMesh().sub_point_locator();
167  for (const auto & elem : mesh.getMesh().active_element_ptr_range())
168  {
169  std::map<dof_id_type, unsigned int>::const_iterator grain_it =
170  element_to_grain.find(elem->id());
171  mooseAssert(grain_it != element_to_grain.end(), "Element not found in map");
172  unsigned int my_grain = grain_it->second;
173 
174  all_active_neighbors.clear();
175  // Loop over all neighbors (at the the same level as the current element)
176  for (unsigned int i = 0; i < elem->n_neighbors(); ++i)
177  {
178  const Elem * neighbor_ancestor = elem->topological_neighbor(i, mesh, *point_locator, pb);
179  if (neighbor_ancestor)
180  // Retrieve only the active neighbors for each side of this element, append them to the list
181  // of active neighbors
183  all_active_neighbors, elem, mesh, *point_locator, pb, false);
184  }
185 
186  // Loop over all active element neighbors
187  for (std::vector<const Elem *>::const_iterator neighbor_it = all_active_neighbors.begin();
188  neighbor_it != all_active_neighbors.end();
189  ++neighbor_it)
190  {
191  const Elem * neighbor = *neighbor_it;
192  std::map<dof_id_type, unsigned int>::const_iterator grain_it2 =
193  element_to_grain.find(neighbor->id());
194  mooseAssert(grain_it2 != element_to_grain.end(), "Element not found in map");
195  unsigned int their_grain = grain_it2->second;
196 
197  if (my_grain != their_grain)
198  {
207  // First add corresponding element and grain information
208  local_ids[my_grain].insert(elem->id());
209  local_ids[their_grain].insert(neighbor->id());
210 
211  // Now add opposing element and grain information
212  halo_ids[my_grain].insert(neighbor->id());
213  halo_ids[their_grain].insert(elem->id());
214  }
215  // adjacency_matrix[my_grain][their_grain] = 1;
216  }
217  }
218 
219  // Build up the halos
220  std::set<dof_id_type> set_difference;
221  for (unsigned int i = 0; i < n_grains; ++i)
222  {
223  std::set<dof_id_type> orig_halo_ids(halo_ids[i]);
224 
225  for (unsigned int halo_level = 0; halo_level < PolycrystalICTools::HALO_THICKNESS; ++halo_level)
226  {
227  for (std::set<dof_id_type>::iterator entity_it = orig_halo_ids.begin();
228  entity_it != orig_halo_ids.end();
229  ++entity_it)
230  {
231  if (true)
233  mesh.elemPtr(*entity_it), mesh.getMesh(), *point_locator, pb, halo_ids[i]);
234  else
235  mooseError("Unimplemented");
236  }
237 
238  set_difference.clear();
239  std::set_difference(
240  halo_ids[i].begin(),
241  halo_ids[i].end(),
242  local_ids[i].begin(),
243  local_ids[i].end(),
244  std::insert_iterator<std::set<dof_id_type>>(set_difference, set_difference.begin()));
245 
246  halo_ids[i].swap(set_difference);
247  }
248  }
249 
250  // Finally look at the halo intersections to build the connectivity graph
251  std::set<dof_id_type> set_intersection;
252  for (unsigned int i = 0; i < n_grains; ++i)
253  for (unsigned int j = i + 1; j < n_grains; ++j)
254  {
255  set_intersection.clear();
256  std::set_intersection(
257  halo_ids[i].begin(),
258  halo_ids[i].end(),
259  halo_ids[j].begin(),
260  halo_ids[j].end(),
261  std::insert_iterator<std::set<dof_id_type>>(set_intersection, set_intersection.begin()));
262 
263  if (!set_intersection.empty())
264  {
265  adjacency_matrix(i, j) = 1.;
266  adjacency_matrix(j, i) = 1.;
267  }
268  }
269 
270  return adjacency_matrix;
271 }
void active_family_tree_by_topological_neighbor(std::vector< const Elem * > &family, const Elem *neighbor, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, bool reset=true) const
const unsigned int HALO_THICKNESS
std::unique_ptr< PointLocatorBase > sub_point_locator() const
const Elem * topological_neighbor(const unsigned int i, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb) const
void mooseError(Args &&... args)
void visitElementalNeighbors(const Elem *elem, const MeshBase &mesh, const PointLocatorBase &point_locator, const PeriodicBoundaries *pb, std::set< dof_id_type > &halo_ids)
Utility routines.
MeshBase & mesh
dof_id_type id() const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ buildGrainAdjacencyMatrix()

PolycrystalICTools::AdjacencyMatrix< Real > PolycrystalICTools::buildGrainAdjacencyMatrix ( const std::map< dof_id_type, unsigned int > &  entity_to_grain,
MooseMesh mesh,
const libMesh::PeriodicBoundaries pb,
unsigned int  n_grains,
bool  is_elemental 
)

Definition at line 136 of file PolycrystalICTools.C.

142 {
143  if (is_elemental)
144  return buildElementalGrainAdjacencyMatrix(entity_to_grain, mesh, pb, n_grains);
145  else
146  return buildNodalGrainAdjacencyMatrix(entity_to_grain, mesh, pb, n_grains);
147 }
AdjacencyMatrix< Real > buildNodalGrainAdjacencyMatrix(const std::map< dof_id_type, unsigned int > &node_to_grain, MooseMesh &mesh, const libMesh::PeriodicBoundaries *pb, unsigned int n_grains)
AdjacencyMatrix< Real > buildElementalGrainAdjacencyMatrix(const std::map< dof_id_type, unsigned int > &element_to_grain, MooseMesh &mesh, const libMesh::PeriodicBoundaries *pb, unsigned int n_grains)

◆ buildNodalGrainAdjacencyMatrix()

PolycrystalICTools::AdjacencyMatrix< Real > PolycrystalICTools::buildNodalGrainAdjacencyMatrix ( const std::map< dof_id_type, unsigned int > &  node_to_grain,
MooseMesh mesh,
const libMesh::PeriodicBoundaries pb,
unsigned int  n_grains 
)

We've found a grain neighbor interface. In order to assign order parameters though, we need to make sure that we build out a small buffer region to avoid literal "corner cases" where nodes on opposite corners of a QUAD end up with the same OP because those nodes are not nodal neighbors. To do that we'll build a halo region based on these interface nodes. For now, we need to record the nodes inside of the grain and those outside of the grain.

Definition at line 274 of file PolycrystalICTools.C.

Referenced by buildGrainAdjacencyMatrix().

279 {
280  // Build node to elem map
281  std::vector<std::vector<const Elem *>> nodes_to_elem_map;
282  MeshTools::build_nodes_to_elem_map(mesh.getMesh(), nodes_to_elem_map);
283 
284  AdjacencyMatrix<Real> adjacency_matrix(n_grains);
285 
286  const auto end = mesh.getMesh().active_nodes_end();
287  for (auto nl = mesh.getMesh().active_nodes_begin(); nl != end; ++nl)
288  {
289  const Node * node = *nl;
290  std::map<dof_id_type, unsigned int>::const_iterator grain_it = node_to_grain.find(node->id());
291  mooseAssert(grain_it != node_to_grain.end(), "Node not found in map");
292  unsigned int my_grain = grain_it->second;
293 
294  std::vector<const Node *> nodal_neighbors;
295  MeshTools::find_nodal_neighbors(mesh.getMesh(), *node, nodes_to_elem_map, nodal_neighbors);
296 
297  // Loop over all nodal neighbors
298  for (unsigned int i = 0; i < nodal_neighbors.size(); ++i)
299  {
300  const Node * neighbor_node = nodal_neighbors[i];
301  std::map<dof_id_type, unsigned int>::const_iterator grain_it2 =
302  node_to_grain.find(neighbor_node->id());
303  mooseAssert(grain_it2 != node_to_grain.end(), "Node not found in map");
304  unsigned int their_grain = grain_it2->second;
305 
306  if (my_grain != their_grain)
314  adjacency_matrix(my_grain, their_grain) = 1.;
315  }
316  }
317 
318  return adjacency_matrix;
319 }
MeshBase & mesh
dof_id_type id() const

◆ coloringAlgorithmDescriptions()

std::string PolycrystalICTools::coloringAlgorithmDescriptions ( )

Definition at line 354 of file PolycrystalICTools.C.

355 {
356  return "The grain neighbor graph coloring algorithm to use. \"legacy\" is the original "
357  "algorithm "
358  "which does not guarantee a valid coloring. \"bt\" is a simple backtracking algorithm "
359  "which will produce a valid coloring but has potential exponential run time. The "
360  "remaining algorithms require PETSc but are recommended for larger problems (See "
361  "MatColoringType)";
362 }

◆ coloringAlgorithms()

MooseEnum PolycrystalICTools::coloringAlgorithms ( )

Definition at line 348 of file PolycrystalICTools.C.

349 {
350  return MooseEnum("legacy bt jp power greedy", "legacy");
351 }

Variable Documentation

◆ HALO_THICKNESS

const unsigned int PolycrystalICTools::HALO_THICKNESS = 4

Definition at line 30 of file PolycrystalICTools.C.

Referenced by buildElementalGrainAdjacencyMatrix().