SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearOperators - Divergence.hpp Hit Total Coverage
Commit: 3c072f0ce967e2e56649d3fa12aa2a0e4fe2a42e Lines: 8 20 40.0 %
Date: 2024-04-23 20:50:18
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             : /// Defines functions and tags for taking a divergence.
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <cstddef>
      10             : #include <string>
      11             : 
      12             : #include "DataStructures/DataBox/PrefixHelpers.hpp"
      13             : #include "DataStructures/DataBox/Tag.hpp"
      14             : #include "DataStructures/DataBox/TagName.hpp"
      15             : #include "DataStructures/Tensor/Tensor.hpp"
      16             : #include "Utilities/Requires.hpp"
      17             : #include "Utilities/TMPL.hpp"
      18             : #include "Utilities/TypeTraits.hpp"  // IWYU pragma: keep
      19             : #include "Utilities/TypeTraits/IsA.hpp"
      20             : 
      21             : /// \cond
      22             : class DataVector;
      23             : template <size_t Dim>
      24             : class Mesh;
      25             : template <typename TagsList>
      26             : class Variables;
      27             : 
      28             : namespace domain {
      29             : namespace Tags {
      30             : template <size_t Dim>
      31             : struct Mesh;
      32             : }  // namespace Tags
      33             : }  // namespace domain
      34             : /// \endcond
      35             : 
      36             : namespace Tags {
      37             : /// \ingroup DataBoxTagsGroup
      38             : /// \brief Prefix indicating the divergence
      39             : ///
      40             : /// Prefix indicating the divergence of a Tensor.
      41             : ///
      42             : /// \see Tags::DivVectorCompute Tags::DivVariablesCompute
      43             : template <typename Tag, typename = std::nullptr_t>
      44           1 : struct div;
      45             : 
      46             : /// \cond
      47             : template <typename Tag>
      48             : struct div<Tag, Requires<tt::is_a_v<Tensor, typename Tag::type>>>
      49             :     : db::PrefixTag, db::SimpleTag {
      50             :   using tag = Tag;
      51             :   using type = TensorMetafunctions::remove_first_index<typename Tag::type>;
      52             : };
      53             : /// \endcond
      54             : }  // namespace Tags
      55             : 
      56             : /// @{
      57             : /// \ingroup NumericalAlgorithmsGroup
      58             : /// \brief Compute the (Euclidean) divergence of fluxes
      59             : template <typename FluxTags, size_t Dim, typename DerivativeFrame>
      60           1 : auto divergence(
      61             :     const Variables<FluxTags>& F, const Mesh<Dim>& mesh,
      62             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
      63             :                           DerivativeFrame>& inverse_jacobian)
      64             :     -> Variables<db::wrap_tags_in<Tags::div, FluxTags>>;
      65             : 
      66             : template <typename... DivTags, typename... FluxTags, size_t Dim,
      67             :           typename DerivativeFrame>
      68           1 : void divergence(
      69             :     gsl::not_null<Variables<tmpl::list<DivTags...>>*> divergence_of_F,
      70             :     const Variables<tmpl::list<FluxTags...>>& F, const Mesh<Dim>& mesh,
      71             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
      72             :                           DerivativeFrame>& inverse_jacobian);
      73             : /// @}
      74             : 
      75             : /// @{
      76             : /// \ingroup NumericalAlgorithmsGroup
      77             : /// \brief Compute the divergence of the vector `input`
      78             : template <size_t Dim, typename DerivativeFrame>
      79           1 : Scalar<DataVector> divergence(
      80             :     const tnsr::I<DataVector, Dim, DerivativeFrame>& input,
      81             :     const Mesh<Dim>& mesh,
      82             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
      83             :                           DerivativeFrame>& inverse_jacobian);
      84             : 
      85             : template <size_t Dim, typename DerivativeFrame>
      86           1 : void divergence(
      87             :     gsl::not_null<Scalar<DataVector>*> div_input,
      88             :     const tnsr::I<DataVector, Dim, DerivativeFrame>& input,
      89             :     const Mesh<Dim>& mesh,
      90             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
      91             :                           DerivativeFrame>& inverse_jacobian);
      92             : /// @}
      93             : 
      94             : namespace Tags {
      95             : /*!
      96             :  * \ingroup DataBoxTagsGroup
      97             :  * \brief Compute the divergence of a Variables
      98             :  *
      99             :  * Computes the divergence of the every Tensor in the Variables represented by
     100             :  * `Tag`. The first index of each Tensor must be an upper spatial index, i.e.,
     101             :  * the first index must have type
     102             :  * `TensorIndexType<Dim, UpLo::Up, Frame::TargetFrame, IndexType::Spatial>`.
     103             :  * The divergence is computed in the frame `TargetFrame`, and
     104             :  * `InverseJacobianTag` must be associated with a map from
     105             :  * `Frame::ElementLogical` to `Frame::TargetFrame`.
     106             :  *
     107             :  * Note that each tensor may have additional tensor indices - in this case the
     108             :  * divergence is computed for each additional index. For instance, a tensor
     109             :  * \f$F^i_{ab}\f$ has divergence
     110             :  * \f$Div_{ab} = \partial_i F^i_{ab}\f$. This is to accommodate evolution
     111             :  * equations where the evolved variables \f$u_\alpha\f$ are higher-rank tensors
     112             :  * and thus their fluxes can be written as \f$F^i_\alpha\f$. A simple example
     113             :  * would be the fluid velocity in hydro systems, where we would write the flux
     114             :  * as \f$F^{ij}\f$.
     115             :  *
     116             :  * This tag inherits from `db::add_tag_prefix<Tags::div, Tag>`.
     117             :  */
     118             : template <typename Tag, typename MeshTag, typename InverseJacobianTag>
     119           1 : struct DivVariablesCompute : db::add_tag_prefix<div, Tag>, db::ComputeTag {
     120             :  private:
     121           0 :   using inv_jac_indices = typename InverseJacobianTag::type::index_list;
     122           0 :   static constexpr auto dim = tmpl::back<inv_jac_indices>::dim;
     123             :   static_assert(std::is_same_v<typename tmpl::front<inv_jac_indices>::Frame,
     124             :                                Frame::ElementLogical>,
     125             :                 "Must map from the logical frame.");
     126             : 
     127             :  public:
     128           0 :   using base = db::add_tag_prefix<div, Tag>;
     129           0 :   using return_type = typename base::type;
     130           0 :   static constexpr void (*function)(
     131             :       const gsl::not_null<return_type*>, const typename Tag::type&,
     132             :       const Mesh<dim>&, const typename InverseJacobianTag::type&) = divergence;
     133           0 :   using argument_tags =
     134             :       tmpl::list<Tag, domain::Tags::Mesh<dim>, InverseJacobianTag>;
     135             : };
     136             : 
     137             : /// \ingroup DataBoxTagsGroup
     138             : /// \brief Compute the divergence of a `tnsr::I` (vector)
     139             : ///
     140             : /// This tag inherits from `db::add_tag_prefix<Tags::div, Tag>`.
     141             : template <typename Tag, typename MeshTag, typename InverseJacobianTag>
     142           1 : struct DivVectorCompute : div<Tag>, db::ComputeTag {
     143             :  private:
     144           0 :   using inv_jac_indices = typename InverseJacobianTag::type::index_list;
     145           0 :   static constexpr auto dim = tmpl::back<inv_jac_indices>::dim;
     146             :   static_assert(std::is_same_v<typename tmpl::front<inv_jac_indices>::Frame,
     147             :                                Frame::ElementLogical>,
     148             :                 "Must map from the logical frame.");
     149             : 
     150             :  public:
     151           0 :   using base = div<Tag>;
     152           0 :   using return_type = typename base::type;
     153           0 :   static constexpr void (*function)(const gsl::not_null<return_type*>,
     154             :                                     const typename Tag::type&, const Mesh<dim>&,
     155             :                                     const typename InverseJacobianTag::type&) =
     156             :       divergence<dim, typename tmpl::back<inv_jac_indices>::Frame>;
     157           0 :   using argument_tags = tmpl::list<Tag, MeshTag, InverseJacobianTag>;
     158             : };
     159             : }  // namespace Tags

Generated by: LCOV version 1.14