16 #ifndef _aspect_plugins_h 17 #define _aspect_plugins_h 25 #include <boost/core/demangle.hpp> 34 #include <type_traits> 63 template <
typename TestType,
typename PluginType,
64 typename =
typename std::enable_if_t<std::is_base_of<PluginType,TestType>::value>>
69 return (dynamic_cast<const TestType *> (&
object) !=
nullptr);
89 template <
typename TestType,
typename PluginType,
90 typename =
typename std::enable_if_t<std::is_base_of<PluginType,TestType>::value>>
96 ExcMessage(
"You have requested to convert a plugin of type <" 97 + boost::core::demangle(
typeid(PluginType).name())
99 + boost::core::demangle(
typeid(TestType).name()) +
100 ">, but this cast cannot be performed."));
105 return *
dynamic_cast<TestType *
> (&object);
204 void save (std::map<std::string, std::string> &status_strings)
const;
218 void load (
const std::map<std::string, std::string> &status_strings);
241 template <
typename InterfaceType>
266 template <
typename PluginType,
267 typename =
typename std::enable_if_t<std::is_base_of<InterfaceType,PluginType>::value>>
269 has_matching_active_plugin ()
const;
285 template <
typename PluginType,
286 typename =
typename std::enable_if_t<std::is_base_of<InterfaceType,PluginType>::value>>
288 get_matching_active_plugin ()
const;
295 const std::list<std::unique_ptr<InterfaceType>> &
296 get_active_plugins ()
const;
304 const std::vector<std::string> &
305 get_active_plugin_names ()
const;
311 template <
class Archive>
312 void save (Archive &ar,
313 const unsigned int version)
const;
327 template <
class Archive>
328 void load (Archive &ar,
329 const unsigned int version);
339 BOOST_SERIALIZATION_SPLIT_MEMBER()
357 template <
typename InterfaceType>
362 #ifdef DEAL_II_HAVE_CXX17 363 if (std::uncaught_exceptions() == 0)
365 if (std::uncaught_exception() ==
false)
373 template <
typename InterfaceType>
377 for (
const auto &p : plugin_objects)
390 catch (std::exception &exc)
392 std::cerr << std::endl << std::endl
393 <<
"----------------------------------------------------" 395 std::cerr <<
"Exception on MPI process <" 396 << ::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)
397 <<
"> while running plugin <" 399 <<
">: " << std::endl
400 << exc.what() << std::endl
401 <<
"Aborting!" << std::endl
402 <<
"----------------------------------------------------" 406 MPI_Abort (MPI_COMM_WORLD, 1);
410 std::cerr << std::endl << std::endl
411 <<
"----------------------------------------------------" 413 std::cerr <<
"Exception on MPI process <" 414 << ::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)
415 <<
"> while running plugin <" 417 <<
">: " << std::endl;
418 std::cerr <<
"Unknown exception!" << std::endl
419 <<
"Aborting!" << std::endl
420 <<
"----------------------------------------------------" 424 MPI_Abort (MPI_COMM_WORLD, 1);
431 template <
typename InterfaceType>
432 template <
class Archive>
434 const unsigned int)
const 438 std::map<std::string,std::string> saved_text;
439 for (
const auto &p : plugin_objects)
440 p->save (saved_text);
446 template <
typename InterfaceType>
447 template <
class Archive>
455 std::map<std::string,std::string> saved_text;
458 for (
auto &p : plugin_objects)
459 p->load (saved_text);
464 template <
typename InterfaceType>
465 template <
typename PluginType,
typename>
470 for (
const auto &p : plugin_objects)
471 if (Plugins::plugin_type_matches<PluginType>(*p))
477 template <
typename InterfaceType>
478 template <
typename PluginType,
typename>
483 AssertThrow(has_matching_active_plugin<PluginType> (),
484 ExcMessage(
"You asked the object managing a collection of plugins for a " 485 "plugin object of type <" + boost::core::demangle(
typeid(PluginType).name()) +
"> " 486 "that could not be found in the current model. You need to " 487 "activate this plugin in the input file for it to be " 490 for (
const auto &p : plugin_objects)
491 if (Plugins::plugin_type_matches<PluginType>(*p))
492 return Plugins::get_plugin_as_type<PluginType>(*p);
495 return Plugins::get_plugin_as_type<PluginType>(**(plugin_objects.begin()));
500 template <
typename InterfaceType>
501 const std::list<std::unique_ptr<InterfaceType>> &
504 return plugin_objects;
509 template <
typename InterfaceType>
510 const std::vector<std::string> &
536 template <
typename InterfaceClass,
548 std::unique_ptr<InterfaceClass> ( *)()),
550 const char *description)
552 register_function (name,
565 return std::make_unique<ModelClass>();
574 template <
typename InterfaceClass>
589 = std::tuple<std::string,
592 std::unique_ptr<InterfaceClass>( *) ()>;
619 void register_plugin (
const std::string &name,
620 const std::string &description,
622 std::unique_ptr<InterfaceClass> (*factory_function) ());
632 std::string get_pattern_of_names ();
642 std::string get_description_string ();
660 std::unique_ptr<InterfaceClass>
661 create_plugin (
const std::string &name,
662 const std::string &documentation);
675 std::unique_ptr<InterfaceClass>
676 create_plugin (
const std::string &name,
677 const std::string &documentation,
704 std::ostream &output_stream,
705 const std::string &attachment_point =
"Simulator");
712 <<
"Can't create a plugin of name <" << arg1
713 <<
"> because such a plugin hasn't been declared.");
719 template <
typename InterfaceClass>
725 if (plugins !=
nullptr)
732 template <
typename InterfaceClass>
736 const std::string &description,
738 std::unique_ptr<InterfaceClass> (*factory_function) ())
742 if (plugins ==
nullptr)
743 plugins =
new std::list<PluginInfo>();
748 for (
const auto &p : *plugins)
750 Assert (std::get<0>(p) != name,
751 ExcMessage (
"A plugin with name <" + name +
"> has " 752 "already been registered!"));
758 plugins->emplace_back (name,
760 declare_parameters_function,
766 template <
typename InterfaceClass>
771 Assert (plugins !=
nullptr,
776 std::set<std::string> names;
777 for (
typename std::list<PluginInfo>::const_iterator
778 p = plugins->begin();
779 p != plugins->end(); ++p)
780 names.insert (std::get<0>(*p));
783 std::string pattern_of_names;
784 for (
const auto &name : names)
786 if (pattern_of_names.size() > 0)
787 pattern_of_names +=
"|";
788 pattern_of_names += name;
791 return pattern_of_names;
796 template <
typename InterfaceClass>
801 std::string description;
805 std::map<std::string,std::string> names_and_descriptions;
806 for (
typename std::list<PluginInfo>::const_iterator
807 p = plugins->begin();
808 p != plugins->end(); ++p)
809 names_and_descriptions[std::get<0>(*p)] = std::get<1>(*p);
812 std::map<std::string,std::string>::const_iterator
813 p = names_and_descriptions.begin();
820 description += p->first;
821 description +=
"': ";
822 description += p->second;
829 if (p != names_and_descriptions.end())
830 description +=
"\n\n";
841 template <
typename InterfaceClass>
846 Assert (plugins !=
nullptr,
847 ExcMessage (
"No postprocessors registered!?"));
849 for (
typename std::list<PluginInfo>::const_iterator
850 p = plugins->begin();
851 p != plugins->end(); ++p)
852 (std::get<2>(*p))(prm);
857 template <
typename InterfaceClass>
858 std::unique_ptr<InterfaceClass>
861 const std::string &documentation)
864 Assert (plugins !=
nullptr,
865 ExcMessage (
"No postprocessors registered!?"));
867 ExcMessage(std::string(
"A plugin must have a name!\n\n" 868 "This function was asked to create a plugin but no name for the " 869 "plugin was provided. This may be due to the fact that you did not " 870 "explicitly specify a name for this plugin in your input file and " 871 "ASPECT does not provide a default for this kind of plugin, for " 872 "example because no generally useful plugin exists. An example " 873 "is that there is no default geometry: You need to explicitly " 874 "provide one in the input file, and it seems like you have not " 876 "To find out which kind of plugin this function tries to create, " 877 "take a look at the backtrace of this error message.\n\n" 878 "The place that called this function also provided as " 879 "additional information this:\n\n" 881 + documentation +
">"));
883 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
884 p != plugins->end(); ++p)
885 if (std::get<0>(*p) == name)
887 std::unique_ptr<InterfaceClass> i = std::get<3>(*p)();
897 template <
typename InterfaceClass>
898 std::unique_ptr<InterfaceClass>
901 const std::string &documentation,
904 std::unique_ptr<InterfaceClass> i = create_plugin(name, documentation);
905 i->parse_parameters (prm);
911 template <
typename InterfaceClass>
915 std::ostream &output_stream,
916 const std::string &attachment_point)
924 output_stream << std::string(
typeid(InterfaceClass).name())
926 << plugin_system_name
927 <<
"\", height=.8,width=.8,shape=\"rect\",fillcolor=\"lightgreen\"]" 939 std::map<std::string, typename std::list<PluginInfo>::const_iterator>
941 for (
typename std::list<PluginInfo>::const_iterator p = plugins->begin();
942 p != plugins->end(); ++p)
943 plugin_map[std::get<0>(*p)] = p;
946 for (
typename std::map<std::string,
typename std::list<PluginInfo>::const_iterator>::
const_iterator 947 p = plugin_map.begin();
948 p != plugin_map.end(); ++p)
954 const std::vector<std::string> plugin_label_parts
955 = ::Utilities::break_text_into_lines(p->first, 15);
957 std::string plugin_name = plugin_label_parts[0];
958 for (
unsigned int i=1; i<plugin_label_parts.size(); ++i)
959 plugin_name +=
"\\n" + plugin_label_parts[i];
964 std::unique_ptr<InterfaceClass> instance (create_plugin (p->first,
""));
965 const std::string node_name =
typeid(*instance).name();
968 output_stream << node_name
971 <<
"\", height=.8,width=.8,shape=\"circle\",fillcolor=\"lightblue\"];" 976 output_stream << node_name
978 << std::string(
typeid(InterfaceClass).name())
979 <<
" [len=3, weight=50]" 989 output_stream <<
"SimulatorAccess" 992 <<
" [style=\"dotted\", arrowhead=\"empty\", constraint=false, color=\"gray\", len=20, weight=0.1];" 999 output_stream << std::string(
typeid(InterfaceClass).name())
1002 <<
" [len=15, weight=50]" 1008 output_stream << std::endl;
1014 template <
typename InterfaceClass>
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)
#define AssertThrow(cond, exc)
void load(Archive &ar, const unsigned int version)
static ::ExceptionBase & ExcInternalError()
std::tuple< std::string, std::string, void(*)(ParameterHandler &), std::unique_ptr< InterfaceClass >(*)()> PluginInfo
virtual void load(const std::map< std::string, std::string > &status_strings)
void declare_parameters(ParameterHandler &prm)
#define Assert(cond, exc)
void save(Archive &ar, const unsigned int version) const
static std::unique_ptr< InterfaceClass > factory()
bool has_matching_active_plugin() const
bool plugin_type_matches(const PluginType &object)
static ::ExceptionBase & ExcMessage(std::string arg1)
const std::list< std::unique_ptr< InterfaceType > > & get_active_plugins() const
virtual void save(std::map< std::string, std::string > &status_strings) const
static std::list< PluginInfo > * plugins
* * const_iterator()=default
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.")