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

Generated by: LCOV version 1.14