www.mooseframework.org
ActionWarehouse.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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  _mesh(nullptr),
37  _displaced_mesh(nullptr)
38 {
39 }
40 
42 
43 void
44 ActionWarehouse::setFinalTask(const std::string & task)
45 {
46  if (!_syntax.hasTask(task))
47  mooseError("cannot use unregistered task '", task, "' as final task");
48  _final_task = task;
49 }
50 
51 void
53 {
55  for (const auto & name : _ordered_names)
57 }
58 
59 void
61 {
62  for (auto & ptr : _all_ptrs)
63  ptr.reset();
64 
65  _action_blocks.clear();
66  _generator_valid = false;
67 
68  // Due to the way ActionWarehouse is cleaned up (see MooseApp's
69  // destructor) we must guarantee that ActionWarehouse::clear()
70  // releases all the resources which have to be released _before_ the
71  // _comm object owned by the MooseApp is destroyed.
72  _problem.reset();
73  _displaced_mesh.reset();
74  _mesh.reset();
75 }
76 
77 void
78 ActionWarehouse::addActionBlock(std::shared_ptr<Action> action)
79 {
87  std::string registered_identifier =
88  action->parameters().get<std::string>("registered_identifier");
89  std::set<std::string> tasks;
90 
91  if (_show_parser)
92  Moose::err << COLOR_DEFAULT << "Parsing Syntax: " << COLOR_GREEN << action->name()
93  << '\n'
94  << COLOR_DEFAULT << "Building Action: " << COLOR_DEFAULT << action->type()
95  << '\n'
96  << COLOR_DEFAULT << "Registered Identifier: " << COLOR_GREEN << registered_identifier
97  << '\n'
98  << COLOR_DEFAULT << "Specific Task: " << COLOR_CYAN
99  << action->specificTaskName() << std::endl;
100 
121  if (action->specificTaskName() != "") // Case 1
122  tasks.insert(action->specificTaskName());
123  else if (registered_identifier == "" &&
124  _syntax.getNonDeprecatedSyntaxByAction(action->type()).size() > 1) // Case 2
125  {
126  std::set<std::string> local_tasks = action->getAllTasks();
127  mooseAssert(local_tasks.size() == 1, "More than one task inside of the " << action->name());
128  tasks.insert(*local_tasks.begin());
129  }
130  else // Case 3
131  tasks = _action_factory.getTasksByAction(action->type());
132 
133  // TODO: Now we need to weed out the double registrations!
134  for (const auto & task : tasks)
135  {
136  // Some error checking
137  if (!_syntax.hasTask(task))
138  mooseError("A(n) ", task, " is not a registered task");
139 
140  // Make sure that the ObjectAction task and Action task are consistent
141  // otherwise that means that is action was built by the wrong type
142  std::shared_ptr<MooseObjectAction> moa = std::dynamic_pointer_cast<MooseObjectAction>(action);
143  if (moa.get())
144  {
145  const InputParameters & mparams = moa->getObjectParams();
146 
147  if (mparams.have_parameter<std::string>("_moose_base"))
148  {
149  const std::string & base = mparams.get<std::string>("_moose_base");
150 
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  _completed_tasks.insert(task);
348  if (_final_task != "" && task == _final_task)
349  break;
350  }
351 
352  if (_show_actions)
353  {
354  MemoryUtils::Stats stats;
356  auto usage =
358  _console << "[DBG][ACT] Finished executing all actions with memory usage " << usage << "MB\n"
359  << std::endl;
360  }
361 }
362 
363 void
365 {
366  // Set the current task name
367  _current_task = task;
368 
370  ++_act_iter)
371  {
372  if (_show_actions)
373  {
374  MemoryUtils::Stats stats;
376  auto usage =
378  _console << "[DBG][ACT] "
379  << "TASK (" << COLOR_YELLOW << std::setw(24) << task << COLOR_DEFAULT << ") "
380  << "TYPE (" << COLOR_YELLOW << std::setw(32) << (*_act_iter)->type() << COLOR_DEFAULT
381  << ") "
382  << "NAME (" << COLOR_YELLOW << std::setw(16) << (*_act_iter)->name() << COLOR_DEFAULT
383  << ") Memory usage " << usage << "MB" << std::endl;
384  }
385 
386  (*_act_iter)->timedAct();
387  }
388 }
389 
390 void
392 {
393  InputFileFormatter tree(false);
394 
395  std::map<std::string, std::vector<Action *>>::iterator iter;
396 
397  std::vector<Action *> ordered_actions;
398  for (const auto & block : _action_blocks)
399  for (const auto & act : block.second)
400  ordered_actions.push_back(act);
401 
402  for (const auto & act : ordered_actions)
403  {
404  std::string name;
405  if (act->parameters().blockFullpath() != "")
406  name = act->parameters().blockFullpath();
407  else
408  name = act->name();
409  const std::set<std::string> & tasks = act->getAllTasks();
410  mooseAssert(!tasks.empty(), "Task list is empty");
411 
412  bool is_parent;
413  if (_syntax.isAssociated(name, &is_parent) != "")
414  {
415  const auto & all_params = _app.getInputParameterWarehouse().getInputParameters();
416  InputParameters & params = *(all_params.find(act->uniqueActionName())->second.get());
417 
418  // temporarily allow input parameter copies required by the input file formatter
419  params.allowCopy(true);
420 
421  // TODO: Do we need to insert more nodes for each task?
422  tree.insertNode(name, *tasks.begin(), true, &params);
423  params.allowCopy(false);
424 
425  MooseObjectAction * moose_object_action = dynamic_cast<MooseObjectAction *>(act);
426  if (moose_object_action)
427  {
428  InputParameters obj_params = moose_object_action->getObjectParams();
429  tree.insertNode(name, *tasks.begin(), false, &obj_params);
430  }
431  }
432  }
433 
434  out << tree.print("");
435 }
436 
437 std::shared_ptr<FEProblem>
439 {
441  "ActionWarehouse::problem() is deprecated, please use ActionWarehouse::problemBase() \n");
443 }
444 
445 std::string
447 {
448  return (*_act_iter)->parameters().blockFullpath();
449 }
450 
451 const std::string &
453 {
454  return _app.name();
455 }
456 
457 bool
458 ActionWarehouse::hasTask(const std::string & task) const
459 {
460  return _action_factory.isRegisteredTask(task);
461 }
462 
463 bool
464 ActionWarehouse::isTaskComplete(const std::string & task) const
465 {
466  if (!hasTask(task))
467  mooseError("\"", task, "\" is not a registered task.");
468  return _completed_tasks.count(task);
469 }
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...
const std::string & name() const
Get the name of the object.
Definition: MooseApp.h:106
unsigned int size(THREAD_ID tid=0) const
Return how many kernels we store in the current warehouse.
std::list< Action * >::iterator ActionIterator
alias to hide implementation details
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:76
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:284
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:2224
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
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:69
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.
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:231
InputParameters & getObjectParams()
Retreive 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.
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)
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:313
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:245
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
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:328
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.
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.
ActionIterator _act_iter
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