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> 40 #include <type_traits> 69 template <
typename TestType,
typename PluginType,
70 typename =
typename std::enable_if<std::is_base_of<PluginType,TestType>::value>::type>
75 return (dynamic_cast<const TestType *> (&
object) !=
nullptr);
95 template <
typename TestType,
typename PluginType,
96 typename =
typename std::enable_if<std::is_base_of<PluginType,TestType>::value>::type>
101 AssertThrow(plugin_type_matches<TestType>(
object),
102 ExcMessage(
"You have requested to convert a plugin of type <" 103 + boost::core::demangle(
typeid(PluginType).name())
105 + boost::core::demangle(
typeid(TestType).name()) +
106 ">, but this cast cannot be performed."));
111 return *
dynamic_cast<TestType *
> (&object);
135 template <
typename InterfaceClass,
146 void ( *)(ParameterHandler &),
147 std::unique_ptr<InterfaceClass> ( *)()),
149 const char *description)
151 register_function (name,
164 return std::make_unique<ModelClass>();
173 template <
typename InterfaceClass>
188 = std::tuple<std::string,
190 void ( *) (ParameterHandler &),
191 std::unique_ptr<InterfaceClass>( *) ()>;
218 void register_plugin (
const std::string &name,
219 const std::string &description,
220 void (*declare_parameters_function) (ParameterHandler &),
221 std::unique_ptr<InterfaceClass> (*factory_function) ());
231 std::string get_pattern_of_names ();
241 std::string get_description_string ();
259 std::unique_ptr<InterfaceClass>
260 create_plugin (
const std::string &name,
261 const std::string &documentation);
274 std::unique_ptr<InterfaceClass>
275 create_plugin (
const std::string &name,
276 const std::string &documentation,
277 ParameterHandler &prm);
303 std::ostream &output_stream,
304 const std::string &attachment_point =
"Simulator");
311 <<
"Can't create a plugin of name <" << arg1
312 <<
"> because such a plugin hasn't been declared.");
318 template <
typename InterfaceClass>
324 if (plugins !=
nullptr)
331 template <
typename InterfaceClass>
335 const std::string &description,
336 void (*declare_parameters_function) (ParameterHandler &),
337 std::unique_ptr<InterfaceClass> (*factory_function) ())
341 if (plugins ==
nullptr)
342 plugins =
new std::list<PluginInfo>();
347 for (
const auto &p : *plugins)
349 Assert (std::get<0>(p) != name,
350 ExcMessage (
"A plugin with name <" + name +
"> has " 351 "already been registered!"));
357 plugins->emplace_back (name,
359 declare_parameters_function,
365 template <
typename InterfaceClass>
370 Assert (plugins !=
nullptr,
371 ExcMessage (
"No plugins registered!?"));
375 std::set<std::string> names;
376 for (
typename std::list<PluginInfo>::const_iterator
377 p = plugins->begin();
378 p != plugins->end(); ++p)
379 names.insert (std::get<0>(*p));
382 std::string pattern_of_names;
383 for (
const auto &name : names)
385 if (pattern_of_names.size() > 0)
386 pattern_of_names +=
"|";
387 pattern_of_names += name;
390 return pattern_of_names;
395 template <
typename InterfaceClass>
400 std::string description;
404 std::map<std::string,std::string> names_and_descriptions;
405 for (
typename std::list<PluginInfo>::const_iterator
406 p = plugins->begin();
407 p != plugins->end(); ++p)
408 names_and_descriptions[std::get<0>(*p)] = std::get<1>(*p);
411 std::map<std::string,std::string>::const_iterator
412 p = names_and_descriptions.begin();
419 description += p->first;
420 description +=
"': ";
421 description += p->second;
428 if (p != names_and_descriptions.end())
429 description +=
"\n\n";
440 template <
typename InterfaceClass>
445 Assert (plugins !=
nullptr,
446 ExcMessage (
"No postprocessors registered!?"));
448 for (
typename std::list<PluginInfo>::const_iterator
449 p = plugins->begin();
450 p != plugins->end(); ++p)
451 (std::get<2>(*p))(prm);
456 template <
typename InterfaceClass>
457 std::unique_ptr<InterfaceClass>
460 const std::string &documentation)
463 Assert (plugins !=
nullptr,
464 ExcMessage (
"No postprocessors registered!?"));
465 AssertThrow (name !=
"unspecified",
466 ExcMessage(std::string(
"A plugin must have a name!\n\n" 467 "This function was asked to create a plugin but no name for the " 468 "plugin was provided. This may be due to the fact that you did not " 469 "explicitly specify a name for this plugin in your input file and " 470 "ASPECT does not provide a default for this kind of plugin, for " 471 "example because no generally useful plugin exists. An example " 472 "is that there is no default geometry: You need to explicitly " 473 "provide one in the input file, and it seems like you have not " 475 "To find out which kind of plugin this function tries to create, " 476 "take a look at the backtrace of this error message.\n\n" 477 "The place that called this function also provided as " 478 "additional information this:\n\n" 480 + documentation +
">"));
482 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
483 p != plugins->end(); ++p)
484 if (std::get<0>(*p) == name)
486 std::unique_ptr<InterfaceClass> i = std::get<3>(*p)();
490 AssertThrow (
false, ExcUnknownPlugin(name));
496 template <
typename InterfaceClass>
497 std::unique_ptr<InterfaceClass>
500 const std::string &documentation,
501 ParameterHandler &prm)
503 std::unique_ptr<InterfaceClass> i = create_plugin(name, documentation);
504 i->parse_parameters (prm);
510 template <
typename InterfaceClass>
514 std::ostream &output_stream,
515 const std::string &attachment_point)
523 output_stream << std::string(
typeid(InterfaceClass).name())
525 << plugin_system_name
526 <<
"\", height=.8,width=.8,shape=\"rect\",fillcolor=\"green\"]" 538 std::map<std::string, typename std::list<PluginInfo>::const_iterator>
540 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
541 p != plugins->end(); ++p)
542 plugin_map[std::get<0>(*p)] = p;
545 for (
typename std::map<std::string,
typename std::list<PluginInfo>::const_iterator>::const_iterator
546 p = plugin_map.begin();
547 p != plugin_map.end(); ++p)
553 const std::vector<std::string> plugin_label_parts
554 = ::Utilities::break_text_into_lines(p->first, 15);
555 Assert (plugin_label_parts.size()>0, ExcInternalError());
556 std::string plugin_name = plugin_label_parts[0];
557 for (
unsigned int i=1; i<plugin_label_parts.size(); ++i)
558 plugin_name +=
"\\n" + plugin_label_parts[i];
563 std::unique_ptr<InterfaceClass> instance (create_plugin (p->first,
""));
564 const std::string node_name =
typeid(*instance).name();
567 output_stream << node_name
570 <<
"\", height=.8,width=.8,shape=\"circle\",fillcolor=\"lightblue\"];" 575 output_stream << node_name
577 << std::string(
typeid(InterfaceClass).name())
578 <<
" [len=3, weight=50]" 588 output_stream <<
"SimulatorAccess" 591 <<
" [style=\"dotted\", arrowhead=\"empty\", constraint=false, color=\"gray\", len=20, weight=0.1];" 598 output_stream << std::string(
typeid(InterfaceClass).name())
601 <<
" [len=15, weight=50]" 607 output_stream << std::endl;
void write_plugin_graph(std::ostream &output_stream)
TestType & get_plugin_as_type(PluginType &object)
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
std::tuple< std::string, std::string, void(*)(ParameterHandler &), std::unique_ptr< InterfaceClass >(*)()> PluginInfo
void declare_parameters(ParameterHandler &prm)
static std::unique_ptr< InterfaceClass > factory()
bool plugin_type_matches(const PluginType &object)
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.")