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 
23 #include "libmesh/simple_range.h"
24 
27  _app(app),
28  _syntax(syntax),
29  _action_factory(factory),
30  _generator_valid(false),
31  _show_actions(false),
32  _show_parser(false)
33 {
34 }
35 
37 
38 void
39 ActionWarehouse::setFinalTask(const std::string & task)
40 {
41  if (!_syntax.hasTask(task))
42  mooseError("cannot use unregistered task '", task, "' as final task");
43  _final_task = task;
44 }
45 
46 void
48 {
50  for (const auto & name : _ordered_names)
52 }
53 
54 void
56 {
57  for (auto & ptr : _all_ptrs)
58  ptr.reset();
59 
60  _action_blocks.clear();
61  _generator_valid = false;
62 
63  // Due to the way ActionWarehouse is cleaned up (see MooseApp's
64  // destructor) we must guarantee that ActionWarehouse::clear()
65  // releases all the resources which have to be released _before_ the
66  // _comm object owned by the MooseApp is destroyed.
67  _problem.reset();
68  _displaced_mesh.reset();
69  _mesh.reset();
70 }
71 
72 void
73 ActionWarehouse::addActionBlock(std::shared_ptr<Action> action)
74 {
82  std::string registered_identifier =
83  action->parameters().get<std::string>("registered_identifier");
84  std::set<std::string> tasks;
85 
86  if (_show_parser)
87  Moose::err << COLOR_DEFAULT << "Parsing Syntax: " << COLOR_GREEN << action->name()
88  << '\n'
89  << COLOR_DEFAULT << "Building Action: " << COLOR_DEFAULT << action->type()
90  << '\n'
91  << COLOR_DEFAULT << "Registered Identifier: " << COLOR_GREEN << registered_identifier
92  << '\n'
93  << COLOR_DEFAULT << "Specific Task: " << COLOR_CYAN
94  << action->specificTaskName() << '\n';
95 
116  if (action->specificTaskName() != "") // Case 1
117  tasks.insert(action->specificTaskName());
118  else if (registered_identifier == "" &&
119  _syntax.getSyntaxByAction(action->type()).size() > 1) // Case 2
120  {
121  std::set<std::string> local_tasks = action->getAllTasks();
122  mooseAssert(local_tasks.size() == 1, "More than one task inside of the " << action->name());
123  tasks.insert(*local_tasks.begin());
124  }
125  else // Case 3
126  tasks = _action_factory.getTasksByAction(action->type());
127 
128  // TODO: Now we need to weed out the double registrations!
129  for (const auto & task : tasks)
130  {
131  // Some error checking
132  if (!_syntax.hasTask(task))
133  mooseError("A(n) ", task, " is not a registered task");
134 
135  // Make sure that the ObjectAction task and Action task are consistent
136  // otherwise that means that is action was built by the wrong type
137  std::shared_ptr<MooseObjectAction> moa = std::dynamic_pointer_cast<MooseObjectAction>(action);
138  if (moa.get())
139  {
140  const InputParameters & mparams = moa->getObjectParams();
141 
142  if (mparams.have_parameter<std::string>("_moose_base"))
143  {
144  const std::string & base = mparams.get<std::string>("_moose_base");
145 
146  if (!_syntax.verifyMooseObjectTask(base, task))
147  mooseError("Task ", task, " is not registered to build ", base, " derived objects");
148  }
149  else
150  mooseError("Unable to locate registered base parameter for ", moa->getMooseObjectType());
151  }
152 
153  // Add the current task to current action
154  action->appendTask(task);
155 
156  if (_show_parser)
157  Moose::err << COLOR_YELLOW << "Adding Action: " << COLOR_DEFAULT << action->type()
158  << " (" << COLOR_YELLOW << task << COLOR_DEFAULT << ")\n";
159 
160  // Add it to the warehouse
161  _action_blocks[task].push_back(action.get());
162  }
163  _all_ptrs.push_back(action);
164 
165  if (_show_parser)
166  Moose::err << std::endl;
167 }
168 
171 {
172  return _action_blocks[task].begin();
173 }
174 
177 {
178  return _action_blocks[task].end();
179 }
180 
181 const std::vector<std::shared_ptr<Action>> &
183 {
184  return _all_ptrs;
185 }
186 
187 const std::list<Action *> &
188 ActionWarehouse::getActionListByName(const std::string & task) const
189 {
190  const auto it = _action_blocks.find(task);
191  if (it == _action_blocks.end())
192  return _empty_action_list;
193  else
194  return it->second;
195 }
196 
197 bool
198 ActionWarehouse::hasActions(const std::string & task) const
199 {
200  return _action_blocks.find(task) != _action_blocks.end();
201 }
202 
203 void
204 ActionWarehouse::buildBuildableActions(const std::string & task)
205 {
206  if (_syntax.shouldAutoBuild(task) && _action_blocks[task].empty())
207  {
208  bool ret_value = false;
209  auto it_pair = _action_factory.getActionsByTask(task);
210  for (const auto & action_pair : as_range(it_pair))
211  {
212  InputParameters params = _action_factory.getValidParams(action_pair.second);
213  params.set<ActionWarehouse *>("awh") = this;
214 
215  if (params.areAllRequiredParamsValid())
216  {
217  params.set<std::string>("registered_identifier") = "(AutoBuilt)";
218  addActionBlock(_action_factory.create(action_pair.second, "", params));
219  ret_value = true;
220  }
221  }
222 
223  if (!ret_value)
224  _unsatisfied_dependencies.insert(task);
225  }
226 }
227 
228 void
230 {
231  std::stringstream oss;
232  bool empty = true;
233 
234  for (const auto & udep : _unsatisfied_dependencies)
235  {
236  if (_action_blocks.find(udep) == _action_blocks.end())
237  {
238  if (empty)
239  empty = false;
240  else
241  oss << " ";
242  oss << udep;
243  }
244  }
245 
246  if (!empty)
247  mooseError(
248  std::string(
249  "The following unsatisfied actions where found while setting up the MOOSE problem:\n") +
250  oss.str() + "\n");
251 }
252 
253 void
255 {
265  std::ostringstream oss;
266 
267  const auto & ordered_names = _syntax.getSortedTaskSet();
268  for (const auto & task_vector : ordered_names)
269  {
270  oss << "[DBG][ACT] (" << COLOR_YELLOW;
271  std::copy(
272  task_vector.begin(), task_vector.end(), infix_ostream_iterator<std::string>(oss, ", "));
273  oss << COLOR_DEFAULT << ")\n";
274 
275  std::set<std::string> task_set(task_vector.begin(), task_vector.end());
276  for (const auto & task : task_set)
277  {
278  if (_action_blocks.find(task) == _action_blocks.end())
279  continue;
280 
281  for (const auto & act : _action_blocks.at(task))
282  {
283  // The Syntax of the Action if it exists
284  if (act->name() != "")
285  oss << "[DBG][ACT]\t" << COLOR_GREEN << act->name() << COLOR_DEFAULT << '\n';
286 
287  // The task sets
288  oss << "[DBG][ACT]\t" << act->type();
289  const std::set<std::string> tasks = act->getAllTasks();
290  if (tasks.size() > 1)
291  {
292  oss << " (";
293  // Break the current Action's tasks into 2 sets, those intersecting with current set and
294  // then the difference.
295  std::set<std::string> intersection, difference;
296  std::set_intersection(tasks.begin(),
297  tasks.end(),
298  task_set.begin(),
299  task_set.end(),
300  std::inserter(intersection, intersection.end()));
301  std::set_difference(tasks.begin(),
302  tasks.end(),
303  intersection.begin(),
304  intersection.end(),
305  std::inserter(difference, difference.end()));
306 
307  oss << COLOR_CYAN;
308  std::copy(intersection.begin(),
309  intersection.end(),
311  oss << COLOR_MAGENTA << (difference.empty() ? "" : ", ");
312  std::copy(
313  difference.begin(), difference.end(), infix_ostream_iterator<std::string>(oss, ", "));
314  oss << COLOR_DEFAULT << ")";
315  }
316  oss << '\n';
317  }
318  }
319  }
320 
321  if (_show_actions)
322  _console << oss.str() << std::endl;
323 }
324 
325 void
327 {
328  if (_show_actions)
329  {
330  _console << "[DBG][ACT] Action Dependency Sets:\n";
332 
333  _console << "\n[DBG][ACT] Executing actions:" << std::endl;
334  }
335 
336  for (const auto & task : _ordered_names)
337  {
339  if (_final_task != "" && task == _final_task)
340  break;
341  }
342 }
343 
344 void
346 {
347  // Set the current task name
348  _current_task = task;
349 
351  ++_act_iter)
352  {
353  if (_show_actions)
354  _console << "[DBG][ACT] "
355  << "TASK (" << COLOR_YELLOW << std::setw(24) << task << COLOR_DEFAULT << ") "
356  << "TYPE (" << COLOR_YELLOW << std::setw(32) << (*_act_iter)->type() << COLOR_DEFAULT
357  << ") "
358  << "NAME (" << COLOR_YELLOW << std::setw(16) << (*_act_iter)->name() << COLOR_DEFAULT
359  << ")" << std::endl;
360 
361  (*_act_iter)->timedAct();
362  }
363 }
364 
365 void
367 {
368  InputFileFormatter tree(false);
369 
370  std::map<std::string, std::vector<Action *>>::iterator iter;
371 
372  std::vector<Action *> ordered_actions;
373  for (const auto & block : _action_blocks)
374  for (const auto & act : block.second)
375  ordered_actions.push_back(act);
376 
377  for (const auto & act : ordered_actions)
378  {
379  std::string name;
380  if (act->parameters().blockFullpath() != "")
381  name = act->parameters().blockFullpath();
382  else
383  name = act->name();
384  const std::set<std::string> & tasks = act->getAllTasks();
385  mooseAssert(!tasks.empty(), "Task list is empty");
386 
387  bool is_parent;
388  if (_syntax.isAssociated(name, &is_parent) != "")
389  {
390  InputParameters params = act->parameters();
391 
392  // TODO: Do we need to insert more nodes for each task?
393  tree.insertNode(name, *tasks.begin(), true, &params);
394 
395  MooseObjectAction * moose_object_action = dynamic_cast<MooseObjectAction *>(act);
396  if (moose_object_action)
397  {
398  InputParameters obj_params = moose_object_action->getObjectParams();
399  tree.insertNode(name, *tasks.begin(), false, &obj_params);
400  }
401  }
402  }
403 
404  out << tree.print("");
405 }
406 
407 std::shared_ptr<FEProblem>
409 {
411  "ActionWarehouse::problem() is deprecated, please use ActionWarehouse::problemBase() \n");
413 }
414 
415 std::string
417 {
418  return (*_act_iter)->parameters().blockFullpath();
419 }
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:112
void checkUnsatisfiedActions() const
This method checks the actions stored in the warehouse against the list of required registered action...
std::list< Action * >::iterator ActionIterator
alias to hide implementation details
Specialization of SubProblem for solving nonlinear equations plus auxiliary equations.
Definition: FEProblem.h:24
InputParameters getValidParams(const std::string &name)
Definition: ActionFactory.C:70
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:207
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
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:59
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:100
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::vector< std::string > getSyntaxByAction(const std::string &action, const std::string &task="")
Retrieve the syntax associated with the passed in action type string.
Definition: Syntax.C:192
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:125
std::string isAssociated(const std::string &real_id, bool *is_parent) const
Method for determining whether a piece of syntax is associated with an Action TODO: I need a better n...
Definition: Syntax.C:218
InputParameters & getObjectParams()
Retreive the parameters of the object to be created by this action.
bool empty() const
returns a Boolean indicating whether the warehouse is empty or not.
bool areAllRequiredParamsValid() const
This method returns true if all of the parameters in this object are valid (i.e.
Specialized factory for generic Action System objects.
Definition: ActionFactory.h:64
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:106
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:236
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.
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.
const std::vector< std::shared_ptr< Action > > & allActionBlocks() const
Returns a reference to all of the actions.
void build()
Builds all auto-buildable tasks.
Holding syntax for parsing input files.
Definition: Syntax.h:20
std::shared_ptr< Action > create(const std::string &action, const std::string &action_name, InputParameters parameters)
Definition: ActionFactory.C:41
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:286
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.
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.
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 InputFileParameters that appears like the normal input fil...
std::string _current_task