www.mooseframework.org
Factory.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 "Factory.h"
11 #include "InfixIterator.h"
13 // Just for testing...
14 #include "Diffusion.h"
15 
16 Factory::Factory(MooseApp & app) : _app(app) {}
17 
19 
20 void
21 Factory::reg(const std::string & label,
22  const std::string & obj_name,
23  const buildPtr & build_ptr,
24  const paramsPtr & params_ptr,
25  const std::string & deprecated_time,
26  const std::string & replacement_name,
27  const std::string & file,
28  int line)
29 {
30  // do nothing if we have already added this exact object before
31  auto key = std::make_pair(label, obj_name);
32  if (_objects_by_label.find(key) != _objects_by_label.end())
33  return;
34 
35  /*
36  * If _registerable_objects has been set the user has requested that we only register some
37  * subset
38  * of the objects for a dynamically loaded application. The objects listed in *this*
39  * application's
40  * registerObjects() method will have already been registered before that member was set.
41  *
42  * If _registerable_objects is empty, the factory is unrestricted
43  */
44  if (_registerable_objects.empty() ||
45  _registerable_objects.find(obj_name) != _registerable_objects.end())
46  {
47  if (_name_to_build_pointer.find(obj_name) != _name_to_build_pointer.end())
48  mooseError("Object '" + obj_name + "' registered from multiple files: ",
49  file,
50  " and ",
51  _name_to_line.getInfo(obj_name).file());
52  _name_to_build_pointer[obj_name] = build_ptr;
53  _name_to_params_pointer[obj_name] = params_ptr;
54  _objects_by_label.insert(key);
55  }
56  _name_to_line.addInfo(obj_name, file, line);
57 
58  if (!replacement_name.empty())
59  _deprecated_name[obj_name] = replacement_name;
60  if (!deprecated_time.empty())
61  _deprecated_time[obj_name] = parseTime(deprecated_time);
62 
63  // TODO: Possibly store and print information about objects that are skipped here?
64 }
65 
67 Factory::getValidParams(const std::string & obj_name)
68 {
69  std::map<std::string, paramsPtr>::iterator it = _name_to_params_pointer.find(obj_name);
70 
71  // Check if the object is registered
72  if (it == _name_to_params_pointer.end())
73  reportUnregisteredError(obj_name);
74 
75  // Print out deprecated message, if it exists
76  deprecatedMessage(obj_name);
77 
78  // Return the parameters
79  paramsPtr & func = it->second;
80  InputParameters params = (*func)();
81  params.addPrivateParam("_moose_app", &_app);
82 
83  return params;
84 }
85 
87 Factory::getADValidParams(const std::string & obj_name)
88 {
89  return getValidParams(obj_name + "<RESIDUAL>");
90 }
91 
93 Factory::create(const std::string & obj_name,
94  const std::string & name,
95  InputParameters & parameters,
96  THREAD_ID tid /* =0 */,
97  bool print_deprecated /* =true */)
98 {
99  if (print_deprecated)
100  mooseDeprecated("Factory::create() is deprecated, please use Factory::create<T>() instead");
101 
102  // Pointer to the object constructor
103  std::map<std::string, buildPtr>::iterator it = _name_to_build_pointer.find(obj_name);
104 
105  // Check if the object is registered
106  if (it == _name_to_build_pointer.end())
107  reportUnregisteredError(obj_name);
108 
109  // Print out deprecated message, if it exists
110  deprecatedMessage(obj_name);
111 
112  // Create the actual parameters object that the object will reference
113  InputParameters & params =
114  _app.getInputParameterWarehouse().addInputParameters(name, parameters, tid);
115 
116  // Set the _type parameter
117  params.set<std::string>("_type") = obj_name;
118 
119  // Check to make sure that all required parameters are supplied
120  params.checkParams(name);
121 
122  // register type name as constructed
123  _constructed_types.insert(obj_name);
124 
125  // add FEProblem pointers to object's params object
127  _app.actionWarehouse().problemBase()->setInputParametersFEProblem(params);
128 
129  // call the function pointer to build the object
130  buildPtr & func = it->second;
131  auto obj = (*func)(params);
132 
133  auto fep = std::dynamic_pointer_cast<FEProblemBase>(obj);
134  if (fep)
135  _app.actionWarehouse().problemBase() = fep;
136 
137  // Make sure no unexpected parameters were added by the object's constructor or by the action
138  // initiating this create call. All parameters modified by the constructor must have already
139  // been specified in the object's validParams function.
140  InputParameters orig_params = getValidParams(obj_name);
141  if (orig_params.n_parameters() != parameters.n_parameters())
142  {
143  std::set<std::string> orig, populated;
144  for (const auto & it : orig_params)
145  orig.emplace(it.first);
146  for (const auto & it : parameters)
147  populated.emplace(it.first);
148 
149  std::set<std::string> diff;
150  std::set_difference(populated.begin(),
151  populated.end(),
152  orig.begin(),
153  orig.end(),
154  std::inserter(diff, diff.begin()));
155 
156  if (!diff.empty())
157  {
158  std::stringstream ss;
159  for (const auto & name : diff)
160  ss << ", " << name;
161  mooseError("attempted to set unregistered parameter(s) for ",
162  obj_name,
163  " object:\n ",
164  ss.str().substr(2));
165  }
166  }
167 
168  return obj;
169 }
170 
171 void
173 {
175 }
176 
177 void
178 Factory::restrictRegisterableObjects(const std::vector<std::string> & names)
179 {
180  _registerable_objects.insert(names.begin(), names.end());
181 }
182 
183 std::time_t
184 Factory::parseTime(const std::string t_str)
185 {
186  // The string must be a certain length to be valid
187  if (t_str.size() != 16)
188  mooseError("The deprecated time not formatted correctly; it must be given as mm/dd/yyyy HH:MM");
189 
190  // Store the time, the time must be specified as: mm/dd/yyyy HH:MM
191  std::time_t t_end;
192  struct tm * t_end_info;
193  time(&t_end);
194  t_end_info = localtime(&t_end);
195  t_end_info->tm_mon = std::atoi(t_str.substr(0, 2).c_str()) - 1;
196  t_end_info->tm_mday = std::atoi(t_str.substr(3, 2).c_str());
197  t_end_info->tm_year = std::atoi(t_str.substr(6, 4).c_str()) - 1900;
198  t_end_info->tm_hour = std::atoi(t_str.substr(11, 2).c_str()) + 1;
199  t_end_info->tm_min = std::atoi(t_str.substr(14, 2).c_str());
200  t_end_info->tm_sec = 0;
201  t_end = mktime(t_end_info);
202  return t_end;
203 }
204 
205 void
206 Factory::deprecatedMessage(const std::string obj_name)
207 {
208  std::map<std::string, std::time_t>::iterator time_it = _deprecated_time.find(obj_name);
209 
210  // If the object is not deprecated return
211  if (time_it == _deprecated_time.end())
212  return;
213 
214  // Get the current time
215  std::time_t now;
216  time(&now);
217 
218  // Get the stop time
219  std::time_t t_end = time_it->second;
220 
221  // Message storage
222  std::ostringstream msg;
223 
224  std::map<std::string, std::string>::iterator name_it = _deprecated_name.find(obj_name);
225 
226  // Expired object
227  if (now > t_end)
228  {
229  msg << "***** Invalid Object: " << obj_name << " *****\n";
230  msg << "Expired on " << ctime(&t_end);
231 
232  // Append replacement object, if it exsits
233  if (name_it != _deprecated_name.end())
234  msg << "Update your application using the '" << name_it->second << "' object";
235 
236  // Produce the error message
237  mooseDeprecationExpired(msg.str());
238  }
239 
240  // Expiring object
241  else
242  {
243  // Build the basic message
244  msg << "Deprecated Object: " << obj_name << "\n";
245  msg << "This object will be removed on " << ctime(&t_end);
246 
247  // Append replacement object, if it exsits
248  if (name_it != _deprecated_name.end())
249  msg << "Replace " << obj_name << " with " << name_it->second;
250 
251  // Produce the error message
252  mooseDeprecated(msg.str());
253  }
254 }
255 
256 void
257 Factory::reportUnregisteredError(const std::string & obj_name) const
258 {
259  // Make sure that we don't have an improperly registered object first
261 
262  std::ostringstream oss;
263  std::set<std::string> paths = _app.getLoadedLibraryPaths();
264 
265  oss << "A '" + obj_name + "' is not a registered object.\n";
266 
267  if (!paths.empty())
268  {
269  oss << "\nWe loaded objects from the following libraries and still couldn't find your "
270  "object:\n\t";
271  std::copy(paths.begin(), paths.end(), infix_ostream_iterator<std::string>(oss, "\n\t"));
272  oss << '\n';
273  }
274 
275  oss << "\nIf you are trying to find this object in a dynamically linked library, make sure that\n"
276  "the library can be found either in your \"Problem/library_path\" parameter or in the\n"
277  "MOOSE_LIBRARY_PATH environment variable.";
278 
279  mooseError(oss.str());
280 }
281 
282 std::vector<std::string>
284 {
285  std::vector<std::string> list;
286  for (const auto & name : _constructed_types)
287  list.push_back(name);
288  return list;
289 }
290 
292 Factory::getLineInfo(const std::string & name) const
293 {
294  return _name_to_line.getInfo(name);
295 }
296 
297 void
298 Factory::associateNameToClass(const std::string & name, const std::string & class_name)
299 {
300  _name_to_class[name] = class_name;
301 }
302 
303 std::string
304 Factory::associatedClassName(const std::string & name) const
305 {
306  auto it = _name_to_class.find(name);
307  if (it == _name_to_class.end())
308  return "";
309  else
310  return it->second;
311 }
312 
313 void
315 {
316  _app.addExecFlag(flag);
317 }
MooseApp::getInputParameterWarehouse
InputParameterWarehouse & getInputParameterWarehouse()
Get the InputParameterWarehouse for MooseObjects.
Definition: MooseApp.C:1428
MooseObjectPtr
std::shared_ptr< MooseObject > MooseObjectPtr
alias to wrap shared pointer type
Definition: Factory.h:123
Factory::create
std::shared_ptr< MooseObject > create(const std::string &obj_name, const std::string &name, InputParameters &parameters, THREAD_ID tid=0, bool print_deprecated=true)
Build an object (must be registered) - THIS METHOD IS DEPRECATED (Use create<T>())
Definition: Factory.C:93
Factory::getValidParams
InputParameters getValidParams(const std::string &name)
Get valid parameters for the object.
Definition: Factory.C:67
THREAD_ID
unsigned int THREAD_ID
Definition: MooseTypes.h:196
Factory::_deprecated_name
std::map< std::string, std::string > _deprecated_name
Storage for the deprecated objects that have replacements.
Definition: Factory.h:391
Factory::_name_to_line
FileLineInfoMap _name_to_line
Definition: Factory.h:382
Factory::_name_to_params_pointer
std::map< std::string, paramsPtr > _name_to_params_pointer
Storage for pointers to the parameters objects.
Definition: Factory.h:380
Factory::reportUnregisteredError
void reportUnregisteredError(const std::string &obj_name) const
Prints error information when an object is not registered.
Definition: Factory.C:257
Factory::associateNameToClass
void associateNameToClass(const std::string &name, const std::string &class_name)
Associates an object name with a class name.
Definition: Factory.C:298
Factory::parseTime
std::time_t parseTime(std::string)
Parse time string (mm/dd/yyyy HH:MM)
Definition: Factory.C:184
Factory::getLineInfo
FileLineInfo getLineInfo(const std::string &name) const
Gets file and line information where an object was initially registered.
Definition: Factory.C:292
InputParameterWarehouse::addInputParameters
InputParameters & addInputParameters(const std::string &name, InputParameters &parameters, THREAD_ID tid=0)
Method for adding a new InputParameters object.
Definition: InputParameterWarehouse.C:20
MooseApp::checkRegistryLabels
virtual void checkRegistryLabels()
Definition: MooseApp.C:450
MooseApp::getLoadedLibraryPaths
std::set< std::string > getLoadedLibraryPaths() const
Return the loaded library filenames in a std::set.
Definition: MooseApp.C:1417
Factory::_name_to_class
std::map< std::string, std::string > _name_to_class
Object name to class name association.
Definition: Factory.h:385
Factory::_registerable_objects
std::set< std::string > _registerable_objects
The list of objects that may be registered.
Definition: Factory.h:394
FileLineInfo
Holds file and line information.
Definition: FileLineInfo.h:18
mooseError
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition: MooseError.h:210
MooseObject
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:50
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
InputParameters::set
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
Definition: InputParameters.h:987
Factory::Factory
Factory(MooseApp &app)
Definition: Factory.C:16
buildPtr
MooseObjectPtr(*)(const InputParameters &parameters) buildPtr
alias for method to build objects
Definition: Factory.h:133
Factory::getConstructedObjects
std::vector< std::string > getConstructedObjects() const
Get a list of all constructed Moose Object types.
Definition: Factory.C:283
FileLineInfo::file
std::string file() const
Definition: FileLineInfo.C:29
InputParameterWarehouse::removeInputParameters
void removeInputParameters(const MooseObject &moose_object, THREAD_ID tid=0)
Allows for the deletion and cleanup of an object while the simulation is running.
Definition: InputParameterWarehouse.C:102
Factory::_name_to_build_pointer
std::map< std::string, buildPtr > _name_to_build_pointer
Storage for pointers to the object.
Definition: Factory.h:377
Factory::restrictRegisterableObjects
void restrictRegisterableObjects(const std::vector< std::string > &names)
Calling this object with a non-empty vector will cause this factory to ignore registrations from any ...
Definition: Factory.C:178
mooseDeprecated
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:239
MooseEnumItem
Class for containing MooseEnum item information.
Definition: MooseEnumItem.h:21
Factory::deprecatedMessage
void deprecatedMessage(const std::string obj_name)
Show the appropriate message for deprecated objects.
Definition: Factory.C:206
MooseApp::actionWarehouse
ActionWarehouse & actionWarehouse()
Return a writable reference to the ActionWarehouse associated with this app.
Definition: MooseApp.h:153
Factory::reg
void reg(const std::string &obj_name, const std::string &file="", int line=-1)
Register a new object.
Definition: Factory.h:164
Factory::associatedClassName
std::string associatedClassName(const std::string &name) const
Get the associated class name for an object name.
Definition: Factory.C:304
InputParameterWarehouse.h
Factory::regExecFlag
void regExecFlag(const ExecFlagType &flag)
Add a new flag to the app.
Definition: Factory.C:314
Factory::_objects_by_label
std::set< std::pair< std::string, std::string > > _objects_by_label
set<label/appname, objectname> used to track if an object previously added is being added again - whi...
Definition: Factory.h:405
Factory::_deprecated_time
std::map< std::string, std::time_t > _deprecated_time
Storage for deprecated object experiation dates.
Definition: Factory.h:388
FileLineInfoMap::addInfo
void addInfo(const std::string &key0, const std::string &file, int line)
Associate a key with file/line info.
Definition: FileLineInfo.C:35
MooseApp
Base class for MOOSE-based applications.
Definition: MooseApp.h:61
ActionWarehouse::problemBase
std::shared_ptr< FEProblemBase > & problemBase()
Definition: ActionWarehouse.h:219
Factory::_constructed_types
std::set< std::string > _constructed_types
Constructed Moose Object types.
Definition: Factory.h:400
InfixIterator.h
MooseApp::addExecFlag
void addExecFlag(const ExecFlagType &flag)
WARNING: This is an internal method for MOOSE, if you need the add new ExecFlagTypes then use the reg...
Definition: MooseApp.C:1829
InputParameters::addPrivateParam
void addPrivateParam(const std::string &name, const T &value)
These method add a parameter to the InputParameters object which can be retrieved like any other para...
Definition: InputParameters.h:1308
Factory::~Factory
virtual ~Factory()
Definition: Factory.C:18
Factory::releaseSharedObjects
void releaseSharedObjects(const MooseObject &moose_object, THREAD_ID tid=0)
Releases any shared resources created as a side effect of creating an object through the Factory::cre...
Definition: Factory.C:172
Factory.h
InputParameters::checkParams
void checkParams(const std::string &parsing_syntax)
This function checks parameters stored in the object to make sure they are in the correct state as th...
Definition: InputParameters.C:409
FileLineInfoMap::getInfo
FileLineInfo getInfo(const std::string &key0) const
Get file/line info for a key.
Definition: FileLineInfo.C:76
Diffusion.h
mooseDeprecationExpired
void mooseDeprecationExpired(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition: MooseError.h:247
infix_ostream_iterator
Definition: InfixIterator.h:19
Factory::_app
MooseApp & _app
Reference to the application.
Definition: Factory.h:374
paramsPtr
InputParameters(*)() paramsPtr
alias for validParams function
Definition: AppFactory.h:32
Factory::getADValidParams
InputParameters getADValidParams(const std::string &name)
Definition: Factory.C:87