Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
MeshGeneratorSystem.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "MeshGeneratorSystem.h"
11 
12 #include "MooseApp.h"
13 #include "MeshGenerator.h"
14 #include "DependencyResolver.h"
15 
16 #include "libmesh/mesh_tools.h"
17 
18 using namespace libMesh;
19 
20 const std::string MeshGeneratorSystem::data_driven_generator_param = "data_driven_generator";
22  "allow_data_driven_mesh_generation";
23 
25  : PerfGraphInterface(app.perfGraph(), "MeshGeneratorSystem"),
26  ParallelObject(app),
27  _app(app),
28  _has_bmbb(false),
29  _verbose(false)
30 {
31 }
32 
33 void
34 MeshGeneratorSystem::addMeshGenerator(const std::string & type,
35  const std::string & name,
36  const InputParameters & params)
37 {
38  mooseAssert(!_mesh_generator_params.count(name), "Already exists");
39  _mesh_generator_params.emplace(
40  std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(type, params));
41 
42  // This should be a sub mesh generator. We can assume this because if we're in the middle of
43  // constructing mesh generators (not "adding" them, where we simply store their parameters)
46 
47  if (type == "BreakMeshByBlockGenerator")
48  _has_bmbb = true;
49 }
50 
51 const MeshGenerator &
53  const std::string & name,
54  InputParameters params)
55 {
57  mooseError("Can only call appendMeshGenerator() during the append_mesh_generator task");
58  const auto param_name_mg_name_pairs = getMeshGeneratorParamDependencies(params, true);
59 
60  // Make sure this mesh generator has one and _only_ one input, in the "input" parameter,
61  // Or several, listed in the "inputs" parameter
62  if ((param_name_mg_name_pairs.size() == 0) ||
63  (param_name_mg_name_pairs.size() == 1 && param_name_mg_name_pairs[0].first != "input" &&
64  param_name_mg_name_pairs[0].first != "inputs") ||
65  (param_name_mg_name_pairs.size() > 1 && param_name_mg_name_pairs[0].first != "inputs"))
66  mooseError("While adding ",
67  type,
68  " '",
69  name,
70  "' via appendMeshGenerator():\nCan only append a mesh generator that takes a "
71  "single input mesh generator via the parameter named 'input' or 'inputs'.");
72 
73  // If no final generator is set, we need to make sure that we have one; we will hit
74  // this the first time we add an appended MeshGenerator and only need to do it once.
75  // We'll then generate the final ordering within the execution phase. We'll also
76  // clear the ordering because it could be invalid if we append any more generators,
77  // and we'll be re-ordering within executeMeshgenerators() anyway (where we don't
78  // keep track of any state for the sake of simpler logic)
79  if (_final_generator_name.empty())
80  {
81  if (_mesh_generators.empty())
82  mooseError("Cannot use appendMeshGenerator() because there is not a generator to append to!");
83 
86  }
87 
88  // Set the final generator as the input if a single generator
89  mooseAssert(hasMeshGenerator(_final_generator_name), "Missing final generator");
90  if (params.have_parameter<MeshGeneratorName>("input"))
91  params.set<MeshGeneratorName>("input") = _final_generator_name;
92  // We'll trust the final combiner generator with its list of inputs
93 
94  // Keep track of the new final generator
96 
97  // Need to add this to the param map so that createMeshGenerator can use it
98  mooseAssert(!_mesh_generator_params.count(name), "Already exists");
99  _mesh_generator_params.emplace(
100  std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(type, params));
101 
102  return *createMeshGenerator(name);
103 }
104 
105 std::vector<std::pair<std::string, MeshGeneratorName>>
107  const bool allow_empty /* = false */) const
108 {
109  std::vector<std::pair<std::string, MeshGeneratorName>> dependencies;
110 
111  auto add_dependency =
112  [&dependencies, &allow_empty](const auto & param_name, const auto & dependency)
113  {
114  if (dependency.size() || allow_empty)
115  dependencies.emplace_back(param_name, dependency);
116  };
117 
118  for (const auto & [name, param] : params)
119  if (const auto dependency =
120  dynamic_cast<const Parameters::Parameter<MeshGeneratorName> *>(param.get()))
121  add_dependency(name, dependency->get());
122  else if (const auto dependencies =
123  dynamic_cast<const Parameters::Parameter<std::vector<MeshGeneratorName>> *>(
124  param.get()))
125  {
126  if (allow_empty && dependencies->get().empty())
127  add_dependency(name, std::string());
128  for (const auto & dependency : dependencies->get())
129  add_dependency(name, dependency);
130  }
131 
132  return dependencies;
133 }
134 
135 void
137 {
138  mooseAssert(_app.actionWarehouse().getCurrentTaskName() == "create_added_mesh_generators",
139  "Should not run now");
140 
141  // No generators were added via addMeshGenerator()
142  if (_mesh_generator_params.empty())
143  return;
144 
146 
147  // Define the dependencies known so far
148  for (const auto & [name, type_params_pair] : _mesh_generator_params)
149  {
150  resolver.addItem(name);
151  for (const auto & param_dependency_pair :
152  getMeshGeneratorParamDependencies(type_params_pair.second))
153  resolver.addEdge(param_dependency_pair.second, name);
154  }
155 
156  std::vector<std::vector<std::string>> ordered_generators;
157  try
158  {
159  ordered_generators = resolver.getSortedValuesSets();
160  }
162  {
163  mooseError("Cyclic dependencies detected in mesh generation: ",
165  }
166 
167  const auto & moose_mesh = _app.actionWarehouse().getMesh();
168 
169  // If there is no mesh
170  if (!moose_mesh.get())
171  mooseError("No mesh created. Either add a Mesh, an ActionComponents or a Components block");
172 
173  // If we're using data-driven generation, find that requirement now
174  mooseAssert(!_data_driven_generator_name, "Should not be set");
175  if (moose_mesh->parameters().get<bool>("_mesh_generator_mesh") &&
176  moose_mesh->isParamValid(data_driven_generator_param))
177  {
178  if (!hasDataDrivenAllowed())
179  moose_mesh->paramError(
181  "This application does not support data-driven mesh generation.\n\nThis generation is an "
182  "advanced feature and must be enabled on the application via the '",
184  "' parameter.");
185 
186  mooseAssert(moose_mesh->type() == "MeshGeneratorMesh",
187  "Assumption for mesh type is now invalid");
188 
189  _data_driven_generator_name = moose_mesh->getParam<std::string>(data_driven_generator_param);
191  moose_mesh->paramError(data_driven_generator_param,
192  "The data driven generator '",
194  "' does not exist");
195  }
196 
197  // Construct all of the mesh generators that we know exist
198  for (const auto & generator_names : ordered_generators)
199  for (const auto & generator_name : generator_names)
200  if (auto it = _mesh_generator_params.find(generator_name); it != _mesh_generator_params.end())
201  {
202  auto & params = it->second.second;
203 
204  // Determine now if we need to run this in data only mode
205  const bool data_only = _data_driven_generator_name &&
206  getDataDrivenGeneratorName() != generator_name &&
207  resolver.dependsOn(getDataDrivenGeneratorName(), generator_name);
208  params.set<bool>(MeshGenerator::data_only_param) = data_only;
209 
210  createMeshGenerator(generator_name);
211 
212  mooseAssert(data_only == getMeshGenerator(generator_name).isDataOnly(),
213  "Inconsistent data only");
214  }
215 
216  mooseAssert(_mesh_generator_params.empty(), "Should be empty");
217  mooseAssert(_final_generator_name.empty(), "Should be unset at this point");
218 
219  // Set the final generator if we have one set by the user
220  // and if so make sure it also exists
221  if (moose_mesh->parameters().get<bool>("_mesh_generator_mesh") &&
222  moose_mesh->isParamValid("final_generator"))
223  {
224  mooseAssert(moose_mesh->type() == "MeshGeneratorMesh",
225  "Assumption for mesh type is now invalid");
226 
227  _final_generator_name = moose_mesh->getParam<std::string>("final_generator");
229  moose_mesh->paramError("final_generator",
230  "The forced final MeshGenerator '",
232  "' does not exist");
233  }
234 }
235 
236 void
238 {
239  mooseAssert(_app.constructingMeshGenerators() ||
240  _app.actionWarehouse().getCurrentTaskName() == "execute_mesh_generators",
241  "Incorrect call time");
242  mooseAssert(_ordered_mesh_generators.empty(), "Already ordered");
243  mooseAssert(_mesh_generators.size(), "No mesh generators to order");
244 
245  TIME_SECTION("createMeshGeneratorOrder", 1, "Ordering Mesh Generators");
246 
247  // We dare not sort these based on address!
249 
250  // The mesh generators that must be called
251  // This is needed to mark the generators that could be cut due to a
252  // final generator being set, but should still be called because they're
253  // either being saved in memory or as output
254  std::vector<std::string> required_generators;
255  for (const auto & it : _mesh_generators)
256  if (it.second->hasSaveMesh() || it.second->hasOutput())
257  required_generators.push_back(it.second->name());
258 
259  // The mesh generator tree should have all the mesh generators that
260  // The final generator depends on and all the mesh generators
261  // with 'save in' flag. Here we loop over all the mesh generators
262  // and conditionally add all of the dependencies into the resolver
263  for (const auto & it : _mesh_generators)
264  {
265  MeshGenerator * mg = it.second.get();
266 
267  // The mesh generator has to meet one of the following conditions:
268  // Final mesh generator is not set, so we build the whole tree
269  if (_final_generator_name.empty() ||
270  // This mesh generator is the final generator
271  mg->name() == _final_generator_name ||
272  // This needs to be saved or output
273  mg->hasSaveMesh() || mg->hasOutput() ||
274  // Final mesh generator set and is a child of this generator
276  // This is a dependency of a generator that needs to be saved or output
277  std::find_if(required_generators.begin(),
278  required_generators.end(),
279  [&mg](const auto & name) { return mg->isChildMeshGenerator(name, false); }) !=
280  required_generators.end())
281  {
282  resolver.addItem(mg);
283  for (const auto & dep_mg : mg->getParentMeshGenerators())
284  resolver.addEdge(&getMeshGeneratorInternal(dep_mg->name()), mg);
285  }
286  }
287 
288  // ...and sort them
289  try
290  {
292  }
293  // It is _quite_ hard to trigger this to test it. I've tried to no avail.
294  // Now that we...
295  // - check and sort up front
296  // - know if dependencies exist at the time of requesting them
297  // - require that sub generators depend only on other sub generators in an object's
298  // tree + input dependencies that we explicitly declare
299  // I don't think it's possible. But we'll leave it here anyway and it
300  // definitely will not be covered
302  {
303  const auto & cycle = e.getCyclicDependencies();
304  std::vector<std::string> names(cycle.size());
305  for (const auto i : index_range(cycle))
306  names[i] = cycle[i]->name();
307 
308  mooseError("Cyclic dependencies detected in mesh generation: ",
309  MooseUtils::join(names, " <- "));
310  }
311 
312  mooseAssert(_ordered_mesh_generators.size(), "No mesh generators found");
313 
314  const auto & final_generators = _ordered_mesh_generators.back();
315 
316  // We haven't forced a final generator yet
317  if (_final_generator_name.empty())
318  {
319  mooseAssert(final_generators.size(), "Empty vector");
320 
321  // See if we have multiple independent trees of generators
322  const auto ancestor_list = resolver.getAncestors(final_generators.back());
323  if (ancestor_list.size() != resolver.size() && _final_generator_name.empty())
324  {
325  // Need to remove duplicates and possibly perform a difference so we'll import our list
326  // into a set for these operations.
327  std::set<MeshGenerator *, MeshGenerator::Comparator> ancestors(ancestor_list.begin(),
328  ancestor_list.end());
329  // Get all of the items from the resolver so we can compare against the tree from the
330  // final generator we just pulled.
331  const auto & allValues = resolver.getSortedValues();
332  decltype(ancestors) all(allValues.begin(), allValues.end());
333 
334  decltype(ancestors) ind_tree;
335  std::set_difference(all.begin(),
336  all.end(),
337  ancestors.begin(),
338  ancestors.end(),
339  std::inserter(ind_tree, ind_tree.end()));
340 
341  std::ostringstream oss;
342  oss << "Your MeshGenerator tree contains multiple possible generator outputs :\n\""
343  << final_generators.back()->name()
344  << "\" and one or more of the following from an independent set: \"";
345  bool first = true;
346  for (const auto & gen : ind_tree)
347  {
348  if (!first)
349  oss << ", ";
350  else
351  first = false;
352 
353  oss << gen->name();
354  }
355  oss << "\"\n\nThis may be due to a missing dependency or may be intentional. Please either\n"
356  "- check that all the mesh generators are connected as a tree and culminate in a "
357  "single final mesh. Having one wrong 'input=mg' parameter is the most common error\n"
358  "- add additional dependencies to remove the ambiguity if you are using a user-built "
359  "MeshGenerator\n"
360  "- if you intend to execute a subset of the defined generators (uncommon), select the"
361  " final MeshGenerator in the [Mesh] block with the \"final_generator\" parameter.";
362  mooseError(oss.str());
363  }
364 
365  _final_generator_name = final_generators.back()->name();
366  }
367  else
368  mooseAssert(hasMeshGenerator(_final_generator_name), "Missing the preset final generator");
369 }
370 
371 void
373 {
374  libmesh_parallel_only(comm());
375 
376  // we do not need to do this when there are no mesh generators
377  if (_mesh_generators.empty())
378  return;
379 
380  // Order the generators
382 
383  // Save all meshes marked to to_save_in_meshes and save in error checking
384  std::map<std::string, std::unique_ptr<MeshBase> *> to_save_in_meshes;
385  for (const auto & generator_set : _ordered_mesh_generators)
386  for (const auto & generator : generator_set)
387  if (generator->hasSaveMesh())
388  {
389  if (_final_generator_name == generator->name())
390  generator->paramError("save_with_name",
391  "Cannot use the save in capability with the final mesh generator");
392  to_save_in_meshes.emplace(generator->getSavedMeshName(),
393  &getMeshGeneratorOutput(generator->name()));
394  }
395  // Grab the outputs from the final generator so MeshGeneratorMesh can pick it up
396  to_save_in_meshes.emplace(mainMeshGeneratorName(),
398 
399  // Run the MeshGenerators in the proper order
400  for (const auto & generator_set : _ordered_mesh_generators)
401  {
402  for (const auto & generator : generator_set)
403  {
404  const auto & name = generator->name();
405  if (_verbose)
406  _app._console << " [DBG] Executing mesh generator (" << COLOR_GREEN << std::setw(20) << name
407  << COLOR_DEFAULT << ") in type (" << COLOR_GREEN << generator->type()
408  << COLOR_DEFAULT << ")" << std::endl;
409  auto current_mesh = generator->generateInternal();
410 
411  // Only generating data for this generator
412  if (generator->isDataOnly())
413  {
414  mooseAssert(!current_mesh, "Should not have a mesh");
415  continue;
416  }
417 
418 #ifdef DEBUG
419  // Assert that the mesh is either marked as not prepared or if it is marked as prepared,
420  // that it's *actually* prepared
421  if (!_has_bmbb && !MeshTools::valid_is_prepared(*current_mesh))
422  generator->mooseError("The generated mesh is marked as prepared but is not actually "
423  "prepared. Please edit the '",
424  generator->type(),
425  "' class to call 'set_isnt_prepared()'");
426 #endif
427 
428  // Now we need to possibly give this mesh to downstream generators
429  auto & outputs = _mesh_generator_outputs[name];
430 
431  if (outputs.size())
432  {
433  auto & first_output = *outputs.begin();
434 
435  first_output = std::move(current_mesh);
436 
437  const auto & copy_from = *first_output;
438 
439  auto output_it = ++outputs.begin();
440 
441  // For all of the rest we need to make a copy
442  for (; output_it != outputs.end(); ++output_it)
443  (*output_it) = copy_from.clone();
444  }
445  }
446  }
447 
448  // Grab all the valid save in meshes from the temporary map to_save_in_meshes
449  // and store them in _save_in_meshes
450  for (auto & [name, mesh_ptr] : to_save_in_meshes)
451  {
452  mooseAssert(mesh_ptr, "Invalid pointer");
453  mooseAssert(*mesh_ptr, "Invalid pointer");
454  if (name != mainMeshGeneratorName())
455  mooseAssert(_save_in_meshes.count(name), "Mesh has not been requested for save");
456  _save_in_meshes[name] = std::move(*mesh_ptr);
457  }
458 }
459 
460 std::shared_ptr<MeshGenerator>
461 MeshGeneratorSystem::createMeshGenerator(const std::string & generator_name)
462 {
463  libmesh_parallel_only(comm());
464  mooseAssert(_app.constructingMeshGenerators(), "Should not run now");
465 
466  const auto find_params = _mesh_generator_params.find(generator_name);
467  mooseAssert(find_params != _mesh_generator_params.end(), "Not added");
468  const auto & [type, params] = find_params->second;
469  mooseAssert(comm().verify(type + generator_name), "Inconsistent construction order");
470 
471  std::shared_ptr<MeshGenerator> mg =
472  _app.getFactory().create<MeshGenerator>(type, generator_name, params);
473 
474  if (mg->hasSaveMesh())
475  {
476  if (_save_in_meshes.count(mg->getSavedMeshName()))
477  mg->paramError("save_with_name",
478  "The save with name '",
479  mg->getSavedMeshName(),
480  "' has already been used");
481  _save_in_meshes.emplace(mg->getSavedMeshName(), nullptr);
482  }
483 
484  // Setup the children and parents
485  for (const auto & dependency : mg->getRequestedMeshGenerators())
486  {
487  // We _shouldn't_ hit this; now that we enforce construction ordering we do
488  // all of this error checking at construction time because the info is available
489  mooseAssert(hasMeshGenerator(dependency), "Missing dependency");
490 
491  auto & dependency_mg = getMeshGeneratorInternal(dependency);
492  mg->addParentMeshGenerator(dependency_mg, MeshGenerator::AddParentChildKey());
493  dependency_mg.addChildMeshGenerator(*mg, MeshGenerator::AddParentChildKey());
494  }
495 
496  // Loop through all of the MeshGeneratorName and std::vector<MeshGeneratorName>
497  // parameters (meshes that we should depend on), and make sure that either:
498  // - We directly depend on them and requested a mesh from them
499  // - We created a sub generator that depends on them and we declared it
500  for (const auto & param_dependency_pair : getMeshGeneratorParamDependencies(mg->parameters()))
501  {
502  const auto & param_name = param_dependency_pair.first;
503  const auto & dependency_name = param_dependency_pair.second;
504 
505  if (mg->isNullMeshName(dependency_name))
506  continue;
507 
508  // True if this dependency was requested and is a parent
509  if (mg->isParentMeshGenerator(dependency_name))
510  {
511  mooseAssert(mg->getRequestedMeshGenerators().count(dependency_name), "Wasn't requested");
512  continue;
513  }
514 
515  // Whether or not this is a dependency of at least one SubGenerator
516  auto find_sub_dependency = std::find_if(mg->getSubMeshGenerators().begin(),
517  mg->getSubMeshGenerators().end(),
518  [&dependency_name](const auto & mg)
519  { return mg->isParentMeshGenerator(dependency_name); });
520  const auto is_sub_dependency = find_sub_dependency != mg->getSubMeshGenerators().end();
521 
522  // This should be used by a sub generator
523  if (mg->getRequestedMeshGeneratorsForSub().count(dependency_name))
524  {
525  if (!is_sub_dependency)
526  mg->mooseError("The sub generator dependency declared from MeshGenerator '",
527  dependency_name,
528  "' from the parameter '",
529  param_name,
530  "' was not used.\n\nDependencies that are declared by declareMeshForSub() "
531  "must be used as an input to a sub generator created by this object.");
532  }
533  // This was used by a sub generator but wasn't declared
534  else if (is_sub_dependency)
535  mg->mooseError(
536  "The MeshGenerator '",
537  dependency_name,
538  "' was referenced in the parameter '",
539  param_name,
540  "' and used in the sub generator ",
541  (*find_sub_dependency)->type(),
542  " '",
543  (*find_sub_dependency)->name(),
544  "', but was not declared as a sub dependency.\n\nTo correct this, modify the code of ",
545  mg->type(),
546  " to include a call to declareMesh(es)ForSub(\"",
547  param_name,
548  "\") in the constructor.");
549  // Isn't used at all
550  else
551  mg->mooseError(
552  "You failed to request the generated mesh(es) for the parameter '",
553  param_name,
554  "'.\n\nIn specific, the mesh from MeshGenerator '",
555  dependency_name,
556  "' was not requested.\n\nTo correct this, you should remove the parameter if the "
557  "mesh(es)\nare not needed, or request the mesh(es) with getMesh()/getMeshes().");
558  }
559 
560  mooseAssert(!_mesh_generators.count(generator_name), "Already created");
561  _mesh_generators.emplace(generator_name, mg);
562  mooseAssert(!_mesh_generator_outputs.count(generator_name), "Already exists");
563  _mesh_generator_outputs[generator_name];
564  _mesh_generator_params.erase(find_params);
565 
566  return mg;
567 }
568 
569 std::unique_ptr<MeshBase> &
570 MeshGeneratorSystem::getMeshGeneratorOutput(const MeshGeneratorName & name)
571 {
572  mooseAssert(_app.constructingMeshGenerators() ||
573  _app.actionWarehouse().getCurrentTaskName() == "execute_mesh_generators",
574  "Incorrect call time");
575 
576  auto it = _mesh_generator_outputs.find(name);
577  mooseAssert(it != _mesh_generator_outputs.end(), "Not initialized");
578  it->second.push_back(nullptr);
579  return it->second.back();
580 }
581 
582 bool
583 MeshGeneratorSystem::hasMeshGenerator(const MeshGeneratorName & name) const
584 {
585  return _mesh_generators.count(name);
586 }
587 
588 bool
589 MeshGeneratorSystem::hasMeshGeneratorParams(const MeshGeneratorName & name) const
590 {
591  return _mesh_generator_params.count(name);
592 }
593 
594 const MeshGenerator &
595 MeshGeneratorSystem::getMeshGenerator(const std::string & name) const
596 {
597  const auto it = _mesh_generators.find(name);
598  if (it == _mesh_generators.end())
599  mooseError("Failed to find a MeshGenerator with the name '", name, "'");
600  mooseAssert(it->second, "Invalid shared pointer");
601  return *it->second;
602 }
603 
604 std::vector<std::string>
606 {
607  std::vector<std::string> names;
608  for (auto & pair : _mesh_generators)
609  names.push_back(pair.first);
610  return names;
611 }
612 
613 std::vector<std::string>
615 {
616  std::vector<std::string> names;
617  for (auto & pair : _save_in_meshes)
618  names.push_back(pair.first);
619  return names;
620 }
621 
622 std::unique_ptr<MeshBase>
623 MeshGeneratorSystem::getSavedMesh(const std::string & name)
624 {
625  auto find_mesh = _save_in_meshes.find(name);
626  if (find_mesh == _save_in_meshes.end())
627  mooseError("Failed to find a saved mesh with the name '", name, "'");
628 
629  auto & mesh_unique_ptr = find_mesh->second;
630  if (!mesh_unique_ptr)
631  mooseError("While getting the saved mesh generator '",
632  name,
633  "', said mesh has already been retrieved");
634 
635  return std::move(mesh_unique_ptr);
636 }
637 
638 bool
640 {
641  return _app.actionWarehouse().getCurrentTaskName() == "append_mesh_generator";
642 }
643 
644 bool
646 {
647  return _app.parameters().get<bool>(allow_data_driven_param);
648 }
649 
650 const std::string &
652 {
653  mooseAssert(_data_driven_generator_name, "Not set");
655 }
656 
657 void
659  const std::string & message) const
660 {
661  const auto & moose_mesh = _app.actionWarehouse().getMesh();
662  moose_mesh->paramError(data_driven_generator_param,
663  "The generator '",
665  "' cannot be used in data-driven mode because the parent ",
666  generator.typeAndName(),
667  " ",
668  message);
669 }
std::string name(const ElemQuality q)
virtual bool constructingMeshGenerators() const
Whether this app is constructing mesh generators.
Definition: MooseApp.C:3492
std::string _final_generator_name
The final mesh generator name to use.
MeshGeneratorSystem(MooseApp &app)
std::string join(Iterator begin, Iterator end, const std::string &delimiter)
Python-like join function for strings over an iterator range.
Definition: MooseUtils.h:142
static const std::string data_only_param
The name of the private parameter for setting data only.
Definition: MeshGenerator.h:62
std::shared_ptr< MeshGenerator > createMeshGenerator(const std::string &name)
Internal method for actually constructing a mesh generator after it has been declared externally in a...
bool isChildMeshGenerator(const MeshGeneratorName &name, const bool direct=true) const
std::unique_ptr< libMesh::MeshBase > & getMeshGeneratorOutput(const MeshGeneratorName &name)
Get a reference to a pointer that will be the output of the MeshGenerator named name.
bool hasSaveMesh() const
Return whether or not to save the current mesh.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
std::map< std::string, std::unique_ptr< libMesh::MeshBase > > _save_in_meshes
Holds the map of save in mesh -> name.
std::size_t size() const
Returns the number of unique items stored in the dependency resolver.
bool hasDataDrivenAllowed() const
const std::vector< T > & getSortedValues()
This function also returns dependency resolved values but with a simpler single vector interface...
const std::shared_ptr< MooseMesh > & getMesh() const
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
std::unique_ptr< libMesh::MeshBase > getSavedMesh(const std::string &name)
Get the saved mesh by name.
std::vector< std::string > getMeshGeneratorNames() const
Get names of all mesh generators Note: This function should be called after all mesh generators are a...
bool dependsOn(const T &key, const T &value)
Return true if key depends on value.
Base class for MOOSE-based applications.
Definition: MooseApp.h:96
void executeMeshGenerators()
Execute and clear the Mesh Generators data structure.
bool hasOutput() const
std::optional< std::string > _data_driven_generator_name
The name of the data driven generator, if any.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const Parallel::Communicator & comm() const
std::list< T > getAncestors(const T &key)
Returns a list of all values that a given key depends on.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const std::vector< std::vector< T > > & getSortedValuesSets()
Returns a vector of sets that represent dependency resolved values.
void addEdge(const T &a, const T &b)
Add an edge between nodes &#39;a&#39; and &#39;b&#39;.
const InputParameters & parameters()
Get the parameters of the object.
Definition: MooseApp.h:161
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition: MooseApp.h:424
bool _verbose
Whether to print the names of the mesh generators being executed or not.
void addMeshGenerator(const std::string &type, const std::string &name, const InputParameters &params)
Add a mesh generator that will act on the meshes in the system.
const MeshGenerator & appendMeshGenerator(const std::string &type, const std::string &name, InputParameters params)
Append a mesh generator that will act on the current final mesh generator in the system.
void addItem(const T &value)
Add an independent item to the set.
MooseApp & _app
The MooseApp that owns this system.
virtual std::unique_ptr< Base > create()=0
void createAddedMeshGenerators()
Creates (constructs) all of the MeshGenerators that have been declared using addMeshGenerator().
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition: MooseApp.h:237
std::string typeAndName() const
Get the class&#39;s combined type and name; useful in error handling.
Definition: MooseBase.C:27
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
std::map< std::string, std::list< std::unique_ptr< libMesh::MeshBase > > > _mesh_generator_outputs
Holds the output for each mesh generator - including duplicates needed downstream.
Interface for objects interacting with the PerfGraph.
std::vector< std::string > getSavedMeshNames() const
Get all user-defined saved meshes except main and main_displaced.
static std::string mainMeshGeneratorName()
The name reserved for the "main" mesh generator which is the one used for the numerical solver downst...
std::map< std::string, std::shared_ptr< MeshGenerator > > _mesh_generators
Owning storage for mesh generators, map of name -> MeshGenerator.
const std::string & getCurrentTaskName() const
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
void createMeshGeneratorOrder()
Order all of the _mesh_generators into _ordered_mesh_generators for later execution in executeMeshGen...
const std::vector< T > & getCyclicDependencies() const
Class that is used as a parameter to add[Parent/Child]() that allows only MeshGeneratorSystem methods...
Definition: MeshGenerator.h:97
static const std::string data_driven_generator_param
The name of the string parameter that sets the data driven generator.
const std::set< const MeshGenerator *, Comparator > & getParentMeshGenerators() const
Gets the MeshGenerators that are parents to this MeshGenerator.
bool hasMeshGenerator(const MeshGeneratorName &name) const
void dataDrivenError(const MeshGenerator &generator, const std::string &message) const
Reports an error with the context of the data driven parameter, coming from the generator generator w...
const MeshGenerator & getMeshGenerator(const std::string &name) const
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
bool appendingMeshGenerators() const
Whether or not mesh generators are currently being appended (append_mesh_generator task) ...
static const std::string allow_data_driven_param
The name of the boolean parameter on the MooseApp that will enable data driven generation.
const std::string & getDataDrivenGeneratorName() const
MeshGenerator & getMeshGeneratorInternal(const std::string &name)
Get a MeshGenerator with the name name.
bool _has_bmbb
Whether any of the mesh generators are a BreakMeshByBlockGenerator.
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
auto index_range(const T &sizable)
std::unordered_map< std::string, std::pair< std::string, InputParameters > > _mesh_generator_params
The MeshGenerators declared using addMeshGenerator(), cleared after createMeshGenerators() Key is the...
bool hasMeshGeneratorParams(const MeshGeneratorName &name) const
Whether or not we know about the parameters for a MeshGenerator with the given name.
std::vector< std::pair< std::string, MeshGeneratorName > > getMeshGeneratorParamDependencies(const InputParameters &params, const bool allow_empty=false) const
Gets the MeshGeneratorNames that are referenced in an object&#39;s parameters.
std::vector< std::vector< MeshGenerator * > > _ordered_mesh_generators
Holds the ordered mesh generators from createMeshGeneratorOrder() until they are executed in executeM...