SpECTRE Documentation Coverage Report
Current view: top level - Domain - Block.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 44.4 % 36 16
Test Date: 2026-10-22 17:29:42
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 Block.
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <array>
      10              : #include <cstddef>
      11              : #include <iosfwd>
      12              : #include <memory>
      13              : #include <string>
      14              : #include <unordered_set>
      15              : 
      16              : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
      17              : #include "Domain/Structure/BlockNeighbors.hpp"
      18              : #include "Domain/Structure/Direction.hpp"
      19              : #include "Domain/Structure/DirectionMap.hpp"
      20              : #include "Domain/Structure/Topology.hpp"
      21              : #include "Utilities/MakeArray.hpp"
      22              : 
      23              : /// \cond
      24              : namespace Frame {
      25              : struct BlockLogical;
      26              : struct Inertial;
      27              : }  // namespace Frame
      28              : namespace PUP {
      29              : class er;
      30              : }  // namespace PUP
      31              : /// \endcond
      32              : 
      33              : /// \ingroup ComputationalDomainGroup
      34              : /// A Block<VolumeDim> is a region of a VolumeDim-dimensional computational
      35              : /// domain that defines the root node of a tree which is used to construct the
      36              : /// Elements that cover a region of the computational domain.
      37              : ///
      38              : /// Each codimension 1 boundary of a Block<VolumeDim> is either an external
      39              : /// boundary or identical to a boundary of one or more Blocks.
      40              : ///
      41              : /// A Block has logical coordinates that depend upon the topology in each
      42              : /// dimension.  The global coordinates are obtained from the logical
      43              : /// coordinates from the Coordinatemap:  CoordinateMap::operator() takes
      44              : /// Points in the BlockLogical Frame (i.e., block logical coordinates) and
      45              : /// returns Points in the Inertial Frame (i.e., the global coordinate frame in
      46              : /// which the problem to be solved is set up).
      47              : template <size_t VolumeDim>
      48            1 : class Block {
      49              :  public:
      50              :   /// \param stationary_map the CoordinateMap.
      51              :   /// \param id a unique ID.
      52              :   /// \param neighbors info about the Blocks that share a codimension 1
      53              :   /// boundary with this Block.
      54              :   /// \param name Human-readable name for the block
      55              :   /// \param topologies domain::Topology in each dimension (default value is
      56              :   /// domain::Topology::I1)
      57            1 :   Block(std::unique_ptr<domain::CoordinateMapBase<
      58              :             Frame::BlockLogical, Frame::Inertial, VolumeDim>>&& stationary_map,
      59              :         size_t id, DirectionMap<VolumeDim, BlockNeighbors<VolumeDim>> neighbors,
      60              :         std::string name = "",
      61              :         std::array<domain::Topology, VolumeDim> topologies =
      62              :             domain::topologies::hypercube<VolumeDim>);
      63              : 
      64            0 :   Block() = default;
      65            0 :   ~Block() = default;
      66            0 :   Block(const Block&) = delete;
      67            0 :   Block(Block&&) = default;
      68            0 :   Block& operator=(const Block&) = delete;
      69            0 :   Block& operator=(Block&&) = default;
      70              : 
      71              :   /// \brief The map used when the coordinate map is time-independent.
      72              :   ///
      73              :   /// \see is_time_dependent()
      74              :   const domain::CoordinateMapBase<Frame::BlockLogical, Frame::Inertial,
      75              :                                   VolumeDim>&
      76            1 :   stationary_map() const;
      77              : 
      78              :   /// \brief The map going from the block logical frame to the last time
      79              :   /// independent frame. Only used when the coordinate map is time-dependent.
      80              :   ///
      81              :   /// \see is_time_dependent() moving_mesh_grid_to_inertial_map()
      82              :   const domain::CoordinateMapBase<Frame::BlockLogical, Frame::Grid, VolumeDim>&
      83            1 :   moving_mesh_logical_to_grid_map() const;
      84              : 
      85              :   /// \brief The map going from the last time independent frame to the frame in
      86              :   /// which the equations are solved. Only used when the coordinate map is
      87              :   /// time-dependent.
      88              :   ///
      89              :   /// \see is_time_dependent() moving_mesh_logical_to_grid_map()
      90              :   const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&
      91            1 :   moving_mesh_grid_to_inertial_map() const;
      92              : 
      93              :   /// \brief The map going from the last time independent frame to the
      94              :   /// distorted frame. Only used when the coordinate map is
      95              :   /// time-dependent. See \ref domain_concepts to see how the distorted
      96              :   /// frame is defined.
      97              :   ///
      98              :   /// \see is_time_dependent() moving_mesh_distorted_to_grid_map()
      99              :   const domain::CoordinateMapBase<Frame::Grid, Frame::Distorted, VolumeDim>&
     100            1 :   moving_mesh_grid_to_distorted_map() const;
     101              : 
     102              :   /// \brief The map going from the distorted frame to the frame in
     103              :   /// which the equations are solved. Only used when the coordinate map is
     104              :   /// time-dependent. See \ref domain_concepts to see how the distorted
     105              :   /// frame is defined.
     106              :   ///
     107              :   /// \see is_time_dependent() moving_mesh_grid_to_distorted_map()
     108              :   const domain::CoordinateMapBase<Frame::Distorted, Frame::Inertial, VolumeDim>&
     109            1 :   moving_mesh_distorted_to_inertial_map() const;
     110              : 
     111              :   /// \brief Returns `true` if the block has time-dependent maps.
     112            1 :   bool is_time_dependent() const { return stationary_map_ == nullptr; }
     113              : 
     114              :   /// \brief Returns `true` if the block has a distorted frame.
     115              :   ///
     116              :   /// If a block has a distorted frame, then
     117              :   ///   - moving_mesh_grid_to_distorted_map() is non-null
     118              :   ///   - moving_mesh_distorted_to_inertial_map() is non-null
     119              :   ///   - moving_mesh_grid_to_inertial_map() is non-null
     120              :   /// Note in particular the last point above:  If the block is time-dependent,
     121              :   /// then the block must have a grid_to_inertial map independent of whether
     122              :   /// it has a distorted frame.  This allows us to write more efficient maps.
     123              :   /// In particular, we often care only about the grid_to_inertial map, so we
     124              :   /// can code that map directly instead of composing
     125              :   /// grid_to_distorted + distorted_to_inertial maps at runtime.
     126              :   ///
     127              :   /// If a block does not have a distorted frame, then
     128              :   ///   - moving_mesh_grid_to_distorted_map() is null
     129              :   ///   - moving_mesh_distorted_to_inertial_map() is null
     130              :   ///   - moving_mesh_grid_to_inertial_map() is non-null
     131              :   ///   - If we ever find ourselves needing ::Frame::Distorted coordinates
     132              :   ///     in that block, we can assume that ::Frame::Distorted and ::Frame::Grid
     133              :   ///     are the same.  Usually this case will not occur.
     134            1 :   bool has_distorted_frame() const {
     135              :     return moving_mesh_grid_to_distorted_map_ != nullptr and
     136              :            moving_mesh_distorted_to_inertial_map_ != nullptr;
     137              :   }
     138              : 
     139              :   /// \brief Given a Block that has a time-independent map, injects the
     140              :   /// time-dependent map into the Block.
     141            1 :   void inject_time_dependent_map(
     142              :       std::unique_ptr<
     143              :           domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
     144              :           moving_mesh_grid_to_inertial_map,
     145              :       std::unique_ptr<
     146              :           domain::CoordinateMapBase<Frame::Grid, Frame::Distorted, VolumeDim>>
     147              :           moving_mesh_grid_to_distorted_map = nullptr,
     148              :       std::unique_ptr<domain::CoordinateMapBase<Frame::Distorted,
     149              :                                                 Frame::Inertial, VolumeDim>>
     150              :           moving_mesh_distorted_to_inertial_map = nullptr);
     151              : 
     152              :   /// A unique identifier for the Block that is in the range
     153              :   /// [0, number_of_blocks -1] where number_of_blocks is the number
     154              :   /// of Blocks that cover the computational domain.
     155            1 :   size_t id() const { return id_; }
     156              : 
     157              :   /// Information about the neighboring Blocks.
     158            1 :   const DirectionMap<VolumeDim, BlockNeighbors<VolumeDim>>& neighbors() const {
     159              :     return neighbors_;
     160              :   }
     161              : 
     162              :   /// The directions of the faces of the Block that are external boundaries.
     163            1 :   const std::unordered_set<Direction<VolumeDim>>& external_boundaries() const {
     164              :     return external_boundaries_;
     165              :   }
     166              : 
     167            0 :   const std::string& name() const { return name_; }
     168              : 
     169              :   /// The topology in each dimensio of this Block
     170            1 :   const std::array<domain::Topology, VolumeDim>& topologies() const {
     171              :     return topologies_;
     172              :   }
     173              : 
     174              :   /// Serialization for Charm++
     175              :   // NOLINTNEXTLINE(google-runtime-references)
     176            1 :   void pup(PUP::er& p);
     177              : 
     178              :  private:
     179              :   template <size_t LocalVolumeDim>
     180              :   // NOLINTNEXTLINE(readability-redundant-declaration)
     181            0 :   friend bool operator==(const Block<LocalVolumeDim>& lhs,
     182              :                          const Block<LocalVolumeDim>& rhs);
     183              : 
     184              :   std::unique_ptr<domain::CoordinateMapBase<Frame::BlockLogical,
     185              :                                             Frame::Inertial, VolumeDim>>
     186            0 :       stationary_map_{nullptr};
     187              :   std::unique_ptr<
     188              :       domain::CoordinateMapBase<Frame::BlockLogical, Frame::Grid, VolumeDim>>
     189            0 :       moving_mesh_logical_to_grid_map_{nullptr};
     190              :   std::unique_ptr<
     191              :       domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>>
     192            0 :       moving_mesh_grid_to_inertial_map_{nullptr};
     193              :   std::unique_ptr<
     194              :       domain::CoordinateMapBase<Frame::Grid, Frame::Distorted, VolumeDim>>
     195            0 :       moving_mesh_grid_to_distorted_map_{nullptr};
     196              :   std::unique_ptr<
     197              :       domain::CoordinateMapBase<Frame::Distorted, Frame::Inertial, VolumeDim>>
     198            0 :       moving_mesh_distorted_to_inertial_map_{nullptr};
     199              : 
     200            0 :   size_t id_{0};
     201            0 :   DirectionMap<VolumeDim, BlockNeighbors<VolumeDim>> neighbors_;
     202            0 :   std::unordered_set<Direction<VolumeDim>> external_boundaries_;
     203            0 :   std::string name_;
     204            0 :   std::array<domain::Topology, VolumeDim> topologies_;
     205              : };
     206              : 
     207              : template <size_t VolumeDim>
     208            0 : std::ostream& operator<<(std::ostream& os, const Block<VolumeDim>& block);
     209              : 
     210              : template <size_t VolumeDim>
     211            0 : bool operator!=(const Block<VolumeDim>& lhs, const Block<VolumeDim>& rhs);
        

Generated by: LCOV version 2.0-1