22 #ifndef _aspect_plugins_h 23 #define _aspect_plugins_h 27 #include <deal.II/base/utilities.h> 28 #include <deal.II/base/parameter_handler.h> 30 #include <deal.II/base/exceptions.h> 32 #include <boost/core/demangle.hpp> 60 template <
typename TestType,
typename PluginType>
65 return (dynamic_cast<const TestType *> (&
object) !=
nullptr);
77 template <
typename TestType,
typename PluginType>
82 AssertThrow(plugin_type_matches<TestType>(
object),
83 ExcMessage(
"You have requested to convert a plugin of type <" 84 + boost::core::demangle(
typeid(PluginType).name())
86 + boost::core::demangle(
typeid(TestType).name()) +
87 ">, but this cast cannot be performed."));
92 return *
dynamic_cast<TestType *
> (&object);
116 template <
typename InterfaceClass,
127 void ( *)(ParameterHandler &),
128 std::unique_ptr<InterfaceClass> ( *)()),
130 const char *description)
132 register_function (name,
145 return std::make_unique<ModelClass>();
154 template <
typename InterfaceClass>
169 = std::tuple<std::string,
171 void ( *) (ParameterHandler &),
172 std::unique_ptr<InterfaceClass>( *) ()>;
199 void register_plugin (
const std::string &name,
200 const std::string &description,
201 void (*declare_parameters_function) (ParameterHandler &),
202 std::unique_ptr<InterfaceClass> (*factory_function) ());
212 std::string get_pattern_of_names ();
222 std::string get_description_string ();
240 std::unique_ptr<InterfaceClass>
241 create_plugin (
const std::string &name,
242 const std::string &documentation);
255 std::unique_ptr<InterfaceClass>
256 create_plugin (
const std::string &name,
257 const std::string &documentation,
258 ParameterHandler &prm);
284 std::ostream &output_stream,
285 const std::string &attachment_point =
"Simulator");
292 <<
"Can't create a plugin of name <" << arg1
293 <<
"> because such a plugin hasn't been declared.");
299 template <
typename InterfaceClass>
305 if (plugins !=
nullptr)
312 template <
typename InterfaceClass>
316 const std::string &description,
317 void (*declare_parameters_function) (ParameterHandler &),
318 std::unique_ptr<InterfaceClass> (*factory_function) ())
322 if (plugins ==
nullptr)
323 plugins =
new std::list<PluginInfo>();
328 for (
const auto &p : *plugins)
330 Assert (std::get<0>(p) != name,
331 ExcMessage (
"A plugin with name <" + name +
"> has " 332 "already been registered!"));
338 plugins->emplace_back (name,
340 declare_parameters_function,
346 template <
typename InterfaceClass>
351 Assert (plugins !=
nullptr,
352 ExcMessage (
"No plugins registered!?"));
356 std::set<std::string> names;
357 for (
typename std::list<PluginInfo>::const_iterator
358 p = plugins->begin();
359 p != plugins->end(); ++p)
360 names.insert (std::get<0>(*p));
363 std::string pattern_of_names;
364 for (
const auto &name : names)
366 if (pattern_of_names.size() > 0)
367 pattern_of_names +=
"|";
368 pattern_of_names += name;
371 return pattern_of_names;
376 template <
typename InterfaceClass>
381 std::string description;
385 std::map<std::string,std::string> names_and_descriptions;
386 for (
typename std::list<PluginInfo>::const_iterator
387 p = plugins->begin();
388 p != plugins->end(); ++p)
389 names_and_descriptions[std::get<0>(*p)] = std::get<1>(*p);
392 std::map<std::string,std::string>::const_iterator
393 p = names_and_descriptions.begin();
400 description += p->first;
401 description +=
"': ";
402 description += p->second;
409 if (p != names_and_descriptions.end())
410 description +=
"\n\n";
421 template <
typename InterfaceClass>
426 Assert (plugins !=
nullptr,
427 ExcMessage (
"No postprocessors registered!?"));
429 for (
typename std::list<PluginInfo>::const_iterator
430 p = plugins->begin();
431 p != plugins->end(); ++p)
432 (std::get<2>(*p))(prm);
437 template <
typename InterfaceClass>
438 std::unique_ptr<InterfaceClass>
441 const std::string &documentation)
444 Assert (plugins !=
nullptr,
445 ExcMessage (
"No postprocessors registered!?"));
446 AssertThrow (name !=
"unspecified",
447 ExcMessage(std::string(
"A plugin must have a name!\n\n" 448 "This function was asked to create a plugin but no name for the " 449 "plugin was provided. This may be due to the fact that you did not " 450 "explicitly specify a name for this plugin in your input file and " 451 "ASPECT does not provide a default for this kind of plugin, for " 452 "example because no generally useful plugin exists. An example " 453 "is that there is no default geometry: You need to explicitly " 454 "provide one in the input file, and it seems like you have not " 456 "To find out which kind of plugin this function tries to create, " 457 "take a look at the backtrace of this error message.\n\n" 458 "The place that called this function also provided as " 459 "additional information this:\n\n" 461 + documentation +
">"));
463 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
464 p != plugins->end(); ++p)
465 if (std::get<0>(*p) == name)
467 std::unique_ptr<InterfaceClass> i = std::get<3>(*p)();
471 AssertThrow (
false, ExcUnknownPlugin(name));
477 template <
typename InterfaceClass>
478 std::unique_ptr<InterfaceClass>
481 const std::string &documentation,
482 ParameterHandler &prm)
484 std::unique_ptr<InterfaceClass> i = create_plugin(name, documentation);
485 i->parse_parameters (prm);
491 template <
typename InterfaceClass>
495 std::ostream &output_stream,
496 const std::string &attachment_point)
504 output_stream << std::string(
typeid(InterfaceClass).name())
506 << plugin_system_name
507 <<
"\", height=.8,width=.8,shape=\"rect\",fillcolor=\"green\"]" 519 std::map<std::string, typename std::list<PluginInfo>::const_iterator>
521 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
522 p != plugins->end(); ++p)
523 plugin_map[std::get<0>(*p)] = p;
526 for (
typename std::map<std::string,
typename std::list<PluginInfo>::const_iterator>::const_iterator
527 p = plugin_map.begin();
528 p != plugin_map.end(); ++p)
534 const std::vector<std::string> plugin_label_parts
535 = ::Utilities::break_text_into_lines(p->first, 15);
536 Assert (plugin_label_parts.size()>0, ExcInternalError());
537 std::string plugin_name = plugin_label_parts[0];
538 for (
unsigned int i=1; i<plugin_label_parts.size(); ++i)
539 plugin_name +=
"\\n" + plugin_label_parts[i];
544 std::unique_ptr<InterfaceClass> instance (create_plugin (p->first,
""));
545 const std::string node_name =
typeid(*instance).name();
548 output_stream << node_name
551 <<
"\", height=.8,width=.8,shape=\"circle\",fillcolor=\"lightblue\"];" 556 output_stream << node_name
558 << std::string(
typeid(InterfaceClass).name())
559 <<
" [len=3, weight=50]" 569 output_stream <<
"SimulatorAccess" 572 <<
" [style=\"dotted\", arrowhead=\"empty\", constraint=false, color=\"gray\", len=20, weight=0.1];" 579 output_stream << std::string(
typeid(InterfaceClass).name())
582 <<
" [len=15, weight=50]" 588 output_stream << std::endl;
bool plugin_type_matches(const PluginType &object)
void write_plugin_graph(std::ostream &output_stream)
RegisterHelper(void(*register_function)(const std::string &, const std::string &, void(*)(ParameterHandler &), std::unique_ptr< InterfaceClass >(*)()), const char *name, const char *description)
static std::list< PluginInfo > * plugins
TestType & get_plugin_as_type(PluginType &object)
std::tuple< std::string, std::string, void(*)(ParameterHandler &), std::unique_ptr< InterfaceClass >(*)()> PluginInfo
void declare_parameters(ParameterHandler &prm)
static std::unique_ptr< InterfaceClass > factory()
DeclException1(ProbabilityFunctionNegative, Point< dim >,<< "Your probability density function in the particle generator " "returned a negative probability density for the following position: "<< arg1<< ". Please check your function expression.")