SpECTRE Documentation Coverage Report
Current view: top level - Domain - FaceNormal.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 29.7 % 37 11
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              : /// Declares function unnormalized_face_normal
       6              : 
       7              : #pragma once
       8              : 
       9              : #include <algorithm>
      10              : #include <cstddef>
      11              : #include <functional>
      12              : #include <string>
      13              : #include <unordered_map>
      14              : 
      15              : #include "DataStructures/DataBox/Tag.hpp"
      16              : #include "DataStructures/Tensor/TypeAliases.hpp"
      17              : #include "Domain/CoordinateMaps/Tags.hpp"
      18              : #include "Domain/FunctionsOfTime/Tags.hpp"
      19              : #include "Domain/InterfaceComputeTags.hpp"
      20              : #include "Domain/Tags.hpp"
      21              : #include "Utilities/Gsl.hpp"
      22              : #include "Utilities/TMPL.hpp"
      23              : 
      24              : /// \cond
      25              : namespace Tags {
      26              : struct Time;
      27              : }  // namespace Tags
      28              : namespace domain {
      29              : template <typename, typename, size_t>
      30              : class CoordinateMapBase;
      31              : }  // namespace domain
      32              : class DataVector;
      33              : template <size_t>
      34              : class Direction;
      35              : template <size_t Dim, typename Frame>
      36              : class ElementMap;
      37              : template <size_t>
      38              : class Mesh;
      39              : /// \endcond
      40              : 
      41              : /// @{
      42              : /*!
      43              :  * \ingroup ComputationalDomainGroup
      44              :  * \brief Compute the outward grid normal on a face of an Element
      45              :  *
      46              :  * \details
      47              :  * Computes the grid-frame normal by taking the logical-frame unit
      48              :  * one-form in the given Direction and mapping it to the grid frame
      49              :  * with the given map, or the given inverse Jacobian.
      50              :  *
      51              :  * \example
      52              :  * \snippet Test_FaceNormal.cpp face_normal_example
      53              :  */
      54              : template <size_t VolumeDim, typename TargetFrame>
      55            1 : void unnormalized_face_normal(
      56              :     const gsl::not_null<tnsr::i<DataVector, VolumeDim, TargetFrame>*> result,
      57              :     const Mesh<VolumeDim - 1>& interface_mesh,
      58              :     const InverseJacobian<DataVector, VolumeDim, Frame::ElementLogical,
      59              :                           TargetFrame>& inv_jacobian_on_interface,
      60              :     const Direction<VolumeDim>& direction);
      61              : 
      62              : template <size_t VolumeDim, typename TargetFrame>
      63            1 : tnsr::i<DataVector, VolumeDim, TargetFrame> unnormalized_face_normal(
      64              :     const Mesh<VolumeDim - 1>& interface_mesh,
      65              :     const InverseJacobian<DataVector, VolumeDim, Frame::ElementLogical,
      66              :                           TargetFrame>& inv_jacobian_on_interface,
      67              :     const Direction<VolumeDim>& direction);
      68              : 
      69              : template <size_t VolumeDim, typename TargetFrame>
      70            1 : void unnormalized_face_normal(
      71              :     gsl::not_null<tnsr::i<DataVector, VolumeDim, TargetFrame>*> result,
      72              :     const Mesh<VolumeDim - 1>& interface_mesh,
      73              :     const ElementMap<VolumeDim, TargetFrame>& map,
      74              :     const Direction<VolumeDim>& direction);
      75              : 
      76              : template <size_t VolumeDim, typename TargetFrame>
      77            1 : tnsr::i<DataVector, VolumeDim, TargetFrame> unnormalized_face_normal(
      78              :     const Mesh<VolumeDim - 1>& interface_mesh,
      79              :     const ElementMap<VolumeDim, TargetFrame>& map,
      80              :     const Direction<VolumeDim>& direction);
      81              : 
      82              : template <size_t VolumeDim, typename TargetFrame>
      83            1 : void unnormalized_face_normal(
      84              :     gsl::not_null<tnsr::i<DataVector, VolumeDim, TargetFrame>*> result,
      85              :     const Mesh<VolumeDim - 1>& interface_mesh,
      86              :     const domain::CoordinateMapBase<Frame::ElementLogical, TargetFrame,
      87              :                                     VolumeDim>& map,
      88              :     const Direction<VolumeDim>& direction);
      89              : 
      90              : template <size_t VolumeDim, typename TargetFrame>
      91            1 : tnsr::i<DataVector, VolumeDim, TargetFrame> unnormalized_face_normal(
      92              :     const Mesh<VolumeDim - 1>& interface_mesh,
      93              :     const domain::CoordinateMapBase<Frame::ElementLogical, TargetFrame,
      94              :                                     VolumeDim>& map,
      95              :     const Direction<VolumeDim>& direction);
      96              : 
      97              : template <size_t VolumeDim>
      98            1 : void unnormalized_face_normal(
      99              :     gsl::not_null<tnsr::i<DataVector, VolumeDim, Frame::Inertial>*> result,
     100              :     const Mesh<VolumeDim - 1>& interface_mesh,
     101              :     const ElementMap<VolumeDim, Frame::Grid>& logical_to_grid_map,
     102              :     const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&
     103              :         grid_to_inertial_map,
     104              :     double time,
     105              :     const std::unordered_map<
     106              :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     107              :         functions_of_time,
     108              :     const Direction<VolumeDim>& direction);
     109              : 
     110              : template <size_t VolumeDim>
     111            1 : tnsr::i<DataVector, VolumeDim, Frame::Inertial> unnormalized_face_normal(
     112              :     const Mesh<VolumeDim - 1>& interface_mesh,
     113              :     const ElementMap<VolumeDim, Frame::Grid>& logical_to_grid_map,
     114              :     const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&
     115              :         grid_to_inertial_map,
     116              :     double time,
     117              :     const std::unordered_map<
     118              :         std::string, std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     119              :         functions_of_time,
     120              :     const Direction<VolumeDim>& direction);
     121              : /// @}
     122              : 
     123              : namespace domain {
     124              : namespace Tags {
     125              : /// \ingroup DataBoxTagsGroup
     126              : /// \ingroup ComputationalDomainGroup
     127              : /// The unnormalized face normal one form
     128              : template <size_t VolumeDim, typename Frame = ::Frame::Inertial>
     129            1 : struct UnnormalizedFaceNormal : db::SimpleTag {
     130            0 :   using type = tnsr::i<DataVector, VolumeDim, Frame>;
     131              : };
     132              : 
     133              : template <size_t VolumeDim, typename Frame = ::Frame::Inertial>
     134            0 : struct UnnormalizedFaceNormalCompute
     135              :     : db::ComputeTag, UnnormalizedFaceNormal<VolumeDim, Frame> {
     136            0 :   using base = UnnormalizedFaceNormal<VolumeDim, Frame>;
     137            0 :   using return_type = typename base::type;
     138            0 :   static constexpr auto function = static_cast<void (*)(
     139              :       gsl::not_null<return_type*>, const ::Mesh<VolumeDim - 1>&,
     140              :       const ::ElementMap<VolumeDim, Frame>&, const ::Direction<VolumeDim>&)>(
     141              :       &unnormalized_face_normal);
     142            0 :   using argument_tags =
     143              :       tmpl::list<Mesh<VolumeDim - 1>, ElementMap<VolumeDim, Frame>,
     144              :                  Direction<VolumeDim>>;
     145            0 :   using volume_tags = tmpl::list<ElementMap<VolumeDim, Frame>>;
     146              : };
     147              : 
     148              : template <size_t VolumeDim>
     149            0 : struct UnnormalizedFaceNormalMovingMeshCompute
     150              :     : db::ComputeTag,
     151              :       UnnormalizedFaceNormal<VolumeDim, Frame::Inertial> {
     152            0 :   using base = UnnormalizedFaceNormal<VolumeDim, Frame::Inertial>;
     153            0 :   using return_type = typename base::type;
     154            0 :   static constexpr auto function = static_cast<void (*)(
     155              :       gsl::not_null<return_type*>, const ::Mesh<VolumeDim - 1>&,
     156              :       const ::ElementMap<VolumeDim, Frame::Grid>&,
     157              :       const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&,
     158              :       double,
     159              :       const std::unordered_map<
     160              :           std::string,
     161              :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&,
     162              :       const ::Direction<VolumeDim>&)>(&unnormalized_face_normal);
     163            0 :   using argument_tags =
     164              :       tmpl::list<Mesh<VolumeDim - 1>, ElementMap<VolumeDim, Frame::Grid>,
     165              :                  CoordinateMaps::Tags::CoordinateMap<VolumeDim, Frame::Grid,
     166              :                                                      Frame::Inertial>,
     167              :                  ::Tags::Time, Tags::FunctionsOfTime, Direction<VolumeDim>>;
     168            0 :   using volume_tags =
     169              :       tmpl::list<ElementMap<VolumeDim, Frame::Grid>,
     170              :                  CoordinateMaps::Tags::CoordinateMap<VolumeDim, Frame::Grid,
     171              :                                                      Frame::Inertial>,
     172              :                  ::Tags::Time, Tags::FunctionsOfTime>;
     173              : };
     174              : 
     175              : /// \ingroup DataBoxTagsGroup
     176              : /// \ingroup ComputationalDomainGroup
     177              : /// Specialisation of UnnormalizedFaceNormal for the external boundaries which
     178              : /// inverts the normals. Since ExternalBoundariesDirections are meant to
     179              : /// represent ghost elements, the normals should correspond to the normals in
     180              : /// said element, which are inverted with respect to the current element.
     181              : template <size_t VolumeDim, typename Frame>
     182            1 : struct InterfaceCompute<Tags::BoundaryDirectionsExterior<VolumeDim>,
     183              :                         UnnormalizedFaceNormalCompute<VolumeDim, Frame>>
     184              :     : db::ComputeTag,
     185              :       Tags::Interface<Tags::BoundaryDirectionsExterior<VolumeDim>,
     186              :                       Tags::UnnormalizedFaceNormal<VolumeDim, Frame>> {
     187            0 :   using base = Tags::Interface<Tags::BoundaryDirectionsExterior<VolumeDim>,
     188              :                                Tags::UnnormalizedFaceNormal<VolumeDim, Frame>>;
     189            0 :   using dirs = BoundaryDirectionsExterior<VolumeDim>;
     190              : 
     191            0 :   static std::string name() {
     192              :     return "BoundaryDirectionsExterior<UnnormalizedFaceNormal>";
     193              :   }
     194            0 :   using return_type = std::unordered_map<::Direction<VolumeDim>,
     195              :                                          tnsr::i<DataVector, VolumeDim, Frame>>;
     196            0 :   static void function(const gsl::not_null<return_type*> normals,
     197              :                        const std::unordered_map<::Direction<VolumeDim>,
     198              :                                                 ::Mesh<VolumeDim - 1>>& meshes,
     199              :                        const ::ElementMap<VolumeDim, Frame>& map) {
     200              :     for (const auto& direction_and_mesh : meshes) {
     201              :       const auto& direction = direction_and_mesh.first;
     202              :       const auto& mesh = direction_and_mesh.second;
     203              :       auto internal_face_normal =
     204              :           unnormalized_face_normal(mesh, map, direction);
     205              :       std::transform(internal_face_normal.begin(), internal_face_normal.end(),
     206              :                      internal_face_normal.begin(), std::negate<>());
     207              :       (*normals)[direction] = std::move(internal_face_normal);
     208              :     }
     209              :   }
     210              : 
     211            0 :   using argument_tags = tmpl::list<Tags::Interface<dirs, Mesh<VolumeDim - 1>>,
     212              :                                    Tags::ElementMap<VolumeDim, Frame>>;
     213              : };
     214              : 
     215              : template <size_t VolumeDim>
     216            0 : struct InterfaceCompute<Tags::BoundaryDirectionsExterior<VolumeDim>,
     217              :                         UnnormalizedFaceNormalMovingMeshCompute<VolumeDim>>
     218              :     : db::ComputeTag,
     219              :       Tags::Interface<
     220              :           Tags::BoundaryDirectionsExterior<VolumeDim>,
     221              :           Tags::UnnormalizedFaceNormal<VolumeDim, Frame::Inertial>> {
     222            0 :   using base =
     223              :       Tags::Interface<Tags::BoundaryDirectionsExterior<VolumeDim>,
     224              :                       Tags::UnnormalizedFaceNormal<VolumeDim, Frame::Inertial>>;
     225            0 :   using dirs = BoundaryDirectionsExterior<VolumeDim>;
     226              : 
     227            0 :   static std::string name() {
     228              :     return "BoundaryDirectionsExterior<UnnormalizedFaceNormal>";
     229              :   }
     230            0 :   using return_type =
     231              :       std::unordered_map<::Direction<VolumeDim>,
     232              :                          tnsr::i<DataVector, VolumeDim, Frame::Inertial>>;
     233            0 :   static void function(
     234              :       const gsl::not_null<return_type*> normals,
     235              :       const std::unordered_map<::Direction<VolumeDim>, ::Mesh<VolumeDim - 1>>&
     236              :           meshes,
     237              :       const ::ElementMap<VolumeDim, Frame::Grid>& logical_to_grid_map,
     238              :       const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, VolumeDim>&
     239              :           grid_to_inertial_map,
     240              :       const double time,
     241              :       const std::unordered_map<
     242              :           std::string,
     243              :           std::unique_ptr<domain::FunctionsOfTime::FunctionOfTime>>&
     244              :           functions_of_time) {
     245              :     for (const auto& direction_and_mesh : meshes) {
     246              :       const auto& direction = direction_and_mesh.first;
     247              :       const auto& mesh = direction_and_mesh.second;
     248              :       auto internal_face_normal = unnormalized_face_normal(
     249              :           mesh, logical_to_grid_map, grid_to_inertial_map, time,
     250              :           functions_of_time, direction);
     251              :       std::transform(internal_face_normal.begin(), internal_face_normal.end(),
     252              :                      internal_face_normal.begin(), std::negate<>());
     253              :       (*normals)[direction] = std::move(internal_face_normal);
     254              :     }
     255              :   }
     256              : 
     257            0 :   using argument_tags =
     258              :       tmpl::list<Tags::Interface<dirs, Mesh<VolumeDim - 1>>,
     259              :                  Tags::ElementMap<VolumeDim, Frame::Grid>,
     260              :                  CoordinateMaps::Tags::CoordinateMap<VolumeDim, Frame::Grid,
     261              :                                                      Frame::Inertial>,
     262              :                  ::Tags::Time, Tags::FunctionsOfTime>;
     263              : };
     264              : 
     265              : }  // namespace Tags
     266              : }  // namespace domain
        

Generated by: LCOV version 2.0-1