diff --git a/include/aspect/time_stepping/interface.h b/include/aspect/time_stepping/interface.h index 2d30a8b6681..f674fc508ee 100644 --- a/include/aspect/time_stepping/interface.h +++ b/include/aspect/time_stepping/interface.h @@ -234,6 +234,36 @@ namespace aspect void parse_parameters (ParameterHandler &prm); + /** + * Go through the list of all mesh refinement strategies that have been selected + * in the input file (and are consequently currently active) and return + * true if one of them has the desired type specified by the template + * argument. + * + * This function can only be called if the given template type (the first template + * argument) is a class derived from the Interface class in this namespace. + */ + template ,PluginType>::value>> + bool + has_matching_plugin () const; + + /** + * Go through the list of all mesh refinement strategies that have been selected + * in the input file (and are consequently currently active) and see + * if one of them has the type specified by the template + * argument or can be casted to that type. If so, return a reference + * to it. If no mesh refinement strategy is active that matches the + * given type, throw an exception. + * + * This function can only be called if the given template type (the first template + * argument) is a class derived from the Interface class in this namespace. + */ + template ,PluginType>::value>> + const PluginType & + get_matching_plugin () const; + /** * For the current plugin subsystem, write a connection graph of all of the * plugins we know about, in the format that the @@ -247,7 +277,6 @@ namespace aspect void write_plugin_graph (std::ostream &output_stream); - /** * A function that is used to register time stepping model objects in such * a way that the Manager can deal with all of them without having to @@ -308,6 +337,50 @@ namespace aspect std::list>> active_plugins; }; + + + template + template + inline + bool + Manager::has_matching_plugin () const + { + for (typename std::list>>::const_iterator + p = active_plugins.begin(); + p != active_plugins.end(); ++p) + if (Plugins::plugin_type_matches(*(*p))) + return true; + + return false; + } + + + + template + template + inline + const PluginType & + Manager::get_matching_plugin () const + { + AssertThrow(has_matching_plugin (), + ExcMessage("You asked TimeStepping::Manager::get_matching_plugin() for a " + "plugin of type <" + boost::core::demangle(typeid(PluginType).name()) + "> " + "that could not be found in the current model. Activate this " + "plugin in the input file.")); + + for (typename std::list>>::const_iterator + p = active_plugins.begin(); + p != active_plugins.end(); ++p) + if (Plugins::plugin_type_matches(*(*p))) + return Plugins::get_plugin_as_type(*(*p)); + + // We will never get here, because we had the Assert above. Just to avoid warnings. + typename std::list>>::const_iterator plugin; + return Plugins::get_plugin_as_type(*(*plugin)); + } + + + /** * Given a class name, a name, and a description for the parameter file, register it with the * aspect::TimeStepping::Manager class. diff --git a/source/simulator/core.cc b/source/simulator/core.cc index 9e0b3df596c..358b16241ca 100644 --- a/source/simulator/core.cc +++ b/source/simulator/core.cc @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -2049,14 +2050,7 @@ namespace aspect throw; } - // reduce timestep size and update time to "go back": - const double new_time_step = 0.5*time_step; - const double multiplier = (parameters.convert_to_years ? 1./year_in_seconds : 1.0); - pcout << "\tReducing timestep by " << new_time_step *multiplier << '\n' << std::endl; - - time -= time_step - new_time_step; - time_step = new_time_step; - continue; // skip the rest of the main loop that would advance in time + time_stepping_manager.template get_matching_plugin>().nonlinear_solver_has_failed(); } else if (parameters.nonlinear_solver_failure_strategy == Parameters::NonlinearSolverFailureStrategy::abort_program) diff --git a/source/time_stepping/repeat_on_nonlinear_fail.cc b/source/time_stepping/repeat_on_nonlinear_fail.cc index 4fd3e3884d8..f203fa45bca 100644 --- a/source/time_stepping/repeat_on_nonlinear_fail.cc +++ b/source/time_stepping/repeat_on_nonlinear_fail.cc @@ -35,9 +35,18 @@ namespace aspect + template + void + RepeatOnNonlinearFail::nonlinear_solver_has_failed() const + { + nonlinear_solver_just_failed = true; + } + + + template std::pair - RepeatOnNonlinearFail::determine_reaction (const TimeStepInfo &info) + RepeatOnNonlinearFail::determine_reaction (const TimeStepInfo &/*info*/) { if (nonlinear_solver_just_failed) {