SpECTRE Documentation Coverage Report
Current view: top level - Domain - FaceNormal.hpp Hit Total Coverage
Commit: 697db44127ce57424c079f629b3283267ec6bd78 Lines: 11 37 29.7 %
Date: 2024-06-21 21:13:41
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"  // IWYU pragma: keep
      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 1.14