SpECTRE Documentation Coverage Report
Current view: top level - Domain - Block.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 16 36 44.4 %
Date: 2025-12-05 05:03:31
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 1.14