https://mooseframework.inl.gov
ActionWarehouse.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 "ActionWarehouse.h"
11 #include "ActionFactory.h"
12 #include "Parser.h"
13 #include "MooseObjectAction.h"
14 #include "InputFileFormatter.h"
15 #include "InputParameters.h"
16 #include "MooseMesh.h"
17 #include "AddVariableAction.h"
18 #include "AddAuxVariableAction.h"
19 #include "XTermConstants.h"
20 #include "InfixIterator.h"
21 #include "FEProblem.h"
22 #include "MemoryUtils.h"
24 
25 #include "libmesh/simple_range.h"
26 
29  _app(app),
30  _syntax(syntax),
31  _action_factory(factory),
32  _generator_valid(false),
33  _show_action_dependencies(false),
34  _show_actions(false),
35  _show_parser(false),
36  _current_action(nullptr),
37  _mesh(nullptr),
38  _displaced_mesh(nullptr)
39 {
40 }
41 
43 
44 void
45 ActionWarehouse::setFinalTask(const std::string & task)
46 {
47  if (!_syntax.hasTask(task))
48  mooseError("cannot use unregistered task '", task, "' as final task");
49  _final_task = task;
50 }
51 
52 void
54 {
56  for (const auto & name : _ordered_names)
58 }
59 
60 void
62 {
63  for (auto & ptr : _all_ptrs)
64  ptr.reset();
65 
66  _action_blocks.clear();
67  _generator_valid = false;
68 
69  // Due to the way ActionWarehouse is cleaned up (see MooseApp's
70  // destructor) we must guarantee that ActionWarehouse::clear()
71  // releases all the resources which have to be released _before_ the
72  // _comm object owned by the MooseApp is destroyed.
73  _problem.reset();
74  _displaced_mesh.reset();
75  _mesh.reset();
76 }
77 
78 void
79 ActionWarehouse::addActionBlock(std::shared_ptr<Action> action)
80 {
88  std::string registered_identifier =
89  action->parameters().get<std::string>("registered_identifier");
90  std::set<std::string> tasks;
91 
92  if (_show_parser)
93  Moose::err << COLOR_DEFAULT << "Parsing Syntax: " << COLOR_GREEN << action->name()
94  << '\n'
95  << COLOR_DEFAULT << "Building Action: " << COLOR_DEFAULT << action->type()
96  << '\n'
97  << COLOR_DEFAULT << "Registered Identifier: " << COLOR_GREEN << registered_identifier
98  << '\n'
99  << COLOR_DEFAULT << "Specific Task: " << COLOR_CYAN
100  << action->specificTaskName() << std::endl;
101 
122  if (action->specificTaskName() != "") // Case 1
123  tasks.insert(action->specificTaskName());
124  else if (registered_identifier == "" &&
125  _syntax.getNonDeprecatedSyntaxByAction(action->type()).size() > 1) // Case 2
126  {
127  std::set<std::string> local_tasks = action->getAllTasks();
128  mooseAssert(local_tasks.size() == 1, "More than one task inside of the " << action->name());
129  tasks.insert(*local_tasks.begin());
130  }
131  else // Case 3
132  tasks = _action_factory.getTasksByAction(action->type());
133 
134  // TODO: Now we need to weed out the double registrations!
135  for (const auto & task : tasks)
136  {
137  // Some error checking
138  if (!_syntax.hasTask(task))
139  mooseError("A(n) ", task, " is not a registered task");
140 
141  // Make sure that the ObjectAction task and Action task are consistent
142  // otherwise that means that is action was built by the wrong type
143  std::shared_ptr<MooseObjectAction> moa = std::dynamic_pointer_cast<MooseObjectAction>(action);
144  if (moa.get())
145  {
146  const InputParameters & mparams = moa->getObjectParams();
147 
148  if (mparams.hasBase())
149  {
150  const std::string & base = mparams.getBase();
151  if (!_syntax.verifyMooseObjectTask(base, task))
152  mooseError("Task ", task, " is not registered to build ", base, " derived objects");
153  }
154  else
155  mooseError("Unable to locate registered base parameter for ", moa->getMooseObjectType());
156  }
157 
158  // Add the current task to current action
159  action->appendTask(task);
160 
161  if (_show_parser)
162  Moose::err << COLOR_YELLOW << "Adding Action: " << COLOR_DEFAULT << action->type()
163  << " (" << COLOR_YELLOW << task << COLOR_DEFAULT << ")" << std::endl;
164 
165  // Add it to the warehouse
166  _action_blocks[task].push_back(action.get());
167  }
168  _all_ptrs.push_back(action);
169 
170  if (_show_parser)
171  Moose::err << std::endl;
172 }
173 
176 {
177  return _action_blocks[task].begin();
178 }
179 
182 {
183  return _action_blocks[task].end();
184 }
185 
186 const std::vector<std::shared_ptr<Action>> &
188 {
189  return _all_ptrs;
190 }
191 
192 const std::list<Action *> &
193 ActionWarehouse::getActionListByName(const std::string & task) const
194 {
195  const auto it = _action_blocks.find(task);
196  if (it == _action_blocks.end())
197  return _empty_action_list;
198  else
199  return it->second;
200 }
201 
202 bool
203 ActionWarehouse::hasActions(const std::string & task) const
204 {
205  auto it = _action_blocks.find(task);
206  return it != _action_blocks.end() && !it->second.empty();
207 }
208 
209 void
210 ActionWarehouse::buildBuildableActions(const std::string & task)
211 {
212  if (_syntax.shouldAutoBuild(task) && _action_blocks[task].empty())
213  {
214  bool ret_value = false;
215  auto it_pair = _action_factory.getActionsByTask(task);
216  for (const auto & action_pair : as_range(it_pair))
217  {
218  const auto & type = action_pair.second;
220  params.set<ActionWarehouse *>("awh") = this;
221 
222  std::string name = "auto_" + type;
223  std::transform(
224  name.begin(), name.end(), name.begin(), [](const auto v) { return std::tolower(v); });
225 
226  if (params.areAllRequiredParamsValid())
227  {
228  params.set<std::string>("registered_identifier") = "(AutoBuilt)";
229  addActionBlock(_action_factory.create(type, name, params));
230  ret_value = true;
231  }
232  }
233 
234  if (!ret_value)
235  _unsatisfied_dependencies.insert(task);
236  }
237 }
238 
239 void
241 {
242  std::stringstream oss;
243  bool empty = true;
244 
245  for (const auto & udep : _unsatisfied_dependencies)
246  {
247  if (_action_blocks.find(udep) == _action_blocks.end())
248  {
249  if (empty)
250  empty = false;
251  else
252  oss << " ";
253  oss << udep;
254  }
255  }
256 
257  if (!empty)
258  mooseError(
259  std::string(
260  "The following unsatisfied actions where found while setting up the MOOSE problem:\n") +
261  oss.str() + "\n");
262 }
263 
264 void
266 {
276  std::ostringstream oss;
277 
278  const auto & ordered_names = _syntax.getSortedTaskSet();
279  for (const auto & task_vector : ordered_names)
280  {
281  oss << "[DBG][ACT] (" << COLOR_YELLOW;
282  std::copy(
283  task_vector.begin(), task_vector.end(), infix_ostream_iterator<std::string>(oss, ", "));
284  oss << COLOR_DEFAULT << ")\n";
285 
286  std::set<std::string> task_set(task_vector.begin(), task_vector.end());
287  for (const auto & task : task_set)
288  {
289  if (_action_blocks.find(task) == _action_blocks.end())
290  continue;
291 
292  for (const auto & act : _action_blocks.at(task))
293  {
294  // The Syntax of the Action if it exists
295  if (act->name() != "")
296  oss << "[DBG][ACT]\t" << COLOR_GREEN << act->name() << COLOR_DEFAULT << '\n';
297 
298  // The task sets
299  oss << "[DBG][ACT]\t" << act->type();
300  const std::set<std::string> tasks = act->getAllTasks();
301  if (tasks.size() > 1)
302  {
303  oss << " (";
304  // Break the current Action's tasks into 2 sets, those intersecting with current set and
305  // then the difference.
306  std::set<std::string> intersection, difference;
307  std::set_intersection(tasks.begin(),
308  tasks.end(),
309  task_set.begin(),
310  task_set.end(),
311  std::inserter(intersection, intersection.end()));
312  std::set_difference(tasks.begin(),
313  tasks.end(),
314  intersection.begin(),
315  intersection.end(),
316  std::inserter(difference, difference.end()));
317 
318  oss << COLOR_CYAN;
319  std::copy(intersection.begin(),
320  intersection.end(),
321  infix_ostream_iterator<std::string>(oss, ", "));
322  oss << COLOR_MAGENTA << (difference.empty() ? "" : ", ");
323  std::copy(
324  difference.begin(), difference.end(), infix_ostream_iterator<std::string>(oss, ", "));
325  oss << COLOR_DEFAULT << ")";
326  }
327  oss << '\n';
328  }
329  }
330  }
331 
333  _console << oss.str() << std::endl;
334 }
335 
336 void
338 {
339  _completed_tasks.clear();
340 
342  {
343  _console << "[DBG][ACT] Action Dependency Sets:\n";
345 
346  _console << "\n[DBG][ACT] Executing actions:" << std::endl;
347  }
348 
349  for (const auto & task : _ordered_names)
350  {
352  std::scoped_lock lock(_completed_tasks_mutex);
353  _completed_tasks.insert(task);
354  if (_final_task != "" && task == _final_task)
355  break;
356  }
357 
358  if (_show_actions)
359  {
360  MemoryUtils::Stats stats;
362  auto usage =
364  _console << "[DBG][ACT] Finished executing all actions with memory usage " << usage << "MB\n"
365  << std::endl;
366  }
367 }
368 
369 void
371 {
372  // Set the current task name
373  _current_task = task;
374 
375  for (auto it = actionBlocksWithActionBegin(task); it != actionBlocksWithActionEnd(task); ++it)
376  {
377  _current_action = *it;
378 
379  if (_show_actions)
380  {
381  MemoryUtils::Stats stats;
383  auto usage =
385  _console << "[DBG][ACT] "
386  << "TASK (" << COLOR_YELLOW << std::setw(24) << task << COLOR_DEFAULT << ") "
387  << "TYPE (" << COLOR_YELLOW << std::setw(32) << _current_action->type()
388  << COLOR_DEFAULT << ") "
389  << "NAME (" << COLOR_YELLOW << std::setw(16) << _current_action->name()
390  << COLOR_DEFAULT << ") Memory usage " << usage << "MB" << std::endl;
391  }
392 
394  }
395 
396  _current_action = nullptr;
397 }
398 
399 void
401 {
402  InputFileFormatter tree(false);
403 
404  std::map<std::string, std::vector<Action *>>::iterator iter;
405 
406  std::vector<Action *> ordered_actions;
407  for (const auto & block : _action_blocks)
408  for (const auto & act : block.second)
409  ordered_actions.push_back(act);
410 
411  for (const auto & act : ordered_actions)
412  {
413  std::string name;
414  if (act->parameters().blockFullpath() != "")
415  name = act->parameters().blockFullpath();
416  else
417  name = act->name();
418  const std::set<std::string> & tasks = act->getAllTasks();
419  mooseAssert(!tasks.empty(), "Task list is empty");
420 
421  bool is_parent;
422  if (_syntax.isAssociated(name, &is_parent) != "")
423  {
424  const auto & all_params = _app.getInputParameterWarehouse().getInputParameters();
425  InputParameters & params = *(all_params.find(act->uniqueActionName())->second.get());
426 
427  // temporarily allow input parameter copies required by the input file formatter
428  params.allowCopy(true);
429 
430  // TODO: Do we need to insert more nodes for each task?
431  tree.insertNode(name, *tasks.begin(), true, &params);
432  params.allowCopy(false);
433 
434  MooseObjectAction * moose_object_action = dynamic_cast<MooseObjectAction *>(act);
435  if (moose_object_action)
436  {
437  InputParameters obj_params = moose_object_action->getObjectParams();
438  tree.insertNode(name, *tasks.begin(), false, &obj_params);
439  }
440  }
441  }
442 
443  out << tree.print("");
444 }
445 
446 std::shared_ptr<FEProblem>
448 {
450  "ActionWarehouse::problem() is deprecated, please use ActionWarehouse::problemBase() \n");
452 }
453 
454 std::string
456 {
457  return getCurrentAction()->parameters().getHitNode()->fullpath();
458 }
459 
460 const std::string &
462 {
463  return _app.name();
464 }
465 
466 bool
467 ActionWarehouse::hasTask(const std::string & task) const
468 {
469  return _action_factory.isRegisteredTask(task);
470 }
471 
472 bool
473 ActionWarehouse::isTaskComplete(const std::string & task) const
474 {
475  if (!hasTask(task))
476  mooseError("\"", task, "\" is not a registered task.");
477  std::scoped_lock lock(_completed_tasks_mutex);
478  return _completed_tasks.count(task);
479 }
std::string name(const ElemQuality q)
bool hasTask(const std::string &task) const
Returns a Boolean indicating whether or not a task is registered with the syntax object.
Definition: Syntax.C:125
bool _show_parser
Whether or not to print messages when actions are inserted in the warehouse by the parser...
void checkUnsatisfiedActions() const
This method checks the actions stored in the warehouse against the list of required registered action...
unsigned int size(THREAD_ID tid=0) const
Return how many kernels we store in the current warehouse.
const hit::Node * getHitNode(const std::string &param) const
std::list< Action * >::iterator ActionIterator
alias to hide implementation details
const Action * getCurrentAction() const
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition: FEProblem.h:20
bool getMemoryStats(Stats &stats)
get all memory stats for the current process stats The Stats object to fill with the data ...
Definition: MemoryUtils.C:79
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:94
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:333
std::size_t _physical_memory
Definition: MemoryUtils.h:23
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
Definition: MooseApp.C:2900
bool isTaskComplete(const std::string &task) const
Syntax & _syntax
Reference to a "syntax" of actions.
std::pair< std::multimap< std::string, std::string >::const_iterator, std::multimap< std::string, std::string >::const_iterator > getActionsByTask(const std::string &task) const
Returns begin and end iterators in a multimap from tasks to actions names.
const InputParameters & parameters() const
Get the parameters of the object.
Definition: MooseBase.h:127
std::set< std::string > getTasksByAction(const std::string &action) const
bool hasTask(const std::string &task) const
const std::string & getMooseAppName()
void setFinalTask(const std::string &task)
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
std::string getCurrentActionName() const
Base class for MOOSE-based applications.
Definition: MooseApp.h:96
Storage for action instances.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const std::vector< std::string > & getSortedTask()
Get a list of serialized tasks in a correct dependency order.
Definition: Syntax.C:105
void addActionBlock(std::shared_ptr< Action > blk)
This method add an Action instance to the warehouse.
bool hasBase() const
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
void printInputFile(std::ostream &out)
This method uses the Actions in the warehouse to reproduce the input file.
void executeActionsWithAction(const std::string &name)
This method executes only the actions in the warehouse that satisfy the task passed in...
const std::list< Action * > & getActionListByName(const std::string &task) const
Retrieve a constant list of Action pointers associated with the passed in task.
void printActionDependencySets() const
This method is used only during debugging when show_actions is set to true.
const std::string & getBase() const
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:40
std::string _final_task
Last task to run before (optional) early termination - blank means no early termination.
std::vector< std::string > _ordered_names
The container that holds the sorted action names from the DependencyResolver.
bool shouldAutoBuild(const std::string &task) const
Returns a Boolean indicating whether MOOSE should attempt to automatically create an Action to satisf...
Definition: Syntax.C:138
std::vector< std::string > getNonDeprecatedSyntaxByAction(const std::string &action, const std::string &task="")
Retrieve the non-deprecated syntax associated with the passed in action type string.
Definition: Syntax.C:237
const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:99
InputParameters & getObjectParams()
Retrieve the parameters of the object to be created by this action.
bool isRegisteredTask(const std::string &task) const
Whether or not a task with the name task is registered.
bool empty() const
returns a Boolean indicating whether the warehouse is empty or not.
std::set< std::string > _completed_tasks
The completed tasks.
const std::multimap< MooseObjectName, std::shared_ptr< InputParameters > > & getInputParameters(THREAD_ID tid=0) const
Return const reference to the map containing the InputParameter objects.
std::mutex _completed_tasks_mutex
Mutex for preventing read/write races for _completed_tasks.
bool areAllRequiredParamsValid() const
This method returns true if all of the parameters in this object are valid (i.e.
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Specialized factory for generic Action System objects.
Definition: ActionFactory.h:50
An inteface for the _console for outputting to the Console object.
const std::vector< std::vector< std::string > > & getSortedTaskSet()
Get a list of serialized tasks in a correct dependency order.
Definition: Syntax.C:119
void usage(const std::string &progName)
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:89
std::map< std::string, std::list< Action * > > _action_blocks
Pointers to the actual parsed input file blocks.
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:384
std::shared_ptr< MooseMesh > _displaced_mesh
Possible mesh for displaced problem.
bool _generator_valid
Flag to indicate whether or not there is an active iterator on this class.
std::string isAssociated(const std::string &real_id, bool *is_parent, const std::map< std::string, std::set< std::string >> &alt_map={}) const
Method for determining whether a piece of syntax is associated with an Action an optional syntax map ...
Definition: Syntax.C:251
void allowCopy(bool status)
Toggle the availability of the copy constructor.
void insertNode(std::string syntax, const std::string &action, bool is_action_params=true, InputParameters *params=NULL)
Definition: SyntaxTree.C:27
const std::list< Action * > _empty_action_list
std::vector< std::shared_ptr< Action > > _all_ptrs
std::shared_ptr< FEProblemBase > _problem
Problem class.
std::string print(const std::string &search_string)
Definition: SyntaxTree.C:39
bool hasActions(const std::string &task) const
Check if Actions associated with passed in task exist.
ActionWarehouse(MooseApp &app, Syntax &syntax, ActionFactory &factory)
std::shared_ptr< MooseMesh > _mesh
Mesh class.
bool _show_actions
Whether or not the action warehouse prints the action execution information.
MooseApp & _app
The MooseApp this Warehouse is associated with.
const std::vector< std::shared_ptr< Action > > & allActionBlocks() const
Returns a reference to all of the actions.
void build()
Builds all auto-buildable tasks.
OStreamProxy out
void timedAct()
The method called externally that causes the action to act()
Definition: Action.C:75
Holding syntax for parsing input files.
Definition: Syntax.h:21
bool verifyMooseObjectTask(const std::string &base, const std::string &task) const
Returns a Boolean indicating whether a task is associated with on of the MOOSE pluggable systems (BAS...
Definition: Syntax.C:334
void executeAllActions()
This method loops over all actions in the warehouse and executes them.
ActionIterator actionBlocksWithActionEnd(const std::string &task)
std::set< std::string > _unsatisfied_dependencies
Use to store the current list of unsatisfied dependencies.
Action * _current_action
bool _show_action_dependencies
Whether or not the action warehouse prints the action dependency information.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
std::shared_ptr< FEProblem > problem()
ActionIterator actionBlocksWithActionBegin(const std::string &task)
Iterators to the Actions in the warehouse.
void clear()
This method deletes all of the Actions in the warehouse.
std::size_t convertBytes(std::size_t bytes, MemUnits unit)
convert bytes to selected unit prefix
Definition: MemoryUtils.C:174
void buildBuildableActions(const std::string &task)
This method auto-builds all Actions that needs to be built and adds them to ActionWarehouse.
ActionFactory & _action_factory
The Factory that builds Actions.
This class produces produces a dump of the InputParameters that appears like the normal input file sy...
std::string _current_task