SpECTRE Documentation Coverage Report
Current view: top level - Domain/Tags - Faces.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 3 8 37.5 %
Date: 2025-12-05 05:03:31
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 <type_traits>
       8             : 
       9             : #include "DataStructures/DataBox/PrefixHelpers.hpp"
      10             : #include "DataStructures/DataBox/SubitemTag.hpp"
      11             : #include "DataStructures/DataBox/Tag.hpp"
      12             : #include "DataStructures/Variables.hpp"
      13             : #include "Domain/Structure/DirectionMap.hpp"
      14             : #include "Utilities/Gsl.hpp"
      15             : #include "Utilities/Requires.hpp"
      16             : #include "Utilities/TMPL.hpp"
      17             : 
      18             : namespace domain {
      19             : namespace Tags {
      20             : 
      21             : /// The `Tag` on element faces
      22             : template <size_t Dim, typename Tag>
      23           1 : struct Faces : db::PrefixTag, db::SimpleTag {
      24           0 :   static constexpr size_t volume_dim = Dim;
      25           0 :   using tag = Tag;
      26           0 :   using type = DirectionMap<Dim, typename Tag::type>;
      27             : };
      28             : 
      29             : }  // namespace Tags
      30             : 
      31             : /// Wrap `Tag` in `domain::Tags::Faces`, unless `Tag` is in the `VolumeTags`
      32             : /// list
      33             : template <typename Dim, typename Tag, typename VolumeTags = tmpl::list<>>
      34           1 : struct make_faces_tag {
      35           0 :   using type = tmpl::conditional_t<tmpl::list_contains_v<VolumeTags, Tag>, Tag,
      36             :                                    domain::Tags::Faces<Dim::value, Tag>>;
      37             : };
      38             : 
      39             : /// Wrap all tags in `TagsList` in `domain::Tags::Faces`, except those in the
      40             : /// `VolumeTags` list
      41             : template <size_t Dim, typename TagsList, typename VolumeTags = tmpl::list<>>
      42           1 : using make_faces_tags =
      43             :     tmpl::transform<TagsList, make_faces_tag<tmpl::pin<tmpl::size_t<Dim>>,
      44             :                                              tmpl::_1, tmpl::pin<VolumeTags>>>;
      45             : 
      46             : }  // namespace domain
      47             : 
      48             : namespace db {
      49             : template <typename FacesTag>
      50             : struct Subitems<
      51             :     FacesTag,
      52             :     Requires<std::is_base_of_v<domain::Tags::Faces<FacesTag::volume_dim,
      53             :                                                    typename FacesTag::tag>,
      54             :                                FacesTag> and
      55             :              tt::is_a_v<Variables, typename FacesTag::tag::type>>> {
      56             :   static constexpr size_t Dim = FacesTag::volume_dim;
      57             :   using VariablesTag = typename FacesTag::tag;
      58             :   using VectorType = typename VariablesTag::type::vector_type;
      59             : 
      60             :   template <typename LocalTag>
      61             :   using faces_tag = domain::Tags::Faces<Dim, LocalTag>;
      62             : 
      63             :   using tag = faces_tag<VariablesTag>;
      64             :   using type =
      65             :       db::wrap_tags_in<faces_tag, typename VariablesTag::type::tags_list>;
      66             : 
      67             :   template <typename Subtag>
      68             :   static void create_item(
      69             :       const gsl::not_null<typename tag::type*> parent_value,
      70             :       const gsl::not_null<typename Subtag::type*> sub_value) {
      71             :     sub_value->clear();
      72             :     for (auto& [direction, all_parent_vars] : *parent_value) {
      73             :       auto& parent_var = get<typename Subtag::tag>(all_parent_vars);
      74             :       auto& sub_var = (*sub_value)[direction];
      75             :       for (auto vars_it = parent_var.begin(), sub_var_it = sub_var.begin();
      76             :            vars_it != parent_var.end(); ++vars_it, ++sub_var_it) {
      77             :         sub_var_it->set_data_ref(&*vars_it);
      78             :       }
      79             :     }
      80             :   }
      81             : 
      82             :   // The `return_type` can be anything for Subitems because the DataBox figures
      83             :   // out the correct return type, we just use the `return_type` type alias to
      84             :   // signal to the DataBox we want mutating behavior.
      85             :   using return_type = NoSuchType;
      86             : 
      87             :   template <typename Subtag>
      88             :   static void create_compute_item(
      89             :       const gsl::not_null<typename Subtag::type*> sub_value,
      90             :       const typename tag::type& parent_value) {
      91             :     for (const auto& [direction, all_parent_vars] : parent_value) {
      92             :       const auto& parent_var = get<typename Subtag::tag>(all_parent_vars);
      93             :       auto& sub_var = (*sub_value)[direction];
      94             :       auto sub_var_it = sub_var.begin();
      95             :       for (auto vars_it = parent_var.begin(); vars_it != parent_var.end();
      96             :            ++vars_it, ++sub_var_it) {
      97             :         // clang-tidy: do not use const_cast
      98             :         // The DataBox will only give out a const reference to the
      99             :         // result of a compute item.  Here, that is a reference to a
     100             :         // const map to Tensors of DataVectors.  There is no (publicly
     101             :         // visible) indirection there, so having the map const will
     102             :         // allow only allow const access to the contained DataVectors,
     103             :         // so no modification through the pointer cast here is
     104             :         // possible.
     105             :         sub_var_it->set_data_ref(const_cast<VectorType*>(&*vars_it));  // NOLINT
     106             :       }
     107             :     }
     108             :   }
     109             : };
     110             : }  // namespace db
     111             : 
     112             : namespace Tags {
     113             : /// \brief Specialization of a subitem tag for a compute tag that inherits off
     114             : /// `domain::Tags::Faces`.
     115             : ///
     116             : /// This tag holds a map from faces to _one_ of the subitems, typically one
     117             : /// tensor in a Variables. The `FacesSubitemTag` represents the particular
     118             : /// tensor on faces, and the `FacesComputeTag` represents the full Variables on
     119             : /// faces.
     120             : template <typename FacesSubitemTag, typename FacesComputeTag>
     121             : struct Subitem<FacesSubitemTag, FacesComputeTag,
     122             :                Requires<std::is_base_of_v<
     123             :                    domain::Tags::Faces<FacesComputeTag::volume_dim,
     124             :                                        typename FacesComputeTag::tag>,
     125             :                    FacesComputeTag>>> : db::ComputeTag,
     126             :                                         FacesSubitemTag {
     127             :   using base = FacesSubitemTag;
     128             :   using return_type = typename base::type;
     129             :   using parent_tag = FacesComputeTag;
     130             :   using argument_tags = tmpl::list<typename parent_tag::base>;
     131             :   static void function(const gsl::not_null<return_type*> subitems,
     132             :                        const typename parent_tag::type& parent_value) {
     133             :     ::db::Subitems<parent_tag>::template create_compute_item<base>(
     134             :         subitems, parent_value);
     135             :   }
     136             : };
     137             : }  // namespace Tags

Generated by: LCOV version 1.14