SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem/Protocols - ControlSystem.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 11.1 % 9 1
Test Date: 2026-10-22 17:29:42
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 <cstddef>
       7              : #include <optional>
       8              : #include <string>
       9              : #include <type_traits>
      10              : 
      11              : #include "ControlSystem/Protocols/ControlError.hpp"
      12              : #include "ControlSystem/Protocols/Measurement.hpp"
      13              : #include "Utilities/ProtocolHelpers.hpp"
      14              : #include "Utilities/TMPL.hpp"
      15              : 
      16              : namespace control_system::protocols {
      17              : /// \brief Definition of a control system
      18              : ///
      19              : /// Defines a control system for controlling a FunctionOfTime.
      20              : ///
      21              : /// A conforming class must provide the following functionality:
      22              : ///
      23              : /// - a static function `name` returning a `std::string`.  This
      24              : ///   corresponds to the name of the FunctionOfTime controlled by this
      25              : ///   system.
      26              : ///
      27              : /// - a static function `component_name` returning a
      28              : ///   `std::optional<std::string>`.  This gives a name associated to each
      29              : ///   component of the FunctionOfTime that is being controlled. E.g. a
      30              : ///   FunctionOfTime controlling translation will have three components with
      31              : ///   names "X", "Y", and "Z". This is useful when writing data to disk. The
      32              : ///   reason this is a `std::optional` rather than just a `std::string` is
      33              : ///   because of shape control. Since the vector of coefficients of the shape
      34              : ///   map is stored in ylm::Spherepack order, not all components of this vector
      35              : ///   correspond to an actual l,m pair (see ylm::Spherepack for why this is).
      36              : ///   Thus, this is a `std::optional` to signify if a component of the
      37              : ///   FunctionOfTime isn't actually used and shouldn't be written to disk.
      38              : ///
      39              : /// - a type alias `measurement` to a struct implementing the
      40              : ///   Measurement protocol.
      41              : ///
      42              : /// - a type alias `simple_tags` to a `tmpl::list` of simple tags needed for the
      43              : ///   control system. These tags will be added to the DataBox of the
      44              : ///   ControlComponent. The list may be empty.
      45              : ///
      46              : /// - a type alias `control_error` to a struct that conforms to the ControlError
      47              : ///   protocol
      48              : ///
      49              : /// - a static constexpr size_t `deriv_order` which is the order of the highest
      50              : ///   derivative of a FunctionOfTime that you wish to control. Typically, this
      51              : ///   is the order of the FunctionOfTime itself.
      52              : ///
      53              : /// - a member struct (or type alias) `process_measurement`, defining
      54              : ///   the following:
      55              : ///
      56              : ///   - a templated type alias `argument_tags`, which must produce a
      57              : ///     `tmpl::list` of tags when instantiated for any submeasurement
      58              : ///     of the control system's `measurement`.
      59              : ///
      60              : ///   - a static function `apply` that accepts as arguments:
      61              : ///
      62              : ///     - any submeasurement of the control system's `measurement`.
      63              : ///       For measurements with multiple submeasurements, this can be
      64              : ///       accomplished either by a template parameter or by
      65              : ///       overloading the function.
      66              : ///
      67              : ///     - the values corresponding to `argument_tags` instantiated with the
      68              : ///       type of the first argument.
      69              : ///
      70              : ///     - the global cache `Parallel::GlobalCache<Metavariables>&`
      71              : ///
      72              : ///     - a `const LinkedMessageId<double>&` identifying the
      73              : ///       measurement, with the `id` field being the measurement time.
      74              : ///
      75              : ///   The `apply` function will be called once for each submeasurement
      76              : ///   of the control system's `measurement` using data from the
      77              : ///   `DataBox` passed to `RunCallbacks`.  It should communicate any
      78              : ///   necessary data to the control system singleton.
      79              : ///
      80              : /// Here's an example for a class conforming to this protocol:
      81              : ///
      82              : /// \snippet Helpers/ControlSystem/Examples.hpp ControlSystem
      83            1 : struct ControlSystem {
      84              :   template <typename ConformingType>
      85            0 :   struct test {
      86              :     static_assert(std::is_same_v<std::decay_t<decltype(ConformingType::name())>,
      87              :                                  std::string>);
      88              : 
      89              :     static_assert(std::is_same_v<decltype(ConformingType::component_name(
      90              :                                      std::declval<const size_t>(),
      91              :                                      std::declval<const size_t>())),
      92              :                                  std::optional<std::string>>);
      93              : 
      94            0 :     using measurement = typename ConformingType::measurement;
      95              :     static_assert(tt::assert_conforms_to_v<measurement, Measurement>);
      96              : 
      97              :     template <typename Submeasurement>
      98            0 :     struct check_process_measurement_argument_tags {
      99            0 :       using type =
     100              :           typename ConformingType::process_measurement::template argument_tags<
     101              :               Submeasurement>;
     102              :     };
     103              : 
     104            0 :     using simple_tags = typename ConformingType::simple_tags;
     105              : 
     106            0 :     using control_error = typename ConformingType::control_error;
     107              :     static_assert(tt::assert_conforms_to_v<control_error, ControlError>);
     108              : 
     109              :     static_assert(
     110              :         std::is_same_v<decltype(ConformingType::deriv_order), const size_t>);
     111              : 
     112            0 :     using process_measurement_argument_tags =
     113              :         tmpl::transform<typename measurement::submeasurements,
     114              :                         check_process_measurement_argument_tags<tmpl::_1>>;
     115              : 
     116              :     // We can't check the apply operator, because the tags may be
     117              :     // incomplete types, so we don't know what the argument types are.
     118              :   };
     119              : };
     120              : }  // namespace control_system::protocols
        

Generated by: LCOV version 2.0-1