SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ObserveTimeStep.hpp Hit Total Coverage
Commit: ecb8a275e1aebab77dcce48a5e098ed4e486ab4b Lines: 3 32 9.4 %
Date: 2026-08-22 01:05:40
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 <tuple>
      10             : #include <type_traits>
      11             : #include <utility>
      12             : #include <vector>
      13             : 
      14             : #include "IO/Observer/Helpers.hpp"
      15             : #include "IO/Observer/ObservationId.hpp"
      16             : #include "IO/Observer/ObserverComponent.hpp"
      17             : #include "IO/Observer/Protocols/ReductionDataFormatter.hpp"
      18             : #include "IO/Observer/ReductionActions.hpp"
      19             : #include "IO/Observer/TypeOfObservation.hpp"
      20             : #include "Options/String.hpp"
      21             : #include "Parallel/ArrayComponentId.hpp"
      22             : #include "Parallel/ArrayIndex.hpp"
      23             : #include "Parallel/GlobalCache.hpp"
      24             : #include "Parallel/Info.hpp"
      25             : #include "Parallel/Invoke.hpp"
      26             : #include "Parallel/Local.hpp"
      27             : #include "Parallel/Reduction.hpp"
      28             : #include "Parallel/TypeTraits.hpp"
      29             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      30             : #include "Utilities/Functional.hpp"
      31             : #include "Utilities/ProtocolHelpers.hpp"
      32             : #include "Utilities/Serialization/CharmPupable.hpp"
      33             : #include "Utilities/TMPL.hpp"
      34             : 
      35             : /// \cond
      36             : class TimeDelta;
      37             : namespace PUP {
      38             : class er;
      39             : }  // namespace PUP
      40             : namespace Tags {
      41             : struct TimeStep;
      42             : }  // namespace Tags
      43             : /// \endcond
      44             : 
      45             : namespace Events {
      46             : namespace detail {
      47             : using ObserveTimeStepReductionData = Parallel::ReductionData<
      48             :     Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      49             :     Parallel::ReductionDatum<size_t, funcl::Plus<>>,
      50             :     Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      51             :     Parallel::ReductionDatum<double, funcl::Min<>>,
      52             :     Parallel::ReductionDatum<double, funcl::Max<>>,
      53             :     Parallel::ReductionDatum<
      54             :         double, funcl::Plus<>,
      55             :         funcl::Divides<funcl::Literal<1, double>, funcl::Divides<>>,
      56             :         std::index_sequence<1>>,
      57             :     Parallel::ReductionDatum<double, funcl::Min<>>,
      58             :     Parallel::ReductionDatum<double, funcl::Max<>>>;
      59             : 
      60             : struct FormatTimeOutput
      61             :     : tt::ConformsTo<observers::protocols::ReductionDataFormatter> {
      62             :   using reduction_data = ObserveTimeStepReductionData;
      63             :   std::string operator()(double time, size_t num_degrees_of_freedom,
      64             :                          double slab_size, double min_time_step,
      65             :                          double max_time_step, double effective_time_step,
      66             :                          double min_wall_time, double max_wall_time) const;
      67             :   // NOLINTNEXTLINE
      68             :   void pup(PUP::er& p);
      69             : };
      70             : }  // namespace detail
      71             : 
      72             : /*!
      73             :  * \brief %Observe the size of the time steps.
      74             :  *
      75             :  * Writes reduction quantities:
      76             :  * - `%Time`
      77             :  * - `Number of degrees of freedom`
      78             :  * - `%Slab size`
      79             :  * - `Minimum time step`
      80             :  * - `Maximum time step`
      81             :  * - `Effective time step`
      82             :  *
      83             :  * The effective time step is the step size of a global-time-stepping
      84             :  * method that would perform a similar amount of work.  This is the
      85             :  * harmonic mean of the step size over all degrees of freedom:
      86             :  *
      87             :  * \f{equation}
      88             :  * (\Delta t)_{\text{eff}}^{-1} =
      89             :  * \frac{\sum_{i \in \text{dof}} (\Delta t)_i^{-1}}{N_{\text{dof}}}.
      90             :  * \f}
      91             :  *
      92             :  * This corresponds to averaging the number of steps per unit time
      93             :  * taken by all points.
      94             :  *
      95             :  * All values are reported as positive numbers, even for backwards
      96             :  * evolutions.
      97             :  */
      98             : /// @{
      99             : template <typename System,
     100             :           typename = tmpl::conditional_t<
     101             :               tt::is_a_v<tmpl::list, typename System::variables_tag>,
     102             :               typename System::variables_tag,
     103             :               tmpl::list<typename System::variables_tag>>>
     104           1 : class ObserveTimeStep;
     105             : 
     106             : template <typename System, typename... VariablesTags>
     107           0 : class ObserveTimeStep<System, tmpl::list<VariablesTags...>> : public Event {
     108             :  private:
     109           0 :   using ReductionData = Events::detail::ObserveTimeStepReductionData;
     110             : 
     111             :  public:
     112             :   /// The name of the subfile inside the HDF5 file
     113           1 :   struct SubfileName {
     114           0 :     using type = std::string;
     115           0 :     static constexpr Options::String help = {
     116             :         "The name of the subfile inside the HDF5 file without an extension and "
     117             :         "without a preceding '/'."};
     118             :   };
     119             : 
     120           0 :   struct PrintTimeToTerminal {
     121           0 :     using type = bool;
     122           0 :     static constexpr Options::String help = {
     123             :         "Whether to print the time to screen."};
     124             :   };
     125             : 
     126           0 :   struct ObservePerCore {
     127           0 :     using type = bool;
     128           0 :     static constexpr Options::String help = {
     129             :         "Also write the data per-core in a file per-node."};
     130             :   };
     131             : 
     132             :   /// \cond
     133             :   explicit ObserveTimeStep(CkMigrateMessage* /*m*/);
     134             :   using PUP::able::register_constructor;
     135             :   WRAPPED_PUPable_decl_template(ObserveTimeStep);  // NOLINT
     136             :   /// \endcond
     137             : 
     138           0 :   using options = tmpl::list<SubfileName, PrintTimeToTerminal, ObservePerCore>;
     139           0 :   static constexpr Options::String help =
     140             :       "Observe the size of the time steps.\n"
     141             :       "\n"
     142             :       "Writes reduction quantities:\n"
     143             :       "- Time\n"
     144             :       "- Number of degrees of freedom\n"
     145             :       "- Slab size\n"
     146             :       "- Minimum time step\n"
     147             :       "- Maximum time step\n"
     148             :       "- Effective time step\n"
     149             :       "\n"
     150             :       "The effective time step is the step size of a global-time-stepping\n"
     151             :       "method that would perform a similar amount of work.\n"
     152             :       "\n"
     153             :       "All values are reported as positive numbers, even for backwards\n"
     154             :       "evolutions.";
     155             : 
     156           0 :   ObserveTimeStep();
     157           0 :   ObserveTimeStep(const std::string& subfile_name, bool output_time,
     158             :                   bool observe_per_core);
     159             : 
     160           0 :   using observed_reduction_data_tags =
     161             :       observers::make_reduction_data_tags<tmpl::list<ReductionData>>;
     162             : 
     163           0 :   using compute_tags_for_observation_box = tmpl::list<>;
     164             : 
     165           0 :   using return_tags = tmpl::list<>;
     166             :   // We obtain the grid size from the variables, rather than the mesh,
     167             :   // so that this observer is not DG-specific.
     168           0 :   using argument_tags = tmpl::list<::Tags::TimeStep, VariablesTags...>;
     169             : 
     170             :   template <typename ArrayIndex, typename ParallelComponent,
     171             :             typename Metavariables>
     172           0 :   void operator()(const TimeDelta& time_step,
     173             :                   const typename VariablesTags::type&... variables,
     174             :                   Parallel::GlobalCache<Metavariables>& cache,
     175             :                   const ArrayIndex& array_index,
     176             :                   const ParallelComponent* const /*meta*/,
     177             :                   const ObservationValue& observation_value) const {
     178             :     auto [observation_id, legend, reduction_data, formatter] =
     179             :         assemble_data(time_step, variables..., observation_value);
     180             : 
     181             :     auto& local_observer = *Parallel::local_branch(
     182             :         Parallel::get_parallel_component<
     183             :             tmpl::conditional_t<Parallel::is_nodegroup_v<ParallelComponent>,
     184             :                                 observers::ObserverWriter<Metavariables>,
     185             :                                 observers::Observer<Metavariables>>>(cache));
     186             : 
     187             :     Parallel::ArrayComponentId array_component_id{
     188             :         std::add_pointer_t<ParallelComponent>{nullptr},
     189             :         Parallel::ArrayIndex<ArrayIndex>(array_index)};
     190             : 
     191             :     if constexpr (Parallel::is_nodegroup_v<ParallelComponent>) {
     192             :       const std::optional<int> observe_with_core_id =
     193             :           observe_per_core_
     194             :               ? std::make_optional(Parallel::my_node<int>(local_observer))
     195             :               : std::nullopt;
     196             :       Parallel::threaded_action<
     197             :           observers::ThreadedActions::CollectReductionDataOnNode>(
     198             :           local_observer, std::move(observation_id),
     199             :           std::move(array_component_id), subfile_path_, std::move(legend),
     200             :           std::move(reduction_data), std::move(formatter),
     201             :           observe_with_core_id);
     202             :     } else {
     203             :       Parallel::simple_action<observers::Actions::ContributeReductionData>(
     204             :           local_observer, std::move(observation_id),
     205             :           std::move(array_component_id), subfile_path_, std::move(legend),
     206             :           std::move(reduction_data), std::move(formatter), observe_per_core_);
     207             :     }
     208             :   }
     209             : 
     210           0 :   using observation_registration_tags = tmpl::list<>;
     211             :   std::pair<observers::TypeOfObservation, observers::ObservationKey>
     212           0 :   get_observation_type_and_key_for_registration() const;
     213             : 
     214           0 :   using is_ready_argument_tags = tmpl::list<>;
     215             : 
     216             :   template <typename Metavariables, typename ArrayIndex, typename Component>
     217           0 :   bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
     218             :                 const ArrayIndex& /*array_index*/,
     219             :                 const Component* const /*meta*/) const {
     220             :     return true;
     221             :   }
     222             : 
     223           1 :   bool needs_evolved_variables() const override;
     224             : 
     225             :   // NOLINTNEXTLINE(google-runtime-references)
     226           0 :   void pup(PUP::er& p) override;
     227             : 
     228             :  private:
     229           0 :   auto assemble_data(const TimeDelta& time_step,
     230             :                      const typename VariablesTags::type&... variables,
     231             :                      const ObservationValue& observation_value) const
     232             :       -> std::tuple<observers::ObservationId, std::vector<std::string>,
     233             :                     ReductionData,
     234             :                     std::optional<Events::detail::FormatTimeOutput>>;
     235             : 
     236           0 :   std::string subfile_path_;
     237           0 :   bool output_time_;
     238           0 :   bool observe_per_core_;
     239             : };
     240             : /// @}
     241             : }  // namespace Events

Generated by: LCOV version 1.14