Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <optional> 7 : #include <string> 8 : 9 : #include "ControlSystem/Protocols/ControlError.hpp" 10 : #include "ControlSystem/TimescaleTuner.hpp" 11 : #include "IO/Logging/Verbosity.hpp" 12 : #include "Parallel/GlobalCache.hpp" 13 : #include "Parallel/Printf/Printf.hpp" 14 : #include "Utilities/Gsl.hpp" 15 : #include "Utilities/ProtocolHelpers.hpp" 16 : #include "Utilities/TypeTraits/CreateIsCallable.hpp" 17 : 18 : namespace control_system { 19 : /*! 20 : * \brief Updates the TimescaleTuner with information from the ControlError, if 21 : * possible. 22 : * 23 : * \details We check for a suggested timescale from the ControlError. If one is 24 : * suggested and it is smaller than the current damping timescale, we set the 25 : * timescale in the TimescaleTuner to this suggested value. Otherwise, we let 26 : * the TimescaleTuner adjust the timescale. Regardless of whether a timescale 27 : * was suggested or not, we always reset the control error. 28 : */ 29 : template <bool AllowDecrease, typename ControlError> 30 1 : void update_timescale_tuner( 31 : const gsl::not_null<TimescaleTuner<AllowDecrease>*> tuner, 32 : const gsl::not_null<ControlError*> control_error, ::Verbosity verbosity, 33 : const double time, const std::string& function_of_time_name) { 34 : static_assert( 35 : tt::assert_conforms_to_v<ControlError, protocols::ControlError>); 36 : 37 : const std::optional<double>& suggested_timescale = 38 : control_error->get_suggested_timescale(); 39 : const double old_timescale = min(tuner->current_timescale()); 40 : 41 : if (suggested_timescale.value_or(std::numeric_limits<double>::infinity()) < 42 : old_timescale) { 43 : tuner->set_timescale_if_in_allowable_range(suggested_timescale.value()); 44 : } 45 : 46 : if (verbosity >= ::Verbosity::Verbose) { 47 : using ::operator<<; 48 : Parallel::printf( 49 : "%s, time = %.16f:\n" 50 : " old_timescale = %.16f\n" 51 : " suggested_timescale = %s\n" 52 : " new_timescale = %.16f\n", 53 : function_of_time_name, time, old_timescale, 54 : MakeString{} << suggested_timescale, min(tuner->current_timescale())); 55 : } 56 : 57 : // This reset call is ok because if there was a discontinuous change 58 : // above after calculating the control error, the control error class was 59 : // already reset so this reset won't do anything. If there wasn't a 60 : // discontinuous change, then this will only affect the suggested 61 : // timescale, which we always want to reset. 62 : control_error->reset(); 63 : } 64 : } // namespace control_system