SpECTRE Documentation Coverage Report
Current view: top level - ControlSystem - WriteData.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 50.0 % 2 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 <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 2.0-1