SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem - TimescaleTuner.cpp Hit Total Coverage
Commit: f1ddee3e40d81480e49140855d2b0e66fafaa908 Lines: 0 1 0.0 %
Date: 2020-12-02 17:35:08
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #include "ControlSystem/TimescaleTuner.hpp"
       5             : 
       6             : #include <algorithm>
       7             : #include <cmath>
       8             : #include <cstddef>
       9             : #include <functional>
      10             : #include <ostream>
      11             : 
      12             : #include "ErrorHandling/Assert.hpp"
      13             : #include "ErrorHandling/Error.hpp"
      14             : #include "Utilities/ConstantExpressions.hpp"
      15             : #include "Utilities/Gsl.hpp"
      16             : 
      17             : TimescaleTuner::TimescaleTuner(DataVector initial_timescale,
      18             :                                const double max_timescale,
      19             :                                const double min_timescale,
      20             :                                const double decrease_timescale_threshold,
      21             :                                const double increase_timescale_threshold,
      22             :                                const double increase_factor,
      23             :                                const double decrease_factor) noexcept
      24             :     : timescale_{std::move(initial_timescale)},
      25             :       max_timescale_{max_timescale},
      26             :       min_timescale_{min_timescale},
      27             :       decrease_timescale_threshold_{decrease_timescale_threshold},
      28             :       increase_timescale_threshold_{increase_timescale_threshold},
      29             :       increase_factor_{increase_factor},
      30             :       decrease_factor_{decrease_factor} {
      31             :   for (const auto& t_scale : timescale_) {
      32             :     if (t_scale <= 0.0) {
      33             :       ERROR("Initial timescale must be > 0");
      34             :     }
      35             :   }
      36             : 
      37             :   if (decrease_factor_ > 1.0 or decrease_factor <= 0.0) {
      38             :     ERROR("The specified decrease_factor "
      39             :           << decrease_factor_ << " must satisfy 0 < decrease_factor <= 1");
      40             :   }
      41             :   if (increase_factor_ < 1.0) {
      42             :     ERROR("The specified increase factor " << increase_factor_
      43             :                                            << " must be >= 1.0");
      44             :   }
      45             :   if (min_timescale_ <= 0.0) {
      46             :     ERROR("The specified minimum timescale " << min_timescale_
      47             :                                              << " must be > 0");
      48             :   }
      49             :   if (max_timescale_ <= min_timescale_) {
      50             :     ERROR("The maximum timescale "
      51             :           << max_timescale_
      52             :           << " must be > than the specified minimum timescale "
      53             :           << min_timescale_);
      54             :   }
      55             :   if (increase_timescale_threshold_ <= 0.0) {
      56             :     ERROR("The specified increase-timescale threshold "
      57             :           << increase_timescale_threshold_ << " must be > 0");
      58             :   }
      59             :   if (decrease_timescale_threshold_ <= increase_timescale_threshold_) {
      60             :     ERROR("The decrease-timescale threshold "
      61             :           << decrease_timescale_threshold_
      62             :           << " must be > than the specified increase-timescale threshold "
      63             :           << increase_timescale_threshold_);
      64             :   }
      65             : }
      66             : 
      67             : void TimescaleTuner::set_timescale_if_in_allowable_range(
      68             :     const double suggested_timescale) noexcept {
      69             :   for (auto& t_scale : timescale_) {
      70             :     t_scale = std::clamp(suggested_timescale, min_timescale_, max_timescale_);
      71             :   }
      72             : }
      73             : 
      74             : void TimescaleTuner::update_timescale(
      75             :     const std::array<DataVector, 2>& q_and_dtq) noexcept {
      76             :   ASSERT(q_and_dtq[0].size() == timescale_.size() and
      77             :              q_and_dtq[1].size() == timescale_.size(),
      78             :          "One or both of the number of components in q_and_dtq("
      79             :              << q_and_dtq[0].size() << "," << q_and_dtq[1].size()
      80             :              << ") is inconsistent with the number of timescales("
      81             :              << timescale_.size() << ")");
      82             : 
      83             :   const DataVector& q = gsl::at(q_and_dtq, 0);
      84             :   const DataVector& dtq = gsl::at(q_and_dtq, 1);
      85             : 
      86             :   for (size_t i = 0; i < q.size(); i++) {
      87             :     // check whether we need to decrease the timescale:
      88             :     if ((fabs(q[i]) > decrease_timescale_threshold_ or
      89             :          fabs(dtq[i] * timescale_[i]) > decrease_timescale_threshold_) and
      90             :         (dtq[i] * q[i] > 0.0 or
      91             :          fabs(dtq[i]) * timescale_[i] < 0.5 * fabs(q[i]))) {
      92             :       // the first check is if Q `or` dtQ are above the maximum tolerance.
      93             :       // the second condition of the `and` is
      94             :       // that Q and dtQ are the same sign (the error is growing)
      95             :       // `or` that Q is not expected to drop to half of its current value in
      96             :       // one timescale (not decreasing fast enough)
      97             :       timescale_[i] *= decrease_factor_;
      98             :     }
      99             :     // check whether we need to increase the timescale:
     100             :     else if (fabs(q[i]) < increase_timescale_threshold_ and
     101             :              fabs(dtq[i] * timescale_[i]) <
     102             :                  (increase_timescale_threshold_ - fabs(q[i]))) {
     103             :       // if Q `and` dtQ are below the minimum required threshold
     104             :       timescale_[i] *= increase_factor_;
     105             :     }
     106             : 
     107             :     // make sure the timescale has not increased(decreased) above(below) the
     108             :     // maximum(minimum) value.
     109             :     timescale_[i] = std::clamp(timescale_[i], min_timescale_, max_timescale_);
     110             :   }
     111             : }

Generated by: LCOV version 1.14