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.have_parameter<std::string>("_moose_base"))
149  {
150  const std::string & base = mparams.get<std::string>("_moose_base");
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  InputParameters params = _action_factory.getValidParams(action_pair.second);
219  params.set<ActionWarehouse *>("awh") = this;
220 
221  if (params.areAllRequiredParamsValid())
222  {
223  params.set<std::string>("registered_identifier") = "(AutoBuilt)";
224  addActionBlock(_action_factory.create(action_pair.second, "", params));
225  ret_value = true;
226  }
227  }
228 
229  if (!ret_value)
230  _unsatisfied_dependencies.insert(task);
231  }
232 }
233 
234 void
236 {
237  std::stringstream oss;
238  bool empty = true;
239 
240  for (const auto & udep : _unsatisfied_dependencies)
241  {
242  if (_action_blocks.find(udep) == _action_blocks.end())
243  {
244  if (empty)
245  empty = false;
246  else
247  oss << " ";
248  oss << udep;
249  }
250  }
251 
252  if (!empty)
253  mooseError(
254  std::string(
255  "The following unsatisfied actions where found while setting up the MOOSE problem:\n") +
256  oss.str() + "\n");
257 }
258 
259 void
261 {
271  std::ostringstream oss;
272 
273  const auto & ordered_names = _syntax.getSortedTaskSet();
274  for (const auto & task_vector : ordered_names)
275  {
276  oss << "[DBG][ACT] (" << COLOR_YELLOW;
277  std::copy(
278  task_vector.begin(), task_vector.end(), infix_ostream_iterator<std::string>(oss, ", "));
279  oss << COLOR_DEFAULT << ")\n";
280 
281  std::set<std::string> task_set(task_vector.begin(), task_vector.end());
282  for (const auto & task : task_set)
283  {
284  if (_action_blocks.find(task) == _action_blocks.end())
285  continue;
286 
287  for (const auto & act : _action_blocks.at(task))
288  {
289  // The Syntax of the Action if it exists
290  if (act->name() != "")
291  oss << "[DBG][ACT]\t" << COLOR_GREEN << act->name() << COLOR_DEFAULT << '\n';
292 
293  // The task sets
294  oss << "[DBG][ACT]\t" << act->type();
295  const std::set<std::string> tasks = act->getAllTasks();
296  if (tasks.size() > 1)
297  {
298  oss << " (";
299  // Break the current Action's tasks into 2 sets, those intersecting with current set and
300  // then the difference.
301  std::set<std::string> intersection, difference;
302  std::set_intersection(tasks.begin(),
303  tasks.end(),
304  task_set.begin(),
305  task_set.end(),
306  std::inserter(intersection, intersection.end()));
307  std::set_difference(tasks.begin(),
308  tasks.end(),
309  intersection.begin(),
310  intersection.end(),
311  std::inserter(difference, difference.end()));
312 
313  oss << COLOR_CYAN;
314  std::copy(intersection.begin(),
315  intersection.end(),
316  infix_ostream_iterator<std::string>(oss, ", "));
317  oss << COLOR_MAGENTA << (difference.empty() ? "" : ", ");
318  std::copy(
319  difference.begin(), difference.end(), infix_ostream_iterator<std::string>(oss, ", "));
320  oss << COLOR_DEFAULT << ")";
321  }
322  oss << '\n';
323  }
324  }
325  }
326 
328  _console << oss.str() << std::endl;
329 }
330 
331 void
333 {
334  _completed_tasks.clear();
335 
337  {
338  _console << "[DBG][ACT] Action Dependency Sets:\n";
340 
341  _console << "\n[DBG][ACT] Executing actions:" << std::endl;
342  }
343 
344  for (const auto & task : _ordered_names)
345  {
347  std::scoped_lock lock(_completed_tasks_mutex);
348  _completed_tasks.insert(task);
349  if (_final_task != "" && task == _final_task)
350  break;
351  }
352 
353  if (_show_actions)
354  {
355  MemoryUtils::Stats stats;
357  auto usage =
359  _console << "[DBG][ACT] Finished executing all actions with memory usage " << usage << "MB\n"
360  << std::endl;
361  }
362 }
363 
364 void
366 {
367  // Set the current task name
368  _current_task = task;
369 
370  for (auto it = actionBlocksWithActionBegin(task); it != actionBlocksWithActionEnd(task); ++it)
371  {
372  _current_action = *it;
373 
374  if (_show_actions)
375  {
376  MemoryUtils::Stats stats;
378  auto usage =
380  _console << "[DBG][ACT] "
381  << "TASK (" << COLOR_YELLOW << std::setw(24) << task << COLOR_DEFAULT << ") "
382  << "TYPE (" << COLOR_YELLOW << std::setw(32) << _current_action->type()
383  << COLOR_DEFAULT << ") "
384  << "NAME (" << COLOR_YELLOW << std::setw(16) << _current_action->name()
385  << COLOR_DEFAULT << ") Memory usage " << usage << "MB" << std::endl;
386  }
387 
389  }
390 
391  _current_action = nullptr;
392 }
393 
394 void
396 {
397  InputFileFormatter tree(false);
398 
399  std::map<std::string, std::vector<Action *>>::iterator iter;
400 
401  std::vector<Action *> ordered_actions;
402  for (const auto & block : _action_blocks)
403  for (const auto & act : block.second)
404  ordered_actions.push_back(act);
405 
406  for (const auto & act : ordered_actions)
407  {
408  std::string name;
409  if (act->parameters().blockFullpath() != "")
410  name = act->parameters().blockFullpath();
411  else
412  name = act->name();
413  const std::set<std::string> & tasks = act->getAllTasks();
414  mooseAssert(!tasks.empty(), "Task list is empty");
415 
416  bool is_parent;
417  if (_syntax.isAssociated(name, &is_parent) != "")
418  {
419  const auto & all_params = _app.getInputParameterWarehouse().getInputParameters();
420  InputParameters & params = *(all_params.find(act->uniqueActionName())->second.get());
421 
422  // temporarily allow input parameter copies required by the input file formatter
423  params.allowCopy(true);
424 
425  // TODO: Do we need to insert more nodes for each task?
426  tree.insertNode(name, *tasks.begin(), true, &params);
427  params.allowCopy(false);
428 
429  MooseObjectAction * moose_object_action = dynamic_cast<MooseObjectAction *>(act);
430  if (moose_object_action)
431  {
432  InputParameters obj_params = moose_object_action->getObjectParams();
433  tree.insertNode(name, *tasks.begin(), false, &obj_params);
434  }
435  }
436  }
437 
438  out << tree.print("");
439 }
440 
441 std::shared_ptr<FEProblem>
443 {
445  "ActionWarehouse::problem() is deprecated, please use ActionWarehouse::problemBase() \n");
447 }
448 
449 std::string
451 {
452  return getCurrentAction()->parameters().getHitNode()->fullpath();
453 }
454 
455 const std::string &
457 {
458  return _app.name();
459 }
460 
461 bool
462 ActionWarehouse::hasTask(const std::string & task) const
463 {
464  return _action_factory.isRegisteredTask(task);
465 }
466 
467 bool
468 ActionWarehouse::isTaskComplete(const std::string & task) const
469 {
470  if (!hasTask(task))
471  mooseError("\"", task, "\" is not a registered task.");
472  std::scoped_lock lock(_completed_tasks_mutex);
473  return _completed_tasks.count(task);
474 }
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:92
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::size_t _physical_memory
Definition: MemoryUtils.h:23
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
Definition: MooseApp.C:2872
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.
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.
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.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters &parameters)
Definition: ActionFactory.C:39
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
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:51
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:353
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.
bool have_parameter(std::string_view name) const
A wrapper around the Parameters base class method.
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:81
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.
const InputParameters & parameters() const
Get the parameters of the object.
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