SpECTRE Documentation Coverage Report
Current view: top level - Evolution/DiscontinuousGalerkin/Actions - NormalCovectorAndMagnitude.hpp Hit Total Coverage
Commit: aabde07399ba7837e5db64eedfd0a21f31f96922 Lines: 0 1 0.0 %
Date: 2024-04-26 02:38:13
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 <memory>
       8             : #include <optional>
       9             : 
      10             : #include "DataStructures/DataBox/Tag.hpp"
      11             : #include "DataStructures/DataVector.hpp"
      12             : #include "DataStructures/Tensor/EagerMath/DotProduct.hpp"
      13             : #include "DataStructures/Tensor/EagerMath/Magnitude.hpp"
      14             : #include "DataStructures/Tensor/Tensor.hpp"
      15             : #include "DataStructures/Variables.hpp"
      16             : #include "Domain/CoordinateMaps/CoordinateMap.hpp"
      17             : #include "Domain/Structure/Direction.hpp"
      18             : #include "Domain/Structure/DirectionMap.hpp"
      19             : #include "Evolution/DiscontinuousGalerkin/Actions/ComputeTimeDerivativeHelpers.hpp"
      20             : #include "Evolution/DiscontinuousGalerkin/NormalVectorTags.hpp"
      21             : #include "Utilities/Gsl.hpp"
      22             : #include "Utilities/TMPL.hpp"
      23             : 
      24             : namespace evolution::dg::Actions::detail {
      25             : struct OneOverNormalVectorMagnitude : db::SimpleTag {
      26             :   using type = Scalar<DataVector>;
      27             : };
      28             : 
      29             : template <size_t Dim>
      30             : struct NormalVector : db::SimpleTag {
      31             :   using type = tnsr::I<DataVector, Dim, Frame::Inertial>;
      32             : };
      33             : 
      34             : /*!
      35             :  * \brief Computes the normal covector, magnitude of the unnormalized normal
      36             :  * covector, and in curved spacetimes the normal vector.
      37             :  *
      38             :  * The `fields_on_face` argument is used as a temporary buffer via the
      39             :  * `OneOverNormalVectorMagnitude` tag and also used to return the normalized
      40             :  * normal vector via the `NormalVector<Dim>` tag. The `fields_on_face` argument
      41             :  * also serves as the input for the inverse spatial metric when the spacetime is
      42             :  * curved. The `fields_on_face` argument must have tags `NormalVector<Dim>` and
      43             :  * `OneOverNormalVectorMagnitude`. If the system specifies
      44             :  * `System::inverse_spatial_metric_tag` then this tag must also be in the
      45             :  * Variables.
      46             :  */
      47             : template <typename System, size_t Dim, typename FieldsOnFaceTags>
      48             : void unit_normal_vector_and_covector_and_magnitude_impl(
      49             :     const gsl::not_null<Scalar<DataVector>*> face_normal_magnitude,
      50             :     const gsl::not_null<tnsr::i<DataVector, Dim, Frame::Inertial>*>
      51             :         unit_normal_covector,
      52             :     const gsl::not_null<Variables<FieldsOnFaceTags>*> fields_on_face,
      53             :     const tnsr::i<DataVector, Dim, Frame::Inertial>&
      54             :         unnormalized_normal_covector) {
      55             :   if constexpr (has_inverse_spatial_metric_tag_v<System>) {
      56             :     using inverse_spatial_metric_tag =
      57             :         typename System::inverse_spatial_metric_tag;
      58             :     auto& normal_vector = get<NormalVector<Dim>>(*fields_on_face);
      59             :     const auto& inverse_spatial_metric =
      60             :         get<inverse_spatial_metric_tag>(*fields_on_face);
      61             :     // Compute unnormalized normal vector
      62             :     for (size_t i = 0; i < Dim; ++i) {
      63             :       normal_vector.get(i) = inverse_spatial_metric.get(i, 0) *
      64             :                              get<0>(unnormalized_normal_covector);
      65             :       for (size_t j = 1; j < Dim; ++j) {
      66             :         normal_vector.get(i) += inverse_spatial_metric.get(i, j) *
      67             :                                 unnormalized_normal_covector.get(j);
      68             :       }
      69             :     }
      70             :     // Perform normalization
      71             :     dot_product(face_normal_magnitude, normal_vector,
      72             :                 unnormalized_normal_covector);
      73             :     get(*face_normal_magnitude) = sqrt(get(*face_normal_magnitude));
      74             :     auto& one_over_normal_vector_magnitude =
      75             :         get<OneOverNormalVectorMagnitude>(*fields_on_face);
      76             :     get(one_over_normal_vector_magnitude) = 1.0 / get(*face_normal_magnitude);
      77             :     for (size_t i = 0; i < Dim; ++i) {
      78             :       unit_normal_covector->get(i) = unnormalized_normal_covector.get(i) *
      79             :                                      get(one_over_normal_vector_magnitude);
      80             :       normal_vector.get(i) *= get(one_over_normal_vector_magnitude);
      81             :     }
      82             :   } else {
      83             :     magnitude(face_normal_magnitude, unnormalized_normal_covector);
      84             :     auto& one_over_normal_vector_magnitude =
      85             :         get<OneOverNormalVectorMagnitude>(*fields_on_face);
      86             :     get(one_over_normal_vector_magnitude) = 1.0 / get(*face_normal_magnitude);
      87             :     for (size_t i = 0; i < Dim; ++i) {
      88             :       unit_normal_covector->get(i) = unnormalized_normal_covector.get(i) *
      89             :                                      get(one_over_normal_vector_magnitude);
      90             :     }
      91             :   }
      92             : }
      93             : 
      94             : /*!
      95             :  * \brief Computes the normal vector, covector, and their magnitude on the face
      96             :  * in the given direction.
      97             :  *
      98             :  * The normal covector and its magnitude are returned using the
      99             :  * `normal_covector_quantities` function argument. The `fields_on_face` argument
     100             :  * is used as a temporary buffer via the `OneOverNormalVectorMagnitude` tag and
     101             :  * also used to return the normalized normal vector via the `NormalVector<Dim>`
     102             :  * tag. The `fields_on_face` argument also serves as the input for the inverse
     103             :  * spatial metric when the spacetime is curved. The `fields_on_face` argument
     104             :  * must have tags `NormalVector<Dim>` and `OneOverNormalVectorMagnitude`. If the
     105             :  * system specifies `System::inverse_spatial_metric_tag` then this tag must also
     106             :  * be in the Variables.
     107             :  */
     108             : template <typename System, size_t Dim, typename FieldsOnFaceTags>
     109             : void unit_normal_vector_and_covector_and_magnitude(
     110             :     const gsl::not_null<
     111             :         DirectionMap<Dim, std::optional<Variables<tmpl::list<
     112             :                               evolution::dg::Tags::MagnitudeOfNormal,
     113             :                               evolution::dg::Tags::NormalCovector<Dim>>>>>*>
     114             :         normal_covector_quantities,
     115             :     const gsl::not_null<Variables<FieldsOnFaceTags>*> fields_on_face,
     116             :     const Direction<Dim>& direction,
     117             :     const std::unordered_map<Direction<Dim>, tnsr::i<DataVector, Dim>>&
     118             :         unnormalized_normal_covectors,
     119             :     const domain::CoordinateMapBase<Frame::Grid, Frame::Inertial, Dim>&
     120             :         moving_mesh_map) {
     121             :   const bool mesh_is_moving = not moving_mesh_map.is_identity();
     122             :   const auto& unnormalized_normal_covector =
     123             :       unnormalized_normal_covectors.at(direction);
     124             : 
     125             :   if (auto& normal_covector_quantity =
     126             :           normal_covector_quantities->at(direction);
     127             :       detail::has_inverse_spatial_metric_tag_v<System> or mesh_is_moving or
     128             :       not normal_covector_quantity.has_value()) {
     129             :     if (not normal_covector_quantity.has_value()) {
     130             :       normal_covector_quantity =
     131             :           Variables<tmpl::list<evolution::dg::Tags::MagnitudeOfNormal,
     132             :                                evolution::dg::Tags::NormalCovector<Dim>>>{
     133             :               fields_on_face->number_of_grid_points()};
     134             :     }
     135             :     detail::unit_normal_vector_and_covector_and_magnitude_impl<System>(
     136             :         make_not_null(&get<evolution::dg::Tags::MagnitudeOfNormal>(
     137             :             *normal_covector_quantity)),
     138             :         make_not_null(&get<evolution::dg::Tags::NormalCovector<Dim>>(
     139             :             *normal_covector_quantity)),
     140             :         fields_on_face, unnormalized_normal_covector);
     141             :   }
     142             : }
     143             : }  // namespace evolution::dg::Actions::detail

Generated by: LCOV version 1.14