SpECTRE Documentation Coverage Report
Current view: top level - Domain/FunctionsOfTime - QuaternionFunctionOfTime.hpp Hit Total Coverage
Commit: a6a8ee404306bec9d92da8ab89f636b037aefc25 Lines: 16 36 44.4 %
Date: 2024-07-26 22:35:59
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <array>
       7             : #include <boost/math/quaternion.hpp>
       8             : #include <cstddef>
       9             : #include <map>
      10             : #include <memory>
      11             : #include <ostream>
      12             : #include <pup.h>
      13             : #include <vector>
      14             : 
      15             : #include "DataStructures/DataVector.hpp"
      16             : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
      17             : #include "Domain/FunctionsOfTime/PiecewisePolynomial.hpp"
      18             : #include "Domain/FunctionsOfTime/ThreadsafeList.hpp"
      19             : #include "Utilities/Gsl.hpp"
      20             : #include "Utilities/Serialization/CharmPupable.hpp"
      21             : 
      22             : namespace domain::FunctionsOfTime {
      23             : /*!
      24             :  * \ingroup ComputationalDomainGroup
      25             :  * \brief A FunctionOfTime that stores quaternions for the rotation map
      26             :  *
      27             :  * \details This FunctionOfTime stores quaternions that will be used in the
      28             :  * time-dependent rotation map as well as the orbital angular velocity that
      29             :  * will be controlled by the rotation control sytem. To get the quaternion, an
      30             :  * ODE is solved of the form \f$ \dot{q} = \frac{1}{2} q \times \omega \f$
      31             :  * where \f$ \omega \f$ is the orbital angular velocity which is stored
      32             :  * internally as the derivative of an angle `PiecewisePolynomial`, and
      33             :  * \f$ \times \f$ here is quaternion multiplication.
      34             :  *
      35             :  * Different from a `PiecewisePolynomial`, only the quaternion
      36             :  * itself is stored, not any of the derivatives because the derivatives must be
      37             :  * calculated from the solved ODE at every function call. Because
      38             :  * derivatives of the quaternion are not stored, the template parameter
      39             :  * `MaxDeriv` refers to both the max derivative of the stored angle
      40             :  * PiecewisePolynomial and the max derivative returned by the
      41             :  * QuaternionFunctionOfTime. The `update` function is then just a wrapper
      42             :  * around the internal `PiecewisePolynomial::update` function with the addition
      43             :  * that it then updates the stored quaternions as well.
      44             :  *
      45             :  * The angle PiecewisePolynomial is accessible through the `angle_func`,
      46             :  * `angle_func_and_deriv`, and `angle_func_and_2_derivs` functions which
      47             :  * correspond to the function calls of a normal PiecewisePolynomial except
      48             :  * without the `angle_` prefix.
      49             :  *
      50             :  * It is encouraged to use `quat_func` and `angle_func` when you want the
      51             :  * specific values of the functions to avoid ambiguity in what you are
      52             :  * calling. However, the original three `func` functions inherited from the
      53             :  * FunctionOfTime base class are necessary because the maps use the generic
      54             :  * `func` functions, thus they return the quaternion and its derivatives (which
      55             :  * are needed for the map). This is all to keep the symmetry of naming
      56             :  * `angle_func` and `quat_func` so that function calls won't be ambiguous.
      57             :  *
      58             :  * \note This class conforms to the requirements of the
      59             :  * `Parallel::GlobalCache` for objects held by mutable global cache tags.
      60             :  */
      61             : template <size_t MaxDeriv>
      62           1 : class QuaternionFunctionOfTime : public FunctionOfTime {
      63             :  public:
      64           0 :   QuaternionFunctionOfTime();
      65           0 :   QuaternionFunctionOfTime(QuaternionFunctionOfTime&&);
      66           0 :   QuaternionFunctionOfTime(const QuaternionFunctionOfTime&);
      67           0 :   QuaternionFunctionOfTime& operator=(QuaternionFunctionOfTime&&);
      68           0 :   QuaternionFunctionOfTime& operator=(const QuaternionFunctionOfTime&);
      69           0 :   ~QuaternionFunctionOfTime() override;
      70             : 
      71           0 :   QuaternionFunctionOfTime(
      72             :       double t, const std::array<DataVector, 1>& initial_quat_func,
      73             :       std::array<DataVector, MaxDeriv + 1> initial_angle_func,
      74             :       double expiration_time);
      75             : 
      76             :   // LCOV_EXCL_START
      77           0 :   explicit QuaternionFunctionOfTime(CkMigrateMessage* /*unused*/);
      78             :   // LCOV_EXCL_STOP
      79             : 
      80           0 :   auto get_clone() const -> std::unique_ptr<FunctionOfTime> override;
      81             : 
      82             :   // clang-tidy: google-runtime-references
      83             :   // clang-tidy: cppcoreguidelines-owning-memory,-warnings-as-errors
      84           0 :   WRAPPED_PUPable_decl_template(QuaternionFunctionOfTime<MaxDeriv>);  // NOLINT
      85             : 
      86             :   /// Returns domain of validity for the function of time
      87           1 :   std::array<double, 2> time_bounds() const override;
      88             : 
      89           1 :   double expiration_after(double time) const override;
      90             : 
      91             :   /// Updates the `MaxDeriv`th derivative of the angle piecewisepolynomial at
      92             :   /// the given time, then updates the stored quaternions.
      93             :   ///
      94             :   /// `updated_max_deriv` is a datavector of the `MaxDeriv`s for each component.
      95             :   /// `next_expiration_time` is the next expiration time.
      96             :   ///
      97             :   /// The \p time_of_update must be the same as the old expiration
      98             :   /// time.  It is passed as a check that the calling code is
      99             :   /// computing the other arguments with the correct value.
     100           1 :   void update(double time_of_update, DataVector updated_max_deriv,
     101             :               double next_expiration_time) override;
     102             : 
     103             :   // NOLINTNEXTLINE(google-runtime-references)
     104           0 :   void pup(PUP::er& p) override;
     105             : 
     106             :   /// Returns the quaternion at an arbitrary time `t`.
     107           1 :   std::array<DataVector, 1> func(const double t) const override {
     108             :     return quat_func(t);
     109             :   }
     110             : 
     111             :   /// Returns the quaternion and its first derivative at an arbitrary time `t`.
     112           1 :   std::array<DataVector, 2> func_and_deriv(const double t) const override {
     113             :     return quat_func_and_deriv(t);
     114             :   }
     115             : 
     116             :   /// Returns the quaternion and the first two derivatives at an arbitrary
     117             :   /// time `t`.
     118           1 :   std::array<DataVector, 3> func_and_2_derivs(const double t) const override {
     119             :     return quat_func_and_2_derivs(t);
     120             :   }
     121             : 
     122             :   /// Returns the quaternion at an arbitrary time `t`.
     123           1 :   std::array<DataVector, 1> quat_func(double t) const;
     124             : 
     125             :   /// Returns the quaternion and its first derivative at an arbitrary time `t`.
     126           1 :   std::array<DataVector, 2> quat_func_and_deriv(double t) const;
     127             : 
     128             :   /// Returns the quaternion and the first two derivatives at an arbitrary
     129             :   /// time `t`.
     130           1 :   std::array<DataVector, 3> quat_func_and_2_derivs(double t) const;
     131             : 
     132             :   /// Returns the quaternion and the first three derivatives at an arbitrary
     133             :   /// time `t`.
     134           1 :   std::array<DataVector, 4> quat_func_and_3_derivs(double t) const;
     135             : 
     136             :   /// Returns stored angle at an arbitrary time `t`.
     137           1 :   std::array<DataVector, 1> angle_func(const double t) const {
     138             :     return angle_f_of_t_.func(t);
     139             :   }
     140             : 
     141             :   /// Returns stored angle and its first derivative (omega) at an arbitrary time
     142             :   /// `t`.
     143           1 :   std::array<DataVector, 2> angle_func_and_deriv(const double t) const {
     144             :     return angle_f_of_t_.func_and_deriv(t);
     145             :   }
     146             : 
     147             :   /// Returns stored angle and the first two derivatives at an arbitrary
     148             :   /// time `t`.
     149           1 :   std::array<DataVector, 3> angle_func_and_2_derivs(const double t) const {
     150             :     return angle_f_of_t_.func_and_2_derivs(t);
     151             :   }
     152             : 
     153           0 :   std::vector<DataVector> angle_func_and_all_derivs(const double t) const {
     154             :     return angle_f_of_t_.func_and_all_derivs(t);
     155             :   }
     156             : 
     157             :  private:
     158             :   template <size_t LocalMaxDeriv>
     159           0 :   friend bool operator==(  // NOLINT(readability-redundant-declaration)
     160             :       const QuaternionFunctionOfTime<LocalMaxDeriv>& lhs,
     161             :       const QuaternionFunctionOfTime<LocalMaxDeriv>& rhs);
     162             : 
     163             :   template <size_t LocalMaxDeriv>
     164           0 :   friend std::ostream& operator<<(  // NOLINT(readability-redundant-declaration)
     165             :       std::ostream& os,
     166             :       const QuaternionFunctionOfTime<LocalMaxDeriv>& quaternion_f_of_t);
     167             : 
     168             :   FunctionOfTimeHelpers::ThreadsafeList<boost::math::quaternion<double>>
     169           0 :       stored_quaternions_and_times_{};
     170           0 :   domain::FunctionsOfTime::PiecewisePolynomial<MaxDeriv> angle_f_of_t_{};
     171           0 :   std::map<double, double> update_backlog_{};
     172             : 
     173           0 :   void unpack_old_version(PUP::er& p, size_t version);
     174             : 
     175             :   /// Integrates the ODE \f$ \dot{q} = \frac{1}{2} q \times \omega \f$ from time
     176             :   /// `t0` to time `t`. On input, `quaternion_to_integrate` is the initial
     177             :   /// quaternion at time `t0` and on output, it stores the result at time `t`
     178           1 :   void solve_quaternion_ode(
     179             :       gsl::not_null<boost::math::quaternion<double>*> quaternion_to_integrate,
     180             :       double t0, double t) const;
     181             : 
     182             :   /// Does common operations to all the `func` functions such as updating stored
     183             :   /// info, solving the ODE, and returning the normalized quaternion as a boost
     184             :   /// quaternion for easy calculations
     185           1 :   boost::math::quaternion<double> setup_func(double t) const;
     186             : };
     187             : 
     188             : template <size_t MaxDeriv>
     189           0 : bool operator!=(const QuaternionFunctionOfTime<MaxDeriv>& lhs,
     190             :                 const QuaternionFunctionOfTime<MaxDeriv>& rhs);
     191             : 
     192             : /// \cond
     193             : template <size_t MaxDeriv>
     194             : PUP::able::PUP_ID QuaternionFunctionOfTime<MaxDeriv>::my_PUP_ID = 0;  // NOLINT
     195             : /// \endcond
     196             : }  // namespace domain::FunctionsOfTime

Generated by: LCOV version 1.14