SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem - WriteData.hpp Hit Total Coverage
Commit: 697db44127ce57424c079f629b3283267ec6bd78 Lines: 1 2 50.0 %
Date: 2024-06-21 21:13:41
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 <cstddef>
       8             : #include <memory>
       9             : #include <optional>
      10             : #include <string>
      11             : #include <tuple>
      12             : #include <vector>
      13             : 
      14             : #include "ControlSystem/Component.hpp"
      15             : #include "DataStructures/DataVector.hpp"
      16             : #include "Domain/FunctionsOfTime/FunctionOfTime.hpp"
      17             : #include "Domain/FunctionsOfTime/QuaternionFunctionOfTime.hpp"
      18             : #include "IO/Observer/ReductionActions.hpp"
      19             : #include "Parallel/GlobalCache.hpp"
      20             : #include "Parallel/Info.hpp"
      21             : #include "Parallel/Invoke.hpp"
      22             : 
      23             : namespace control_system {
      24             : /*!
      25             :  * \ingroup ControlSystemGroup
      26             :  * \brief Writes all components of a function of time to disk at a specific time
      27             :  * from a control system after it updates the functions of time.
      28             :  *
      29             :  * \details The columns of data written are:
      30             :  * - %Time
      31             :  * - FunctionOfTime
      32             :  * - dtFunctionOfTime
      33             :  * - d2tFunctionOfTime
      34             :  * - ControlError
      35             :  * - dtControlError
      36             :  * - DampingTimescale
      37             :  *
      38             :  * Data will be stored in the reduction file. All subfiles for the control
      39             :  * system within the H5 file will be under the group "/ControlSystems".
      40             :  * Within this group, there will be one group for each control system. The name
      41             :  * of each group will be the result of the `name()` function from each control
      42             :  * system. An example would look like
      43             :  *
      44             :  * - /ControlSystems/SystemA
      45             :  * - /ControlSystems/SystemB
      46             :  * - /ControlSystems/SystemC
      47             :  *
      48             :  * Then, within each system group, there will be one subfile for each component
      49             :  * of the function of time that is being controlled. The name of this subfile is
      50             :  * the name of the component. The name of each component will be the result of
      51             :  * the `component_name(i)` function from the control system, where `i` is the
      52             :  * index of the component. For example, if "SystemA" has 3 components with names
      53             :  * "X", "Y", and "Z", then the subfiles would look like
      54             :  *
      55             :  * - /ControlSystems/SystemA/X.dat
      56             :  * - /ControlSystems/SystemA/Y.dat
      57             :  * - /ControlSystems/SystemA/Z.dat
      58             :  */
      59             : template <typename ControlSystem, typename Metavariables>
      60           1 : void write_components_to_disk(
      61             :     const double time, Parallel::GlobalCache<Metavariables>& cache,
      62             :     const std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>&
      63             :         function_of_time,
      64             :     const std::array<DataVector, 2>& q_and_dtq, const DataVector& timescales) {
      65             :   auto& observer_writer_proxy = Parallel::get_parallel_component<
      66             :       observers::ObserverWriter<Metavariables>>(cache);
      67             : 
      68             :   constexpr size_t deriv_order = ControlSystem::deriv_order;
      69             :   std::array<DataVector, 3> function_at_current_time{};
      70             :   const auto* const quat_func_of_time = dynamic_cast<
      71             :       const domain::FunctionsOfTime::QuaternionFunctionOfTime<deriv_order>*>(
      72             :       function_of_time.get());
      73             :   if (quat_func_of_time == nullptr) {
      74             :     // Just call the usual `func_and_2_derivs` member.
      75             :     function_at_current_time = function_of_time->func_and_2_derivs(time);
      76             :   } else {
      77             :     // If we are working with a QuaternionFunctionOfTime, we aren't actually
      78             :     // controlling a quaternion. We are controlling a small change in angle
      79             :     // associated with the angular velocity in each direction. Because of this,
      80             :     // we want to write the component data of the thing we are actually
      81             :     // controlling. This is accessed by the `angle_func_and_2_derivs` member of
      82             :     // a QuaternionFunctionOfTime. Since `angle_func_and_2_derivs` is not a
      83             :     // virtual function of the FunctionOfTime base class, we need to down cast
      84             :     // the original function to a QuaternionFunctionOfTime.
      85             :     function_at_current_time = quat_func_of_time->angle_func_and_2_derivs(time);
      86             :   }
      87             : 
      88             :   // Each control system is its own group under the overarching `ControlSystems`
      89             :   // group. There is a different subfile for each component, so loop over them.
      90             :   // Eg. translation files will look like
      91             :   //
      92             :   // ControlSystems/Translation/X.dat
      93             :   // ControlSystems/Translation/Y.dat
      94             :   // ControlSystems/Translation/Z.dat
      95             :   const size_t num_components = function_at_current_time[0].size();
      96             :   for (size_t i = 0; i < num_components; ++i) {
      97             :     const std::optional<std::string> component_name_opt =
      98             :         ControlSystem::component_name(i, num_components);
      99             :     if (not component_name_opt) {
     100             :       continue;
     101             :     }
     102             :     // Currently all reduction data is written to the reduction file so preface
     103             :     // everything with ControlSystems/
     104             :     const std::string subfile_name{"/ControlSystems/" + ControlSystem::name() +
     105             :                                    "/" + *component_name_opt};
     106             :     std::vector<std::string> legend{"Time",
     107             :                                     "FunctionOfTime",
     108             :                                     "dtFunctionOfTime",
     109             :                                     "d2tFunctionOfTime",
     110             :                                     "ControlError",
     111             :                                     "dtControlError",
     112             :                                     "DampingTimescale"};
     113             : 
     114             :     Parallel::threaded_action<
     115             :         observers::ThreadedActions::WriteReductionDataRow>(
     116             :         // Node 0 is always the writer
     117             :         observer_writer_proxy[0], subfile_name, std::move(legend),
     118             :         std::make_tuple(
     119             :             // clang-format off
     120             :             time,
     121             :             function_at_current_time[0][i],
     122             :             function_at_current_time[1][i],
     123             :             function_at_current_time[2][i],
     124             :             q_and_dtq[0][i],
     125             :             q_and_dtq[1][i],
     126             :             timescales[i])
     127             :         // clang-format on
     128             :     );
     129             :   }
     130             : }
     131             : }  // namespace control_system

Generated by: LCOV version 1.14