diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp index 8529c65bd5a8af589c4daf7f6f217c09c0ab693f..b356039b420ebf38d025251a2c758e46480f8c78 100644 --- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp +++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp @@ -36,7 +36,7 @@ bool EvolutionaryPIDcontroller::next(double const solution_error, : 0.5 * _ts_current.dt(); h_new = limitStepSize(h_new, is_previous_step_accepted); - h_new = checkSpecificTimeReached(h_new); + h_new = possiblyClampToNextFixedTime(h_new); _ts_current = _ts_prev; _ts_current += h_new; @@ -96,7 +96,7 @@ bool EvolutionaryPIDcontroller::next(double const solution_error, } h_new = limitStepSize(h_new, is_previous_step_accepted); - h_new = checkSpecificTimeReached(h_new); + h_new = possiblyClampToNextFixedTime(h_new); _dt_vector.push_back(h_new); _ts_prev = _ts_current; @@ -145,19 +145,22 @@ double EvolutionaryPIDcontroller::limitStepSize( return limited_h; } -double EvolutionaryPIDcontroller::checkSpecificTimeReached(const double h_new) +double EvolutionaryPIDcontroller::possiblyClampToNextFixedTime( + const double h_new) const { - if (_fixed_output_times.empty()) + auto const specific_time = + std::upper_bound(std::cbegin(_fixed_output_times), + std::cend(_fixed_output_times), _ts_current.current()); + + if (specific_time == std::cend(_fixed_output_times)) { return h_new; } - const double specific_time = _fixed_output_times.back(); - if ((specific_time > _ts_current.current()) && - (_ts_current.current() + h_new - specific_time > 0.0)) + if ((*specific_time > _ts_current.current()) && + (_ts_current.current() + h_new - *specific_time > 0.0)) { - _fixed_output_times.pop_back(); - return specific_time - _ts_current.current(); + return *specific_time - _ts_current.current(); } return h_new; @@ -170,8 +173,8 @@ void EvolutionaryPIDcontroller::addFixedOutputTimes( extra_fixed_output_times.begin(), extra_fixed_output_times.end()); - // Remove possible duplicated elements and sort in descending order. - BaseLib::makeVectorUnique(_fixed_output_times, std::greater<double>()); + // Remove possible duplicated elements. Result will be sorted. + BaseLib::makeVectorUnique(_fixed_output_times); } bool EvolutionaryPIDcontroller::canReduceTimestepSize() const diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h index 522f8fe0127b0966bfba74339d9a9d3605ef3a8a..ad2d397e91fbeca234d992e82dba9ca7027dedbb 100644 --- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h +++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h @@ -15,6 +15,7 @@ #include <vector> #include "TimeStepAlgorithm.h" +#include "BaseLib/Algorithm.h" namespace BaseLib { @@ -69,6 +70,8 @@ public: _e_n_minus2(0.), _is_accepted(true) { + // Remove possible duplicated elements. Result will be sorted. + BaseLib::makeVectorUnique(_fixed_output_times); } bool next(double solution_error, int number_iterations) override; @@ -125,7 +128,9 @@ private: double limitStepSize(const double h_new, const bool previous_step_accepted) const; - double checkSpecificTimeReached(const double h_new); + /// If any time will be reached with given time increment, it will be + /// reduced, otherwise the input will be returned. + double possiblyClampToNextFixedTime(const double h_new) const; }; /// Create an EvolutionaryPIDcontroller time stepper from the given