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
|