SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ErrorIfDataTooBig.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 8.3 % 24 2
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 <cmath>
       7              : #include <cstddef>
       8              : #include <limits>
       9              : #include <optional>
      10              : #include <pup.h>
      11              : #include <string>
      12              : #include <type_traits>
      13              : #include <unordered_set>
      14              : #include <vector>
      15              : 
      16              : #include "DataStructures/DataBox/ObservationBox.hpp"
      17              : #include "DataStructures/DataBox/TagName.hpp"
      18              : #include "DataStructures/DataBox/ValidateSelection.hpp"
      19              : #include "DataStructures/DataVector.hpp"
      20              : #include "DataStructures/ExtractPoint.hpp"
      21              : #include "DataStructures/Tensor/Tensor.hpp"
      22              : #include "DataStructures/Tensor/TypeAliases.hpp"
      23              : #include "Domain/Tags.hpp"
      24              : #include "Options/String.hpp"
      25              : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      26              : #include "Utilities/ErrorHandling/Error.hpp"
      27              : #include "Utilities/Serialization/CharmPupable.hpp"
      28              : #include "Utilities/TMPL.hpp"
      29              : #include "Utilities/TypeTraits/IsA.hpp"
      30              : 
      31              : /// \cond
      32              : namespace Frame {
      33              : struct Inertial;
      34              : }  // namespace Frame
      35              : namespace Parallel {
      36              : template <typename Metavariables>
      37              : class GlobalCache;
      38              : }  // namespace Parallel
      39              : namespace domain::Tags {
      40              : template <size_t Dim, typename Frame>
      41              : struct Coordinates;
      42              : }  // namespace domain::Tags
      43              : /// \endcond
      44              : 
      45              : namespace Events {
      46              : /*!
      47              :  * \brief ERROR if tensors get too big.
      48              :  *
      49              :  * The magnitudes of the components of the specified tensors are
      50              :  * checked, and if any exceed the specified threshold an ERROR is
      51              :  * thrown, terminating the evolution.
      52              :  *
      53              :  * Any `Tensor` in the `db::DataBox` can be checked but must be listed
      54              :  * in the `Tensors` template parameter. Any additional compute tags
      55              :  * that hold a `Tensor` can also be added to the `Tensors` template
      56              :  * parameter. Finally, `Variables` and other non-tensor compute tags
      57              :  * used to calculate tensors can be listed in the
      58              :  * `NonTensorComputeTags`.
      59              :  *
      60              :  * \note The `NonTensorComputeTags` are intended to be used for `Variables`
      61              :  * compute tags like `Tags::DerivCompute`
      62              :  */
      63              : template <size_t Dim, typename Tensors, typename NonTensorComputeTags>
      64            1 : class ErrorIfDataTooBig : public Event {
      65              :  public:
      66              :   /// \cond
      67              :   explicit ErrorIfDataTooBig(CkMigrateMessage* /*unused*/) {}
      68              :   using PUP::able::register_constructor;
      69              :   WRAPPED_PUPable_decl_template(ErrorIfDataTooBig);  // NOLINT
      70              :   /// \endcond
      71              : 
      72            0 :   struct VariablesToCheck {
      73            0 :     static constexpr Options::String help = "Subset of variables to check";
      74            0 :     using type = std::vector<std::string>;
      75            0 :     static size_t lower_bound_on_size() { return 1; }
      76              :   };
      77              : 
      78            0 :   struct Threshold {
      79            0 :     static constexpr Options::String help = "Threshold at which to ERROR";
      80            0 :     using type = double;
      81            0 :     static type lower_bound() { return 0.0; }
      82              :   };
      83              : 
      84            0 :   using options = tmpl::list<VariablesToCheck, Threshold>;
      85              : 
      86            0 :   static constexpr Options::String help = "ERROR if tensors get too big";
      87              : 
      88            0 :   ErrorIfDataTooBig() = default;
      89              : 
      90            0 :   ErrorIfDataTooBig(const std::vector<std::string>& variables_to_check,
      91              :                     const double threshold, const Options::Context& context)
      92              :       : variables_to_check_(variables_to_check.begin(),
      93              :                             variables_to_check.end()),
      94              :         threshold_(threshold) {
      95              :     db::validate_selection<Tensors>(variables_to_check, context);
      96              :   }
      97              : 
      98            0 :   using compute_tags_for_observation_box =
      99              :       tmpl::append<Tensors, NonTensorComputeTags>;
     100              : 
     101            0 :   using return_tags = tmpl::list<>;
     102            0 :   using argument_tags =
     103              :       tmpl::list<::Tags::ObservationBox,
     104              :                  ::domain::Tags::Coordinates<Dim, Frame::Inertial>>;
     105              : 
     106              :   template <typename ComputeTagsList, typename DataBoxType,
     107              :             typename Metavariables, typename ArrayIndex,
     108              :             typename ParallelComponent>
     109            0 :   void operator()(const ObservationBox<ComputeTagsList, DataBoxType>& box,
     110              :                   const tnsr::I<DataVector, Dim>& coordinates,
     111              :                   Parallel::GlobalCache<Metavariables>& /*cache*/,
     112              :                   const ArrayIndex& /*array_index*/,
     113              :                   const ParallelComponent* const /*component*/,
     114              :                   const ObservationValue& /*observation_value*/) const {
     115              :     tmpl::for_each<Tensors>([&](const auto tensor_tag_v) {
     116              :       using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
     117              :       const std::string tag_name = db::tag_name<tensor_tag>();
     118              :       if (variables_to_check_.count(tag_name) != 0) {
     119              :         const auto check_components = [&](const auto& tensor) {
     120              :           for (const auto& component : tensor) {
     121              :             for (size_t point = 0; point < component.size(); ++point) {
     122              :               if (std::abs(component[point]) > threshold_) {
     123              :                 ERROR_NO_TRACE(
     124              :                     tag_name
     125              :                     << " too big with value " << extract_point(tensor, point)
     126              :                     << " at position\n"
     127              :                     << extract_point(coordinates, point) << "\nwith ElementId: "
     128              :                     << get<::domain::Tags::Element<Dim>>(box).id());
     129              :               }
     130              :             }
     131              :           }
     132              :         };
     133              :         const auto& tensor = get<tensor_tag>(box);
     134              :         if constexpr (tt::is_a_v<std::optional,
     135              :                                  std::decay_t<decltype(tensor)>>) {
     136              :           if (tensor.has_value()) {
     137              :             check_components(*tensor);
     138              :           }
     139              :         } else {
     140              :           check_components(tensor);
     141              :         }
     142              :       }
     143              :     });
     144              :   }
     145              : 
     146            0 :   using is_ready_argument_tags = tmpl::list<>;
     147              : 
     148              :   template <typename Metavariables, typename ArrayIndex, typename Component>
     149            0 :   bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
     150              :                 const ArrayIndex& /*array_index*/,
     151              :                 const Component* const /*meta*/) const {
     152              :     return true;
     153              :   }
     154              : 
     155            1 :   bool needs_evolved_variables() const override { return true; }
     156              : 
     157              :   // NOLINTNEXTLINE(google-runtime-references)
     158            0 :   void pup(PUP::er& p) override {
     159              :     Event::pup(p);
     160              :     p | variables_to_check_;
     161              :     p | threshold_;
     162              :   }
     163              : 
     164              :  private:
     165            0 :   std::unordered_set<std::string> variables_to_check_{};
     166            0 :   double threshold_ = std::numeric_limits<double>::signaling_NaN();
     167              : };
     168              : 
     169              : /// \cond
     170              : template <size_t Dim, typename Tensors, typename NonTensorComputeTags>
     171              : PUP::able::PUP_ID
     172              :     ErrorIfDataTooBig<Dim, Tensors,
     173              :                       NonTensorComputeTags>::my_PUP_ID = 0;  // NOLINT
     174              : /// \endcond
     175              : }  // namespace Events
        

Generated by: LCOV version 2.0-1