SpECTRE Documentation Coverage Report
Current view: top level - Domain - Domain.hpp Hit Total Coverage
Commit: 13732b46b6725478a0972e5abbf2d5c85faeaf3b Lines: 5 24 20.8 %
Date: 2024-05-01 20:05:12
Legend: Lines: hit not hit

          Line data    Source code
       1           1 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : /// \file
       5             : /// Defines class template Domain.
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <array>
      10             : #include <cstddef>
      11             : #include <iosfwd>
      12             : #include <memory>
      13             : #include <string>
      14             : #include <unordered_map>
      15             : #include <unordered_set>
      16             : #include <vector>
      17             : 
      18             : #include "Domain/Block.hpp"  // IWYU pragma: keep
      19             : #include "Domain/DomainHelpers.hpp"
      20             : #include "Domain/ExcisionSphere.hpp"
      21             : #include "Domain/Structure/DirectionMap.hpp"
      22             : #include "Utilities/ConstantExpressions.hpp"
      23             : 
      24             : namespace Frame {
      25             : struct BlockLogical;
      26             : }  // namespace Frame
      27             : namespace PUP {
      28             : class er;
      29             : }  // namespace PUP
      30             : /// \cond
      31             : namespace domain {
      32             : template <typename SourceFrame, typename TargetFrame, size_t Dim>
      33             : class CoordinateMapBase;
      34             : }  // namespace domain
      35             : /// \endcond
      36             : 
      37             : /*!
      38             :  * \brief Holds entities related to the computational domain.
      39             :  */
      40             : namespace domain {}
      41             : 
      42             : /*!
      43             :  * \ingroup ComputationalDomainGroup
      44             :  * \brief A wrapper around a vector of Blocks that represent the computational
      45             :  * domain.
      46             :  *
      47             :  * ### Serialization and versioning
      48             :  *
      49             :  * The domain will be serialized and written to output files so it can be used
      50             :  * for interpolations, as are `domain::FunctionOfTime` classes. To be able to
      51             :  * read in domains written by older versions of the code the `pup` function in
      52             :  * this class and all `pup` functions it invokes support lightweight versioning.
      53             :  * A `version` integer is written alongside the data when serializing, and read
      54             :  * back in when deserializing. Increment the version number every time you make
      55             :  * changes to the `pup` function. Retain support for unpacking data written by
      56             :  * previous versions whenever possible. When adding a new field to serialize,
      57             :  * you can simply pack/unpack the new field only for newer versions like this:
      58             :  *
      59             :  * ```cpp
      60             :  * void pup(PUP::er& p) {
      61             :  *   size_t version = 1;  // Incremented from 0 to 1
      62             :  *   p | version;
      63             :  *   if (version >= 0) {
      64             :  *     p | some_data_;
      65             :  *   }
      66             :  *   if (version >= 1) {
      67             :  *     p | added_data_;
      68             :  *   } else if (p.isUnpacking()) {
      69             :  *     // You may have to initialize added_data_ here if default-construction
      70             :  *     // isn't sufficient.
      71             :  *   }
      72             :  * }
      73             :  * ```
      74             :  *
      75             :  * When removing or changing a field, make sure to deserialize old data
      76             :  * consistent with how it was written:
      77             :  *
      78             :  * ```cpp
      79             :  * void pup(PUP::er& p) {
      80             :  *   size_t version = 2;  // Incremented from 1 to 2
      81             :  *   p | version;
      82             :  *   if (version < 2) {
      83             :  *     // The field some_data_ was changed in version 2
      84             :  *     OldDataType old_some_data_;
      85             :  *     p | old_some_data_;
      86             :  *     // Possibly use the old deserialized data to initialize the changed field
      87             :  *     some_data_ = old_some_data_ * 2.;
      88             :  *   } else {
      89             :  *     p | some_data_;
      90             :  *   }
      91             :  *   // ...
      92             :  * }
      93             :  * ```
      94             :  *
      95             :  * Make sure that all data types you serialize in the `pup` function also
      96             :  * support versioning. Also make sure to keep all factory-creatable classes
      97             :  * registered that were written by old versions of the code.
      98             :  */
      99             : template <size_t VolumeDim>
     100           1 : class Domain {
     101             :  public:
     102           0 :   explicit Domain(std::vector<Block<VolumeDim>> blocks);
     103             : 
     104             :   /*!
     105             :    * \brief Create a Domain using CoordinateMaps to encode the Orientations.
     106             :    * This constructor does not support periodic boundary conditions.
     107             :    *
     108             :    * \details A constructor that does not require the user to provide a corner
     109             :    * numbering scheme. Constructs a global corner numbering for each pair
     110             :    * of abutting Blocks from their maps alone. The numbering is used to
     111             :    * set up the corresponding Orientation, and then is discarded; the
     112             :    * next pair of blocks uses a new global corner numbering, and so on,
     113             :    * until all pairs of abutting Blocks have had their Orientations
     114             :    * determined. For more information on setting up domains, see the
     115             :    * [domain creation tutorial](\ref tutorial_domain_creation).
     116             :    *
     117             :    * \param maps The BlockLogical -> Inertial coordinate map for each block.
     118             :    * \param excision_spheres Any ExcisionSphere%s in the domain.
     119             :    * \param block_names A human-readable name for every block, or empty if no
     120             :    * block names have been chosen (yet).
     121             :    * \param block_groups Labels to refer to groups of blocks. The groups can
     122             :    * overlap, and they don't have to cover all blocks in the domain. The groups
     123             :    * can be used to refer to multiple blocks at once.
     124             :    */
     125           1 :   explicit Domain(
     126             :       std::vector<std::unique_ptr<domain::CoordinateMapBase<
     127             :           Frame::BlockLogical, Frame::Inertial, VolumeDim>>>
     128             :           maps,
     129             :       std::unordered_map<std::string, ExcisionSphere<VolumeDim>>
     130             :           excision_spheres = {},
     131             :       std::vector<std::string> block_names = {},
     132             :       std::unordered_map<std::string, std::unordered_set<std::string>>
     133             :           block_groups = {});
     134             : 
     135             :   /*!
     136             :    * \brief Create a Domain using a corner numbering scheme to encode the
     137             :    * Orientations
     138             :    *
     139             :    * \see [domain creation tutorial](@ref tutorial_domain_creation)
     140             :    *
     141             :    * \param maps The BlockLogical -> Inertial coordinate map for each block.
     142             :    * \param corners_of_all_blocks The corner numbering for each block's corners
     143             :    * according to the global corner number scheme. The details of the corner
     144             :    * numbering scheme are described in the
     145             :    * [tutorial](@ref tutorial_orientations).
     146             :    * \param identifications Used to impose periodic boundary conditions on the
     147             :    * domain. To identify faces, `identifications` should contain the PairOfFaces
     148             :    * containing the corners of each pair of faces that you wish to identify with
     149             :    * one another. The number of `identifications` must be even.
     150             :    * \param excision_spheres Any ExcisionSphere%s in the domain.
     151             :    * \param block_names A human-readable name for every block, or empty if no
     152             :    * block names have been chosen (yet).
     153             :    * \param block_groups Labels to refer to groups of blocks. The groups can
     154             :    * overlap, and they don't have to cover all blocks in the domain. The groups
     155             :    * can be used to refer to multiple blocks at once.
     156             :    */
     157           1 :   Domain(std::vector<std::unique_ptr<domain::CoordinateMapBase<
     158             :              Frame::BlockLogical, Frame::Inertial, VolumeDim>>>
     159             :              maps,
     160             :          const std::vector<std::array<size_t, two_to_the(VolumeDim)>>&
     161             :              corners_of_all_blocks,
     162             :          const std::vector<PairOfFaces>& identifications = {},
     163             :          std::unordered_map<std::string, ExcisionSphere<VolumeDim>>
     164             :              excision_spheres = {},
     165             :          std::vector<std::string> block_names = {},
     166             :          std::unordered_map<std::string, std::unordered_set<std::string>>
     167             :              block_groups = {});
     168             : 
     169           0 :   Domain() = default;
     170           0 :   ~Domain() = default;
     171           0 :   Domain(const Domain&) = delete;
     172           0 :   Domain(Domain&&) = default;
     173           0 :   Domain<VolumeDim>& operator=(const Domain<VolumeDim>&) = delete;
     174           0 :   Domain<VolumeDim>& operator=(Domain<VolumeDim>&&) = default;
     175             : 
     176           0 :   void inject_time_dependent_map_for_block(
     177             :       size_t block_id,
     178             :       std::unique_ptr<
     179             :           domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
     180             :           moving_mesh_grid_to_inertial_map,
     181             :       std::unique_ptr<
     182             :           domain::CoordinateMapBase<Frame::Grid, Frame::Distorted, VolumeDim>>
     183             :           moving_mesh_grid_to_distorted_map = nullptr,
     184             :       std::unique_ptr<domain::CoordinateMapBase<Frame::Distorted,
     185             :                                                 Frame::Inertial, VolumeDim>>
     186             :           moving_mesh_distorted_to_inertial_map = nullptr);
     187             : 
     188           0 :   void inject_time_dependent_map_for_excision_sphere(
     189             :       const std::string& excision_sphere_name,
     190             :       std::unique_ptr<
     191             :           domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
     192             :           moving_mesh_grid_to_inertial_map);
     193             : 
     194           0 :   const std::vector<Block<VolumeDim>>& blocks() const { return blocks_; }
     195             : 
     196           0 :   bool is_time_dependent() const;
     197             : 
     198             :   const std::unordered_map<std::string, ExcisionSphere<VolumeDim>>&
     199           0 :   excision_spheres() const {
     200             :     return excision_spheres_;
     201             :   }
     202             : 
     203             :   /// Labels to refer to groups of blocks. The groups can overlap, and they
     204             :   /// don't have to cover all blocks in the domain. The groups can be used to
     205             :   /// refer to multiple blocks at once.
     206             :   const std::unordered_map<std::string, std::unordered_set<std::string>>&
     207           1 :   block_groups() const {
     208             :     return block_groups_;
     209             :   }
     210             : 
     211             :   // NOLINTNEXTLINE(google-runtime-references)
     212           0 :   void pup(PUP::er& p);
     213             : 
     214             :  private:
     215           0 :   std::vector<Block<VolumeDim>> blocks_{};
     216             :   std::unordered_map<std::string, ExcisionSphere<VolumeDim>>
     217           0 :       excision_spheres_{};
     218             :   std::unordered_map<std::string, std::unordered_set<std::string>>
     219           0 :       block_groups_{};
     220             : };
     221             : 
     222             : template <size_t VolumeDim>
     223           0 : bool operator==(const Domain<VolumeDim>& lhs, const Domain<VolumeDim>& rhs);
     224             : 
     225             : template <size_t VolumeDim>
     226           0 : bool operator!=(const Domain<VolumeDim>& lhs, const Domain<VolumeDim>& rhs);
     227             : 
     228             : template <size_t VolumeDim>
     229           0 : std::ostream& operator<<(std::ostream& os, const Domain<VolumeDim>& d);

Generated by: LCOV version 1.14