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 321 of file PolycrystalICTools.C.

325 {
326  std::vector<unsigned int> grain_to_op(n_grains, GraphColoring::INVALID_COLOR);
327 
328  // Use a simple backtracking coloring algorithm
329  if (coloring_algorithm == "bt")
330  {
331  if (!colorGraph(adjacency_matrix, grain_to_op, n_grains, n_ops, 0))
332  mooseError(
333  "Unable to find a valid Grain to op configuration, do you have enough op variables?");
334  }
335  else // PETSc Coloring algorithms
336  {
337  const std::string & ca_str = coloring_algorithm;
338  Real * am_data = adjacency_matrix.rawDataPtr();
340  am_data, n_grains, n_ops, grain_to_op, ca_str.c_str());
341  }
342 
343  return grain_to_op;
344 }
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 149 of file PolycrystalICTools.C.

Referenced by buildGrainAdjacencyMatrix().

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

141 {
142  if (is_elemental)
143  return buildElementalGrainAdjacencyMatrix(entity_to_grain, mesh, pb, n_grains);
144  else
145  return buildNodalGrainAdjacencyMatrix(entity_to_grain, mesh, pb, n_grains);
146 }
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 273 of file PolycrystalICTools.C.

Referenced by buildGrainAdjacencyMatrix().

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

◆ coloringAlgorithmDescriptions()

std::string PolycrystalICTools::coloringAlgorithmDescriptions ( )

Definition at line 353 of file PolycrystalICTools.C.

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

◆ coloringAlgorithms()

MooseEnum PolycrystalICTools::coloringAlgorithms ( )

Definition at line 347 of file PolycrystalICTools.C.

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

Variable Documentation

◆ HALO_THICKNESS

const unsigned int PolycrystalICTools::HALO_THICKNESS = 4

Definition at line 30 of file PolycrystalICTools.C.

Referenced by buildElementalGrainAdjacencyMatrix().