SpECTRE Documentation Coverage Report
Current view: top level - IO/Observer - Tags.hpp Hit Total Coverage
Commit: 9a905b0737f373631c1b8e8389b8f26e67fa5313 Lines: 22 62 35.5 %
Date: 2024-03-28 09:03:18
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 <atomic>
       7             : #include <converse.h>
       8             : #include <cstddef>
       9             : #include <memory>
      10             : #include <set>
      11             : #include <string>
      12             : #include <unordered_map>
      13             : #include <unordered_set>
      14             : #include <vector>
      15             : 
      16             : #include "DataStructures/DataBox/Tag.hpp"
      17             : #include "DataStructures/DataVector.hpp"
      18             : #include "IO/H5/TensorData.hpp"
      19             : #include "IO/Observer/ObservationId.hpp"
      20             : #include "Options/String.hpp"
      21             : #include "Parallel/ArrayComponentId.hpp"
      22             : #include "Parallel/NodeLock.hpp"
      23             : #include "Parallel/Reduction.hpp"
      24             : #include "Utilities/PrettyType.hpp"
      25             : 
      26             : namespace observers {
      27             : /// \ingroup ObserversGroup
      28             : /// %Tags used on the observer parallel component
      29           1 : namespace Tags {
      30             : /// \brief The set of `ArrayComponentId`s that will contribute to each
      31             : /// `ObservationId` for reduction.
      32             : ///
      33             : /// This is set during registration is only read from later on in the
      34             : /// simulation, except for possibly during migration of an `ArrayComponentId`
      35             : /// component.
      36           1 : struct ExpectedContributorsForObservations : db::SimpleTag {
      37           0 :   using type =
      38             :       std::unordered_map<ObservationKey,
      39             :                          std::unordered_set<Parallel::ArrayComponentId>>;
      40             : };
      41             : 
      42             : /// \brief The set of `ArrayComponentId` that have contributed to each
      43             : /// `ObservationId` for reductions
      44             : ///
      45             : /// The tag is used both on the `Observer` and on the `ObserverWriter`
      46             : /// components since all we need to do is keep track of array component IDs in
      47             : /// both cases.
      48           1 : struct ContributorsOfReductionData : db::SimpleTag {
      49           0 :   using type =
      50             :       std::unordered_map<ObservationId,
      51             :                          std::unordered_set<Parallel::ArrayComponentId>>;
      52             : };
      53             : 
      54             : /// \brief The set of nodes that have contributed to each `ObservationId` for
      55             : /// writing reduction data
      56             : ///
      57             : /// This is used on node 0 (or whichever node has been designated as the one to
      58             : /// write the reduction files). The `unordered_set` is the node IDs that have
      59             : /// contributed so far.
      60           1 : struct NodesThatContributedReductions : db::SimpleTag {
      61           0 :   using type = std::unordered_map<ObservationId, std::unordered_set<size_t>>;
      62             : };
      63             : 
      64             : /// \brief The set of nodes that are registered with each
      65             : /// `ObservationIdRegistrationKey` for writing reduction data
      66             : ///
      67             : /// The set contains all the nodes that have been registered.
      68             : ///
      69             : /// We need to keep track of this separately from the local reductions on the
      70             : /// node that are contributing so we need a separate tag. Since nodes are easily
      71             : /// indexed by an unsigned integer, we use `size_t` to keep track of them.
      72           1 : struct NodesExpectedToContributeReductions : db::SimpleTag {
      73           0 :   using type = std::unordered_map<ObservationKey, std::set<size_t>>;
      74             : };
      75             : 
      76             : /// \brief Lock used when contributing reduction data.
      77             : ///
      78             : /// A separate lock from the node lock of the nodegroup is used in order to
      79             : /// allow other cores to contribute volume data, write to disk, etc.
      80           1 : struct ReductionDataLock : db::SimpleTag {
      81           0 :   using type = Parallel::NodeLock;
      82             : };
      83             : 
      84             : /// \brief The set of `ArrayComponentId` that have contributed to each
      85             : /// `ObservationId` for volume observation
      86             : ///
      87             : /// The tag is used both on the `Observer` and on the `ObserverWriter`
      88             : /// components since all we need to do is keep track of array component IDs in
      89             : /// both cases.
      90           1 : struct ContributorsOfTensorData : db::SimpleTag {
      91           0 :   using type =
      92             :       std::unordered_map<ObservationId,
      93             :                          std::unordered_set<Parallel::ArrayComponentId>>;
      94             : };
      95             : 
      96             : /// \brief Lock used when contributing volume data.
      97             : ///
      98             : /// A separate lock from the node lock of the nodegroup is used in order to
      99             : /// allow other cores to contribute reduction data, write to disk, etc.
     100           1 : struct VolumeDataLock : db::SimpleTag {
     101           0 :   using type = Parallel::NodeLock;
     102             : };
     103             : 
     104             : /// Volume tensor data to be written to disk.
     105           1 : struct TensorData : db::SimpleTag {
     106           0 :   using type = std::unordered_map<
     107             :       observers::ObservationId,
     108             :       std::unordered_map<Parallel::ArrayComponentId, ElementVolumeData>>;
     109             : };
     110             : 
     111             : /// Volume tensor data to be written to disk from the Interpolator
     112           1 : struct InterpolatorTensorData : db::SimpleTag {
     113           0 :   using type =
     114             :       std::unordered_map<observers::ObservationId,
     115             :                          std::unordered_map<Parallel::ArrayComponentId,
     116             :                                             std::vector<ElementVolumeData>>>;
     117             : };
     118             : 
     119             : /// \cond
     120             : template <class... ReductionDatums>
     121             : struct ReductionDataNames;
     122             : /// \endcond
     123             : 
     124             : /// Reduction data to be written to disk.
     125             : ///
     126             : /// If we have `M` `ArrayComponentIds` registered with a given `Observer`
     127             : /// for a given `ObservationId`, then we expect the `Observer` to receive
     128             : /// `M` contributions with the given `ObservationId`. We combine the reduction
     129             : /// data as we receive it, so we only need one copy for each `ObservationId`.
     130             : template <class... ReductionDatums>
     131           1 : struct ReductionData : db::SimpleTag {
     132           0 :   using type = std::unordered_map<observers::ObservationId,
     133             :                                   Parallel::ReductionData<ReductionDatums...>>;
     134           0 :   using names_tag = ReductionDataNames<ReductionDatums...>;
     135             : };
     136             : 
     137             : /// Names of the reduction data to be written to disk.
     138             : template <class... ReductionDatums>
     139           1 : struct ReductionDataNames : db::SimpleTag {
     140           0 :   using type =
     141             :       std::unordered_map<observers::ObservationId, std::vector<std::string>>;
     142           0 :   using data_tag = ReductionData<ReductionDatums...>;
     143             : };
     144             : 
     145             : /// Node lock used when needing to read/write to H5 files on disk.
     146             : ///
     147             : /// The reason for only having one lock for all files is that we currently don't
     148             : /// require a thread-safe HDF5 installation. In the future we will need to
     149             : /// experiment with different HDF5 configurations.
     150           1 : struct H5FileLock : db::SimpleTag {
     151           0 :   using type = Parallel::NodeLock;
     152             : };
     153             : 
     154             : /*!
     155             :  * \brief A string identifying observations related to the `Tag`.
     156             :  *
     157             :  * For example, the `Tag` could refer to the block in the computational domain
     158             :  * and the `ObservationKey` holds the name of the block, so reduction
     159             :  * observations can be registered per-block. A value of `std::nullopt` means
     160             :  * that the element doesn't participate in observations related to the `Tag`.
     161             :  *
     162             :  * This tag only provides a way to store and share the observation key related
     163             :  * to the `Tag`. How it is used to construct composite observation keys or
     164             :  * subfile paths is up to the code that performs the observations.
     165             :  */
     166             : template <typename Tag>
     167           1 : struct ObservationKey : db::SimpleTag {
     168           0 :   using type = std::optional<std::string>;
     169           0 :   static std::string name() {
     170             :     return "ObservationKey(" + pretty_type::name<Tag>() + ")";
     171             :   }
     172             : };
     173             : 
     174             : }  // namespace Tags
     175             : 
     176             : /// \ingroup ObserversGroup
     177             : /// Option tags related to recording data
     178           1 : namespace OptionTags {
     179             : /// Groups option tags related to recording data, e.g. file names.
     180           1 : struct Group {
     181           0 :   static std::string name() { return "Observers"; }
     182           0 :   static constexpr Options::String help = {"Options for recording data"};
     183             : };
     184             : 
     185             : /// The name of the H5 file on disk to which all volume data is written.
     186           1 : struct VolumeFileName {
     187           0 :   using type = std::string;
     188           0 :   static constexpr Options::String help = {
     189             :       "Name of the volume data file without extension"};
     190           0 :   using group = Group;
     191             : };
     192             : 
     193             : /// The name of the H5 file on disk to which all reduction data is written.
     194           1 : struct ReductionFileName {
     195           0 :   using type = std::string;
     196           0 :   static constexpr Options::String help = {
     197             :       "Name of the reduction data file without extension"};
     198           0 :   using group = Group;
     199             : };
     200             : 
     201             : /// The name of the H5 file on disk to which all surface data is written.
     202           1 : struct SurfaceFileName {
     203           0 :   using type = std::string;
     204           0 :   static constexpr Options::String help = {
     205             :       "Name of the surface data file without extension"};
     206           0 :   using group = Group;
     207             : };
     208             : }  // namespace OptionTags
     209             : 
     210             : namespace Tags {
     211             : /// \brief The name of the HDF5 file on disk into which volume data is
     212             : /// written.
     213             : ///
     214             : /// By volume data we mean any data that is not written once across all nodes.
     215             : /// For example, data on a 2d surface written from a 2d simulation is
     216             : /// considered volume data, while an integral over the entire (or a subset of
     217             : /// the) domain is considered reduction data. Data for a 2d surface in
     218             : /// a 3d simulation, such as a horizon, is considered surface data and
     219             : /// is written to a file specified by SurfaceFileName.
     220           1 : struct VolumeFileName : db::SimpleTag {
     221           0 :   using type = std::string;
     222           0 :   using option_tags = tmpl::list<::observers::OptionTags::VolumeFileName>;
     223             : 
     224           0 :   static constexpr bool pass_metavariables = false;
     225           0 :   static std::string create_from_options(const std::string& volume_file_name) {
     226             :     return volume_file_name;
     227             :   }
     228             : };
     229             : 
     230             : /// \brief The name of the HDF5 file on disk into which reduction data is
     231             : /// written.
     232             : ///
     233             : /// By reduction data we mean any data that is written once across all nodes.
     234             : /// For example, an integral over the entire (or a subset of the) domain
     235             : /// is considered reduction data, while data on a 3d surface written from a 3d
     236             : /// simulation is considered volume data. Data for a 2d surface in
     237             : /// a 3d simulation, such as a horizon, is considered surface data and
     238             : /// is written to a file specified by SurfaceFileName.
     239           1 : struct ReductionFileName : db::SimpleTag {
     240           0 :   using type = std::string;
     241           0 :   using option_tags = tmpl::list<::observers::OptionTags::ReductionFileName>;
     242             : 
     243           0 :   static constexpr bool pass_metavariables = false;
     244           0 :   static std::string create_from_options(
     245             :       const std::string& reduction_file_name) {
     246             :     return reduction_file_name;
     247             :   }
     248             : };
     249             : 
     250             : /// \brief The name of the HDF5 file on disk into which surface data is
     251             : /// written.
     252             : ///
     253             : /// By surface data we mean data for a 2d surface in
     254             : /// a 3d simulation, such as a horizon. Surface data is written once across
     255             : /// all nodes. For example, data on a 2d surface written from a 2d simulation is
     256             : /// considered volume data, while an integral over the entire (or a subset of
     257             : /// the) domain is considered reduction data.
     258           1 : struct SurfaceFileName : db::SimpleTag {
     259           0 :   using type = std::string;
     260           0 :   using option_tags = tmpl::list<::observers::OptionTags::SurfaceFileName>;
     261             : 
     262           0 :   static constexpr bool pass_metavariables = false;
     263           0 :   static std::string create_from_options(const std::string& surface_file_name) {
     264             :     return surface_file_name;
     265             :   }
     266             : };
     267             : }  // namespace Tags
     268             : }  // namespace observers

Generated by: LCOV version 1.14