SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ObserveVolumeIntegrals.hpp Hit Total Coverage
Commit: b1342d46f40e2d46bbd11d0cef68fd973031a24b Lines: 2 21 9.5 %
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/DataVector.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"
      19             : #include "IO/Observer/ReductionActions.hpp"
      20             : #include "IO/Observer/TypeOfObservation.hpp"
      21             : #include "NumericalAlgorithms/LinearOperators/DefiniteIntegral.hpp"
      22             : #include "Options/Options.hpp"
      23             : #include "Parallel/ArrayIndex.hpp"
      24             : #include "Parallel/CharmPupable.hpp"
      25             : #include "Parallel/GlobalCache.hpp"
      26             : #include "Parallel/Invoke.hpp"
      27             : #include "Parallel/Reduction.hpp"
      28             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      29             : #include "Utilities/ConstantExpressions.hpp"
      30             : #include "Utilities/Functional.hpp"
      31             : #include "Utilities/Registration.hpp"
      32             : #include "Utilities/TMPL.hpp"
      33             : #include "Utilities/TaggedTuple.hpp"
      34             : 
      35             : /// \cond
      36             : namespace Frame {
      37             : struct Inertial;
      38             : }  // namespace Frame
      39             : /// \endcond
      40             : 
      41             : namespace dg {
      42             : namespace Events {
      43             : template <size_t VolumeDim, typename ObservationValueTag, typename Tensors,
      44             :           typename EventRegistrars>
      45           0 : class ObserveVolumeIntegrals;
      46             : 
      47             : namespace Registrars {
      48             : template <size_t VolumeDim, typename ObservationValueTag, typename Tensors>
      49             : // Presence of size_t template argument requires to define this struct
      50             : // instead of using Registration::Registrar alias.
      51           0 : struct ObserveVolumeIntegrals {
      52             :   template <typename RegistrarList>
      53           0 :   using f = Events::ObserveVolumeIntegrals<VolumeDim, ObservationValueTag,
      54             :                                            Tensors, RegistrarList>;
      55             : };
      56             : }  // namespace Registrars
      57             : 
      58             : template <size_t VolumeDim, typename ObservationValueTag, typename Tensors,
      59             :           typename EventRegistrars =
      60             :               tmpl::list<Registrars::ObserveVolumeIntegrals<
      61             :                   VolumeDim, ObservationValueTag, Tensors>>>
      62             : class ObserveVolumeIntegrals;
      63             : 
      64             : /*!
      65             :  * \ingroup DiscontinuousGalerkinGroup
      66             :  * \brief %Observe the volume integrals of the tensors over the domain.
      67             :  *
      68             :  * Writes reduction quantities:
      69             :  * - `ObservationValueTag`
      70             :  * - `Volume` = volume of the domain
      71             :  * - `VolumeIntegral(*)` = volume integral of the tensor
      72             :  */
      73             : template <size_t VolumeDim, typename ObservationValueTag, typename... Tensors,
      74             :           typename EventRegistrars>
      75             : class ObserveVolumeIntegrals<VolumeDim, ObservationValueTag,
      76             :                              tmpl::list<Tensors...>, EventRegistrars>
      77           1 :     : public Event<EventRegistrars> {
      78             :  private:
      79           0 :   using VolumeIntegralDatum =
      80             :       Parallel::ReductionDatum<std::vector<double>, funcl::VectorPlus>;
      81             : 
      82           0 :   using ReductionData = tmpl::wrap<
      83             :       tmpl::list<Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      84             :                  Parallel::ReductionDatum<double, funcl::Plus<>>,
      85             :                  VolumeIntegralDatum>,
      86             :       Parallel::ReductionData>;
      87             : 
      88             :  public:
      89             :   /// The name of the subfile inside the HDF5 file
      90           1 :   struct SubfileName {
      91           0 :     using type = std::string;
      92           0 :     static constexpr Options::String help = {
      93             :         "The name of the subfile inside the HDF5 file without an extension and "
      94             :         "without a preceding '/'."};
      95             :   };
      96             : 
      97             :   /// \cond
      98             :   explicit ObserveVolumeIntegrals(CkMigrateMessage* /*unused*/) noexcept {}
      99             :   using PUP::able::register_constructor;
     100             :   WRAPPED_PUPable_decl_template(ObserveVolumeIntegrals);  // NOLINT
     101             :   /// \endcond
     102             : 
     103           0 :   using options = tmpl::list<SubfileName>;
     104           0 :   static constexpr Options::String help =
     105             :       "Observe the volume integrals of the tensors over the domain.\n"
     106             :       "\n"
     107             :       "Writes reduction quantities:\n"
     108             :       " * ObservationValueTag\n"
     109             :       " * Volume = volume of the domain\n"
     110             :       " * VolumeIntegral(*) = volume integral of the tensor\n"
     111             :       "\n"
     112             :       "Warning: Currently, only one reduction observation event can be\n"
     113             :       "triggered at a given observation value.  Causing multiple events to\n"
     114             :       "run at once will produce unpredictable results.";
     115             : 
     116           0 :   ObserveVolumeIntegrals() = default;
     117           0 :   explicit ObserveVolumeIntegrals(const std::string& subfile_name) noexcept;
     118             : 
     119           0 :   using observed_reduction_data_tags =
     120             :       observers::make_reduction_data_tags<tmpl::list<ReductionData>>;
     121             : 
     122           0 :   using argument_tags =
     123             :       tmpl::list<ObservationValueTag, domain::Tags::Mesh<VolumeDim>,
     124             :                  domain::Tags::DetInvJacobian<Frame::Logical, Frame::Inertial>,
     125             :                  Tensors...>;
     126             : 
     127             :   template <typename Metavariables, typename ArrayIndex,
     128             :             typename ParallelComponent>
     129           0 :   void operator()(const typename ObservationValueTag::type& observation_value,
     130             :                   const Mesh<VolumeDim>& mesh,
     131             :                   const Scalar<DataVector>& det_inv_jacobian,
     132             :                   const typename Tensors::type&... tensors,
     133             :                   Parallel::GlobalCache<Metavariables>& cache,
     134             :                   const ArrayIndex& array_index,
     135             :                   const ParallelComponent* const /*meta*/) const noexcept {
     136             :     // Determinant of Jacobian is needed because integral is performed in
     137             :     // logical coords.
     138             :     const DataVector det_jacobian = 1.0 / get(det_inv_jacobian);
     139             :     const double local_volume = definite_integral(det_jacobian, mesh);
     140             : 
     141             :     std::vector<double> local_volume_integrals{};
     142             :     std::vector<std::string> reduction_names = {
     143             :         db::tag_name<ObservationValueTag>(), "Volume"};
     144             :     const auto record_integrals =
     145             :         [&local_volume_integrals, &reduction_names, &det_jacobian, &mesh ](
     146             :             const auto tensor_tag_v, const auto& tensor) noexcept {
     147             :       using tensor_tag = tmpl::type_from<decltype(tensor_tag_v)>;
     148             :       for (size_t i = 0; i < tensor.size(); ++i) {
     149             :         reduction_names.push_back("VolumeIntegral(" +
     150             :                                   db::tag_name<tensor_tag>() +
     151             :                                   tensor.component_suffix(i) + ")");
     152             :         local_volume_integrals.push_back(
     153             :             definite_integral(det_jacobian * tensor[i], mesh));
     154             :       }
     155             :       return 0;
     156             :     };
     157             :     EXPAND_PACK_LEFT_TO_RIGHT(
     158             :         record_integrals(tmpl::type_<Tensors>{}, tensors));
     159             : 
     160             :     // Send data to reduction observer
     161             :     auto& local_observer =
     162             :         *Parallel::get_parallel_component<observers::Observer<Metavariables>>(
     163             :              cache)
     164             :              .ckLocalBranch();
     165             :     Parallel::simple_action<observers::Actions::ContributeReductionData>(
     166             :         local_observer,
     167             :         observers::ObservationId(observation_value, subfile_path_ + ".dat"),
     168             :         observers::ArrayComponentId{
     169             :             std::add_pointer_t<ParallelComponent>{nullptr},
     170             :             Parallel::ArrayIndex<ArrayIndex>(array_index)},
     171             :         subfile_path_, reduction_names,
     172             :         ReductionData{static_cast<double>(observation_value), local_volume,
     173             :                       local_volume_integrals});
     174             :   }
     175             : 
     176           0 :   using observation_registration_tags = tmpl::list<>;
     177             :   std::pair<observers::TypeOfObservation, observers::ObservationKey>
     178           0 :   get_observation_type_and_key_for_registration() const noexcept {
     179             :     return {observers::TypeOfObservation::Reduction,
     180             :             observers::ObservationKey(subfile_path_ + ".dat")};
     181             :   }
     182             : 
     183             :   // NOLINTNEXTLINE(google-runtime-references)
     184           0 :   void pup(PUP::er& p) override {
     185             :     Event<EventRegistrars>::pup(p);
     186             :     p | subfile_path_;
     187             :   }
     188             : 
     189             :  private:
     190           0 :   std::string subfile_path_;
     191             : };
     192             : 
     193             : template <size_t VolumeDim, typename ObservationValueTag, typename... Tensors,
     194             :           typename EventRegistrars>
     195             : ObserveVolumeIntegrals<VolumeDim, ObservationValueTag, tmpl::list<Tensors...>,
     196             :                        EventRegistrars>::
     197             :     ObserveVolumeIntegrals(const std::string& subfile_name) noexcept
     198             :     : subfile_path_("/" + subfile_name) {}
     199             : 
     200             : /// \cond
     201             : template <size_t VolumeDim, typename ObservationValueTag, typename... Tensors,
     202             :           typename EventRegistrars>
     203             : PUP::able::PUP_ID ObserveVolumeIntegrals<VolumeDim, ObservationValueTag,
     204             :                                          tmpl::list<Tensors...>,
     205             :                                          EventRegistrars>::my_PUP_ID =
     206             :     0;  // NOLINT
     207             : /// \endcond
     208             : }  // namespace Events
     209             : }  // namespace dg

Generated by: LCOV version 1.14