SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ObserveErrorNorms.hpp Hit Total Coverage
Commit: b1342d46f40e2d46bbd11d0cef68fd973031a24b Lines: 2 24 8.3 %
Date: 2020-09-24 20:24: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 <pup.h>
       8             : #include <string>
       9             : #include <utility>
      10             : #include <vector>
      11             : 
      12             : #include "DataStructures/DataBox/Prefixes.hpp"
      13             : #include "DataStructures/DataBox/TagName.hpp"
      14             : #include "Domain/Tags.hpp"
      15             : #include "IO/Observer/ArrayComponentId.hpp"
      16             : #include "IO/Observer/Helpers.hpp"
      17             : #include "IO/Observer/ObservationId.hpp"
      18             : #include "IO/Observer/ObserverComponent.hpp"  // IWYU pragma: keep
      19             : #include "IO/Observer/ReductionActions.hpp"   // IWYU pragma: keep
      20             : #include "IO/Observer/TypeOfObservation.hpp"
      21             : #include "Options/Options.hpp"
      22             : #include "Parallel/ArrayIndex.hpp"
      23             : #include "Parallel/CharmPupable.hpp"
      24             : #include "Parallel/GlobalCache.hpp"
      25             : #include "Parallel/Invoke.hpp"
      26             : #include "Parallel/Reduction.hpp"
      27             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      28             : #include "PointwiseFunctions/AnalyticSolutions/Tags.hpp"
      29             : #include "Utilities/ConstantExpressions.hpp"
      30             : #include "Utilities/Functional.hpp"
      31             : #include "Utilities/Numeric.hpp"
      32             : #include "Utilities/Registration.hpp"
      33             : #include "Utilities/TMPL.hpp"
      34             : #include "Utilities/TaggedTuple.hpp"
      35             : 
      36             : /// \cond
      37             : namespace Frame {
      38             : struct Inertial;
      39             : }  // namespace Frame
      40             : /// \endcond
      41             : 
      42             : namespace dg {
      43           0 : namespace Events {
      44             : template <typename ObservationValueTag, typename Tensors,
      45             :           typename EventRegistrars>
      46           0 : class ObserveErrorNorms;
      47             : 
      48           0 : namespace Registrars {
      49             : template <typename ObservationValueTag, typename Tensors>
      50           0 : using ObserveErrorNorms =
      51             :     ::Registration::Registrar<Events::ObserveErrorNorms, ObservationValueTag,
      52             :                               Tensors>;
      53             : }  // namespace Registrars
      54             : 
      55             : template <typename ObservationValueTag, typename Tensors,
      56             :           typename EventRegistrars = tmpl::list<
      57             :               Registrars::ObserveErrorNorms<ObservationValueTag, Tensors>>>
      58             : class ObserveErrorNorms;  // IWYU pragma: keep
      59             : 
      60             : /*!
      61             :  * \ingroup DiscontinuousGalerkinGroup
      62             :  * \brief %Observe the RMS errors in the tensors compared to their
      63             :  * analytic solution.
      64             :  *
      65             :  * Writes reduction quantities:
      66             :  * - `ObservationValueTag`
      67             :  * - `NumberOfPoints` = total number of points in the domain
      68             :  * - `Error(*)` = RMS errors in `Tensors` =
      69             :  *   \f$\operatorname{RMS}\left(\sqrt{\sum_{\text{independent components}}\left[
      70             :  *   \text{value} - \text{analytic solution}\right]^2}\right)\f$
      71             :  *   over all points
      72             :  */
      73             : template <typename ObservationValueTag, typename... Tensors,
      74             :           typename EventRegistrars>
      75             : class ObserveErrorNorms<ObservationValueTag, tmpl::list<Tensors...>,
      76           1 :                         EventRegistrars> : public Event<EventRegistrars> {
      77             :  private:
      78             :   template <typename Tag>
      79           0 :   struct LocalSquareError {
      80           0 :     using type = double;
      81             :   };
      82             : 
      83           0 :   using L2ErrorDatum = Parallel::ReductionDatum<double, funcl::Plus<>,
      84             :                                                 funcl::Sqrt<funcl::Divides<>>,
      85             :                                                 std::index_sequence<1>>;
      86           0 :   using ReductionData = tmpl::wrap<
      87             :       tmpl::append<
      88             :           tmpl::list<Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      89             :                      Parallel::ReductionDatum<size_t, funcl::Plus<>>>,
      90             :           tmpl::filled_list<L2ErrorDatum, sizeof...(Tensors)>>,
      91             :       Parallel::ReductionData>;
      92             : 
      93             :  public:
      94             :   /// The name of the subfile inside the HDF5 file
      95           1 :   struct SubfileName {
      96           0 :     using type = std::string;
      97           0 :     static constexpr Options::String help = {
      98             :         "The name of the subfile inside the HDF5 file without an extension and "
      99             :         "without a preceding '/'."};
     100             :   };
     101             : 
     102             :   /// \cond
     103             :   explicit ObserveErrorNorms(CkMigrateMessage* /*unused*/) noexcept {}
     104             :   using PUP::able::register_constructor;
     105             :   WRAPPED_PUPable_decl_template(ObserveErrorNorms);  // NOLINT
     106             :   /// \endcond
     107             : 
     108           0 :   using options = tmpl::list<SubfileName>;
     109           0 :   static constexpr Options::String help =
     110             :       "Observe the RMS errors in the tensors compared to their analytic\n"
     111             :       "solution.\n"
     112             :       "\n"
     113             :       "Writes reduction quantities:\n"
     114             :       " * ObservationValueTag\n"
     115             :       " * NumberOfPoints = total number of points in the domain\n"
     116             :       " * Error(*) = RMS errors in Tensors (see online help details)\n"
     117             :       "\n"
     118             :       "Warning: Currently, only one reduction observation event can be\n"
     119             :       "triggered at a given observation value.  Causing multiple events to\n"
     120             :       "run at once will produce unpredictable results.";
     121             : 
     122           0 :   ObserveErrorNorms() = default;
     123           0 :   explicit ObserveErrorNorms(const std::string& subfile_name) noexcept;
     124             : 
     125           0 :   using observed_reduction_data_tags =
     126             :       observers::make_reduction_data_tags<tmpl::list<ReductionData>>;
     127             : 
     128           0 :   using argument_tags =
     129             :       tmpl::list<ObservationValueTag, Tensors..., ::Tags::Analytic<Tensors>...>;
     130             : 
     131             :   template <typename Metavariables, typename ArrayIndex,
     132             :             typename ParallelComponent>
     133           0 :   void operator()(
     134             :       const typename ObservationValueTag::type& observation_value,
     135             :       const typename Tensors::type&... tensors,
     136             :       const typename ::Tags::Analytic<Tensors>::type&... analytic_tensors,
     137             :       Parallel::GlobalCache<Metavariables>& cache,
     138             :       const ArrayIndex& array_index,
     139             :       const ParallelComponent* const /*meta*/) const noexcept {
     140             :     tuples::TaggedTuple<LocalSquareError<Tensors>...> local_square_errors;
     141             :     const auto record_errors = [&local_square_errors](
     142             :         const auto tensor_tag_v, const auto& tensor,
     143             :         const auto& analytic_tensor) noexcept {
     144             :       using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
     145             :       double local_square_error = 0.0;
     146             :       for (size_t i = 0; i < tensor.size(); ++i) {
     147             :         const auto error = tensor[i] - analytic_tensor[i];
     148             :         local_square_error += alg::accumulate(square(error), 0.0);
     149             :       }
     150             :       get<LocalSquareError<tensor_tag>>(local_square_errors) =
     151             :           local_square_error;
     152             :       return 0;
     153             :     };
     154             :     expand_pack(
     155             :         record_errors(tmpl::type_<Tensors>{}, tensors, analytic_tensors)...);
     156             :     const size_t num_points = get_first_argument(tensors...).begin()->size();
     157             : 
     158             :     // Send data to reduction observer
     159             :     auto& local_observer =
     160             :         *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
     161             :              cache)
     162             :              .ckLocalBranch();
     163             :     Parallel::simple_action<observers::Actions::ContributeReductionData>(
     164             :         local_observer,
     165             :         observers::ObservationId(observation_value, subfile_path_ + ".dat"),
     166             :         observers::ArrayComponentId{
     167             :             std::add_pointer_t<ParallelComponent>{nullptr},
     168             :             Parallel::ArrayIndex<ArrayIndex>(array_index)},
     169             :         subfile_path_,
     170             :         std::vector<std::string>{db::tag_name<ObservationValueTag>(),
     171             :                                  "NumberOfPoints",
     172             :                                  ("Error(" + db::tag_name<Tensors>() + ")")...},
     173             :         ReductionData{
     174             :             static_cast<double>(observation_value), num_points,
     175             :             std::move(get<LocalSquareError<Tensors>>(local_square_errors))...});
     176             :   }
     177             : 
     178           0 :   using observation_registration_tags = tmpl::list<>;
     179             :   std::pair<observers::TypeOfObservation, observers::ObservationKey>
     180           0 :   get_observation_type_and_key_for_registration() const noexcept {
     181             :     return {observers::TypeOfObservation::Reduction,
     182             :             observers::ObservationKey(subfile_path_ + ".dat")};
     183             :   }
     184             : 
     185             :   // NOLINTNEXTLINE(google-runtime-references)
     186           0 :   void pup(PUP::er& p) override {
     187             :     Event<EventRegistrars>::pup(p);
     188             :     p | subfile_path_;
     189             :   }
     190             : 
     191             :  private:
     192           0 :   std::string subfile_path_;
     193             : };
     194             : 
     195             : template <typename ObservationValueTag, typename... Tensors,
     196             :           typename EventRegistrars>
     197             : ObserveErrorNorms<ObservationValueTag, tmpl::list<Tensors...>,
     198             :                   EventRegistrars>::ObserveErrorNorms(const std::string&
     199             :                                                           subfile_name) noexcept
     200             :     : subfile_path_("/" + subfile_name) {}
     201             : 
     202             : /// \cond
     203             : template <typename ObservationValueTag, typename... Tensors,
     204             :           typename EventRegistrars>
     205             : PUP::able::PUP_ID ObserveErrorNorms<ObservationValueTag, tmpl::list<Tensors...>,
     206             :                                     EventRegistrars>::my_PUP_ID = 0;  // NOLINT
     207             : /// \endcond
     208             : }  // namespace Events
     209             : }  // namespace dg

Generated by: LCOV version 1.14