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> 29 #include <deal.II/base/exceptions.h> 30 #include <deal.II/fe/component_mask.h> 32 #include <boost/core/demangle.hpp> 41 #include <type_traits> 68 template <
typename TestType,
typename PluginType,
69 typename =
typename std::enable_if_t<std::is_base_of<PluginType,TestType>::value>>
74 return (dynamic_cast<const TestType *> (&
object) !=
nullptr);
94 template <
typename TestType,
typename PluginType,
95 typename =
typename std::enable_if_t<std::is_base_of<PluginType,TestType>::value>>
100 AssertThrow(plugin_type_matches<TestType>(
object),
101 ExcMessage(
"You have requested to convert a plugin of type <" 102 + boost::core::demangle(
typeid(PluginType).name())
104 + boost::core::demangle(
typeid(TestType).name()) +
105 ">, but this cast cannot be performed."));
110 return *
dynamic_cast<TestType *
> (&object);
185 parse_parameters (ParameterHandler &prm);
208 template <
typename InterfaceType>
233 template <
typename PluginType,
234 typename =
typename std::enable_if_t<std::is_base_of<InterfaceType,PluginType>::value>>
236 has_matching_active_plugin ()
const;
252 template <
typename PluginType,
253 typename =
typename std::enable_if_t<std::is_base_of<InterfaceType,PluginType>::value>>
255 get_matching_active_plugin ()
const;
262 const std::list<std::unique_ptr<InterfaceType>> &
263 get_active_plugins ()
const;
271 const std::vector<std::string> &
272 get_active_plugin_names ()
const;
290 template <
typename InterfaceType>
295 #ifdef DEAL_II_HAVE_CXX17 296 if (std::uncaught_exceptions() == 0)
298 if (std::uncaught_exception() ==
false)
301 Assert (plugin_names.size() == plugin_objects.size(), ExcInternalError());
306 template <
typename InterfaceType>
310 for (
const auto &p : plugin_objects)
323 catch (std::exception &exc)
325 std::cerr << std::endl << std::endl
326 <<
"----------------------------------------------------" 328 std::cerr <<
"Exception on MPI process <" 329 << ::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)
330 <<
"> while running plugin <" 332 <<
">: " << std::endl
333 << exc.what() << std::endl
334 <<
"Aborting!" << std::endl
335 <<
"----------------------------------------------------" 339 MPI_Abort (MPI_COMM_WORLD, 1);
343 std::cerr << std::endl << std::endl
344 <<
"----------------------------------------------------" 346 std::cerr <<
"Exception on MPI process <" 347 << ::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)
348 <<
"> while running plugin <" 350 <<
">: " << std::endl;
351 std::cerr <<
"Unknown exception!" << std::endl
352 <<
"Aborting!" << std::endl
353 <<
"----------------------------------------------------" 357 MPI_Abort (MPI_COMM_WORLD, 1);
363 template <
typename InterfaceType>
364 template <
typename PluginType,
typename>
369 for (
const auto &p : plugin_objects)
370 if (Plugins::plugin_type_matches<PluginType>(*p))
376 template <
typename InterfaceType>
377 template <
typename PluginType,
typename>
382 AssertThrow(has_matching_active_plugin<PluginType> (),
383 ExcMessage(
"You asked the object managing a collection of plugins for a " 384 "plugin object of type <" + boost::core::demangle(
typeid(PluginType).name()) +
"> " 385 "that could not be found in the current model. You need to " 386 "activate this plugin in the input file for it to be " 389 for (
const auto &p : plugin_objects)
390 if (Plugins::plugin_type_matches<PluginType>(*p))
391 return Plugins::get_plugin_as_type<PluginType>(*p);
394 return Plugins::get_plugin_as_type<PluginType>(**(plugin_objects.begin()));
399 template <
typename InterfaceType>
400 const std::list<std::unique_ptr<InterfaceType>> &
403 return plugin_objects;
408 template <
typename InterfaceType>
409 const std::vector<std::string> &
435 template <
typename InterfaceClass,
446 void ( *)(ParameterHandler &),
447 std::unique_ptr<InterfaceClass> ( *)()),
449 const char *description)
451 register_function (name,
464 return std::make_unique<ModelClass>();
473 template <
typename InterfaceClass>
488 = std::tuple<std::string,
490 void ( *) (ParameterHandler &),
491 std::unique_ptr<InterfaceClass>( *) ()>;
518 void register_plugin (
const std::string &name,
519 const std::string &description,
520 void (*declare_parameters_function) (ParameterHandler &),
521 std::unique_ptr<InterfaceClass> (*factory_function) ());
531 std::string get_pattern_of_names ();
541 std::string get_description_string ();
559 std::unique_ptr<InterfaceClass>
560 create_plugin (
const std::string &name,
561 const std::string &documentation);
574 std::unique_ptr<InterfaceClass>
575 create_plugin (
const std::string &name,
576 const std::string &documentation,
577 ParameterHandler &prm);
603 std::ostream &output_stream,
604 const std::string &attachment_point =
"Simulator");
611 <<
"Can't create a plugin of name <" << arg1
612 <<
"> because such a plugin hasn't been declared.");
618 template <
typename InterfaceClass>
624 if (plugins !=
nullptr)
631 template <
typename InterfaceClass>
635 const std::string &description,
636 void (*declare_parameters_function) (ParameterHandler &),
637 std::unique_ptr<InterfaceClass> (*factory_function) ())
641 if (plugins ==
nullptr)
642 plugins =
new std::list<PluginInfo>();
647 for (
const auto &p : *plugins)
649 Assert (std::get<0>(p) != name,
650 ExcMessage (
"A plugin with name <" + name +
"> has " 651 "already been registered!"));
657 plugins->emplace_back (name,
659 declare_parameters_function,
665 template <
typename InterfaceClass>
670 Assert (plugins !=
nullptr,
671 ExcMessage (
"No plugins registered!?"));
675 std::set<std::string> names;
676 for (
typename std::list<PluginInfo>::const_iterator
677 p = plugins->begin();
678 p != plugins->end(); ++p)
679 names.insert (std::get<0>(*p));
682 std::string pattern_of_names;
683 for (
const auto &name : names)
685 if (pattern_of_names.size() > 0)
686 pattern_of_names +=
"|";
687 pattern_of_names += name;
690 return pattern_of_names;
695 template <
typename InterfaceClass>
700 std::string description;
704 std::map<std::string,std::string> names_and_descriptions;
705 for (
typename std::list<PluginInfo>::const_iterator
706 p = plugins->begin();
707 p != plugins->end(); ++p)
708 names_and_descriptions[std::get<0>(*p)] = std::get<1>(*p);
711 std::map<std::string,std::string>::const_iterator
712 p = names_and_descriptions.begin();
719 description += p->first;
720 description +=
"': ";
721 description += p->second;
728 if (p != names_and_descriptions.end())
729 description +=
"\n\n";
740 template <
typename InterfaceClass>
745 Assert (plugins !=
nullptr,
746 ExcMessage (
"No postprocessors registered!?"));
748 for (
typename std::list<PluginInfo>::const_iterator
749 p = plugins->begin();
750 p != plugins->end(); ++p)
751 (std::get<2>(*p))(prm);
756 template <
typename InterfaceClass>
757 std::unique_ptr<InterfaceClass>
760 const std::string &documentation)
763 Assert (plugins !=
nullptr,
764 ExcMessage (
"No postprocessors registered!?"));
765 AssertThrow (name !=
"unspecified",
766 ExcMessage(std::string(
"A plugin must have a name!\n\n" 767 "This function was asked to create a plugin but no name for the " 768 "plugin was provided. This may be due to the fact that you did not " 769 "explicitly specify a name for this plugin in your input file and " 770 "ASPECT does not provide a default for this kind of plugin, for " 771 "example because no generally useful plugin exists. An example " 772 "is that there is no default geometry: You need to explicitly " 773 "provide one in the input file, and it seems like you have not " 775 "To find out which kind of plugin this function tries to create, " 776 "take a look at the backtrace of this error message.\n\n" 777 "The place that called this function also provided as " 778 "additional information this:\n\n" 780 + documentation +
">"));
782 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
783 p != plugins->end(); ++p)
784 if (std::get<0>(*p) == name)
786 std::unique_ptr<InterfaceClass> i = std::get<3>(*p)();
790 AssertThrow (
false, ExcUnknownPlugin(name));
796 template <
typename InterfaceClass>
797 std::unique_ptr<InterfaceClass>
800 const std::string &documentation,
801 ParameterHandler &prm)
803 std::unique_ptr<InterfaceClass> i = create_plugin(name, documentation);
804 i->parse_parameters (prm);
810 template <
typename InterfaceClass>
814 std::ostream &output_stream,
815 const std::string &attachment_point)
823 output_stream << std::string(
typeid(InterfaceClass).name())
825 << plugin_system_name
826 <<
"\", height=.8,width=.8,shape=\"rect\",fillcolor=\"lightgreen\"]" 838 std::map<std::string, typename std::list<PluginInfo>::const_iterator>
840 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
841 p != plugins->end(); ++p)
842 plugin_map[std::get<0>(*p)] = p;
845 for (
typename std::map<std::string,
typename std::list<PluginInfo>::const_iterator>::const_iterator
846 p = plugin_map.begin();
847 p != plugin_map.end(); ++p)
853 const std::vector<std::string> plugin_label_parts
854 = ::Utilities::break_text_into_lines(p->first, 15);
855 Assert (plugin_label_parts.size()>0, ExcInternalError());
856 std::string plugin_name = plugin_label_parts[0];
857 for (
unsigned int i=1; i<plugin_label_parts.size(); ++i)
858 plugin_name +=
"\\n" + plugin_label_parts[i];
863 std::unique_ptr<InterfaceClass> instance (create_plugin (p->first,
""));
864 const std::string node_name =
typeid(*instance).name();
867 output_stream << node_name
870 <<
"\", height=.8,width=.8,shape=\"circle\",fillcolor=\"lightblue\"];" 875 output_stream << node_name
877 << std::string(
typeid(InterfaceClass).name())
878 <<
" [len=3, weight=50]" 888 output_stream <<
"SimulatorAccess" 891 <<
" [style=\"dotted\", arrowhead=\"empty\", constraint=false, color=\"gray\", len=20, weight=0.1];" 898 output_stream << std::string(
typeid(InterfaceClass).name())
901 <<
" [len=15, weight=50]" 907 output_stream << std::endl;
const std::vector< std::string > & get_active_plugin_names() const
const PluginType & get_matching_active_plugin() const
std::list< std::unique_ptr< InterfaceType > > plugin_objects
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 has_matching_active_plugin() const
bool plugin_type_matches(const PluginType &object)
const std::list< std::unique_ptr< InterfaceType > > & get_active_plugins() const
std::vector< std::string > plugin_names
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.")