SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearOperators - PartialDerivatives.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 20 35 57.1 %
Date: 2025-12-05 05:03:31
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 computing partial derivatives.
       6             : 
       7             : #pragma once
       8             : 
       9             : #include <array>
      10             : #include <cstddef>
      11             : #include <string>
      12             : 
      13             : #include "DataStructures/DataBox/PrefixHelpers.hpp"
      14             : #include "DataStructures/DataBox/Prefixes.hpp"
      15             : #include "DataStructures/DataBox/Tag.hpp"
      16             : #include "DataStructures/DataBox/TagName.hpp"
      17             : #include "DataStructures/Variables.hpp"
      18             : #include "Utilities/Requires.hpp"
      19             : #include "Utilities/TMPL.hpp"
      20             : #include "Utilities/TypeTraits/IsA.hpp"
      21             : 
      22             : /// \cond
      23             : class DataVector;
      24             : class Matrix;
      25             : template <size_t Dim>
      26             : class Mesh;
      27             : 
      28             : namespace domain {
      29             : namespace Tags {
      30             : template <size_t Dim>
      31             : struct Mesh;
      32             : }  // namespace Tags
      33             : }  // namespace domain
      34             : namespace Tags {
      35             : template <class TagList>
      36             : struct Variables;
      37             : }  // namespace Tags
      38             : /// \endcond
      39             : 
      40             : namespace partial_derivatives_detail {
      41             : void apply_matrix_in_first_dim(double* result, const double* input,
      42             :                                const Matrix& matrix, size_t size,
      43             :                                bool add_to_result = false);
      44             : void apply_matrix_in_first_dim(std::complex<double>* result,
      45             :                                const std::complex<double>* input,
      46             :                                const Matrix& matrix, size_t size,
      47             :                                bool add_to_result = false);
      48             : }  // namespace partial_derivatives_detail
      49             : 
      50             : /// @{
      51             : /// \ingroup NumericalAlgorithmsGroup
      52             : /// \brief Compute the partial derivatives of each variable with respect to
      53             : /// the element logical coordinate.
      54             : ///
      55             : /// \requires `DerivativeTags` to be the head of `VariableTags`
      56             : ///
      57             : /// Returns a `Variables` with a spatial tensor index appended to the front
      58             : /// of each tensor within `u` and each `Tag` wrapped with a `Tags::deriv`.
      59             : ///
      60             : /// \tparam DerivativeTags the subset of `VariableTags` for which derivatives
      61             : /// are computed.
      62             : template <typename DerivativeTags, typename VariableTags, size_t Dim>
      63           1 : void logical_partial_derivatives(
      64             :     gsl::not_null<std::array<Variables<DerivativeTags>, Dim>*>
      65             :         logical_partial_derivatives_of_u,
      66             :     const Variables<VariableTags>& u, const Mesh<Dim>& mesh);
      67             : 
      68             : template <typename DerivativeTags, typename VariableTags, size_t Dim>
      69           1 : auto logical_partial_derivatives(const Variables<VariableTags>& u,
      70             :                                  const Mesh<Dim>& mesh)
      71             :     -> std::array<Variables<DerivativeTags>, Dim>;
      72             : /// @}
      73             : 
      74             : /// @{
      75             : /*!
      76             :  * \ingroup NumericalAlgorithmsGroup
      77             :  * \brief Computes the logical partial derivative of a tensor, prepending the
      78             :  * spatial derivative index, e.g. for \f$\partial_i T_{a}{}^{b}\f$ the C++ call
      79             :  * is `get(i, a, b)`.
      80             :  *
      81             :  * There is an overload that accepts a `buffer` of size
      82             :  * `mesh.number_of_grid_points()` or larger. When passed this function performs
      83             :  * no memory allocations, which helps improve performance.
      84             :  *
      85             :  * If you have a `Variables` with several tensors you need to differentiate you
      86             :  * should use the `logical_partial_derivatives` function that operates on
      87             :  * `Variables` since that'll be more efficient.
      88             :  */
      89             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim>
      90           1 : void logical_partial_derivative(
      91             :     gsl::not_null<TensorMetafunctions::prepend_spatial_index<
      92             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo,
      93             :         Frame::ElementLogical>*>
      94             :         logical_derivative_of_u,
      95             :     gsl::not_null<gsl::span<typename DataType::value_type>*> buffer,
      96             :     const Tensor<DataType, SymmList, IndexList>& u, const Mesh<Dim>& mesh);
      97             : 
      98             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim>
      99           1 : void logical_partial_derivative(
     100             :     gsl::not_null<TensorMetafunctions::prepend_spatial_index<
     101             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo,
     102             :         Frame::ElementLogical>*>
     103             :         logical_derivative_of_u,
     104             :     const Tensor<DataType, SymmList, IndexList>& u, const Mesh<Dim>& mesh);
     105             : 
     106             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim>
     107           1 : auto logical_partial_derivative(const Tensor<DataType, SymmList, IndexList>& u,
     108             :                                 const Mesh<Dim>& mesh)
     109             :     -> TensorMetafunctions::prepend_spatial_index<
     110             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo,
     111             :         Frame::ElementLogical>;
     112             : /// @}
     113             : 
     114             : /// @{
     115             : /*!
     116             :  * \ingroup NumericalAlgorithmsGroup
     117             :  * \brief Compute the partial derivatives of each variable, using the Cartoon
     118             :  * method for directions not in the computational domain.
     119             :  *
     120             :  * For a spacetime with some Killing vector \f$\xi^a\f$, not only does the
     121             :  * metric respect the isometry via \f$\mathcal{L}_\xi g_{ab} = 0\f$, but the
     122             :  * fields must as well.
     123             :  *
     124             :  * In the case of axial symmetry about the \f$y\f$-axis, the Killing vector is
     125             :  * \f$\xi^a = (0, -z, 0, x)\f$, so we have that for a vector \f$V^a\f$,
     126             :  *
     127             :  * \f{align*}{
     128             :  *     \mathcal{L}_\xi V^a &= \xi^b \partial_b V^a - V^b \partial_b \xi^a
     129             :  *       = -z \partial_x V^a + x \partial_z V^a - V^b \partial_b \xi^a = 0.
     130             :  * \f}
     131             :  *
     132             :  * Choosing the computational domain to be the \f$z=0\f$ plane, get the result:
     133             :  *
     134             :  * \f{align*}{
     135             :  *     \partial_z V^a &= \frac{V^b \partial_b \xi^a}{x}.
     136             :  * \f}
     137             :  *
     138             :  * In the case that $x=0$ is in the computational domain, L'H&ocirc;pital's
     139             :  * rule is used. For a general tensor,
     140             :  * \f$T^{a_0,\ldots,a_n}{}_{b_0,\ldots,b_m}\f$ we have
     141             :  *
     142             :  * \f{align*}{
     143             :  *   \partial_z T^{a_0,\ldots,a_n}{}_{b_0,\ldots,b_m} &=
     144             :  *   \left\{
     145             :  *   \begin{array}{ll}
     146             :  *     \partial_x(\sum_k
     147             :  *     T^{a_0,\ldots,c_k,\ldots,a_n}{}_{b_0,\ldots,b_m}\partial_{c_k}
     148             :  *     \xi^{a_k} & \\
     149             :  *     \;\;\;\;\;-\sum_k
     150             :  *     T^{a_0,\ldots,a_n}{}_{b_0,\ldots,c_k,\ldots,b_m}\partial_{b_k}
     151             :  *     \xi^{c_k}
     152             :  *     ) & \mathrm{if} \; x=0  \\
     153             :  *     (\sum_k
     154             :  *     T^{a_0,\ldots,c_k,\ldots,a_n}{}_{b_0,\ldots,b_m}\partial_{c_k}
     155             :  *     \xi^{a_k} & \\
     156             :  *     \;-\sum_k
     157             :  *     T^{a_0,\ldots,a_n}{}_{b_0,\ldots,c_k,\ldots,b_m}\partial_{b_k}
     158             :  *     \xi^{c_k})\frac{1}{x} & \mathrm{otherwise}
     159             :  *   \end{array}\right.
     160             :  * \f}
     161             :  *
     162             :  * In the case of spherical symmetry, another Killing vector
     163             :  * \f$\xi'^a = (0, -y, x, 0) \f$ is used as well, with the above equation
     164             :  * easily generalizing. In that case, the computational domain is only the
     165             :  * \f$x\f$-axis.
     166             :  *
     167             :  * This function computes the partial derivatives of _all_ variables in
     168             :  * `VariableTags`. The additional parameter `inertial_coords` is used for
     169             :  * division by the \f$x\f$ coordinates. If \f$x=0\f$ is included in the domain,
     170             :  * it is assumed to be present only at the first index and is handled by
     171             :  * L'H&ocirc;pital's rule.
     172             :  *
     173             :  * The mesh is required to have the Cartoon basis in the last and potentially
     174             :  * second-to-last coordinates and the inverse Jacobian is accordingly used only
     175             :  * in the first and potentially second dimensions.
     176             :  */
     177             : template <typename ResultTags, typename VariableTags, size_t Dim,
     178             :           typename DerivativeFrame, Requires<Dim == 3> = nullptr>
     179           1 : void cartoon_partial_derivatives(
     180             :     gsl::not_null<Variables<ResultTags>*> du, const Variables<VariableTags>& u,
     181             :     const Mesh<Dim>& mesh,
     182             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     183             :                           DerivativeFrame>& inverse_jacobian_3d,
     184             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
     185             : /// @}
     186             : 
     187             : /// @{
     188             : /// \ingroup NumericalAlgorithmsGroup
     189             : /// \brief Compute the partial derivatives of each variable with respect to
     190             : /// the coordinates of `DerivativeFrame`.
     191             : ///
     192             : /// Either compute partial derivatives of _all_ variables in `VariableTags`, or
     193             : /// of a subset of the `VariablesTags`. The subset of tags (`DerivativeTags`)
     194             : /// must be the head of `VariablesTags`.
     195             : ///
     196             : /// The return-by-reference overload infers all template parameters from the
     197             : /// arguments. The tensor types in the output buffer must have a spatial index
     198             : /// appended to the front.
     199             : ///
     200             : /// The return-by-value overload requires that the `DerivativeTags` are
     201             : /// specified explicitly as the first template parameter. It returns a
     202             : /// `Variables` with the `DerivativeTags` wrapped in `Tags::deriv`.
     203             : template <typename ResultTags, typename DerivativeTags, size_t Dim,
     204             :           typename DerivativeFrame>
     205           1 : void partial_derivatives(
     206             :     gsl::not_null<Variables<ResultTags>*> du,
     207             :     const std::array<Variables<DerivativeTags>, Dim>&
     208             :         logical_partial_derivatives_of_u,
     209             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     210             :                           DerivativeFrame>& inverse_jacobian);
     211             : 
     212             : template <typename ResultTags, typename VariableTags, size_t Dim,
     213             :           typename DerivativeFrame>
     214           1 : void partial_derivatives(
     215             :     gsl::not_null<Variables<ResultTags>*> du, const Variables<VariableTags>& u,
     216             :     const Mesh<Dim>& mesh,
     217             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     218             :                           DerivativeFrame>& inverse_jacobian);
     219             : 
     220             : template <typename DerivativeTags, typename VariableTags, size_t Dim,
     221             :           typename DerivativeFrame>
     222           1 : auto partial_derivatives(
     223             :     const Variables<VariableTags>& u, const Mesh<Dim>& mesh,
     224             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     225             :                           DerivativeFrame>& inverse_jacobian)
     226             :     -> Variables<db::wrap_tags_in<Tags::deriv, DerivativeTags,
     227             :                                   tmpl::size_t<Dim>, DerivativeFrame>>;
     228             : /// @}
     229             : 
     230             : /// @{
     231             : /// \ingroup NumericalAlgorithmsGroup
     232             : /// \brief Compute the partial derivative of a `Tensor` with respect to
     233             : /// the coordinates of `DerivativeFrame`.
     234             : ///
     235             : /// Returns a `Tensor` with a spatial tensor index appended to the front
     236             : /// of the input `Tensor`.
     237             : ///
     238             : /// If you have a `Variables` with several tensors you need to differentiate,
     239             : /// you should use the `partial_derivatives` function that operates on
     240             : /// `Variables` since that'll be more efficient.
     241             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim,
     242             :           typename DerivativeFrame>
     243           1 : void partial_derivative(
     244             :     const gsl::not_null<TensorMetafunctions::prepend_spatial_index<
     245             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo, DerivativeFrame>*>
     246             :         du,
     247             :     const TensorMetafunctions::prepend_spatial_index<
     248             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo,
     249             :         Frame::ElementLogical>& logical_partial_derivative_of_u,
     250             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     251             :                           DerivativeFrame>& inverse_jacobian);
     252             : 
     253             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim,
     254             :           typename DerivativeFrame>
     255           1 : void partial_derivative(
     256             :     const gsl::not_null<TensorMetafunctions::prepend_spatial_index<
     257             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo, DerivativeFrame>*>
     258             :         du,
     259             :     const Tensor<DataType, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     260             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     261             :                           DerivativeFrame>& inverse_jacobian);
     262             : 
     263             : template <typename DataType, typename SymmList, typename IndexList, size_t Dim,
     264             :           typename DerivativeFrame>
     265           1 : auto partial_derivative(
     266             :     const Tensor<DataType, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     267             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     268             :                           DerivativeFrame>& inverse_jacobian)
     269             :     -> TensorMetafunctions::prepend_spatial_index<
     270             :         Tensor<DataType, SymmList, IndexList>, Dim, UpLo::Lo, DerivativeFrame>;
     271             : /// @}
     272             : 
     273             : /// @{
     274             : /// \ingroup NumericalAlgorithmsGroup
     275             : /// \brief Compute the partial derivative of a `Tensor` with respect to
     276             : /// the coordinates of `DerivativeFrame` when a Cartoon basis is being used.
     277             : ///
     278             : /// Returns a `Tensor` with a spatial tensor index appended to the front
     279             : /// of the input `Tensor`.
     280             : ///
     281             : /// If you have a `Variables` with several tensors with Cartoon bases you need
     282             : /// to differentiate, you should use the `cartoon_partial_derivatives` function
     283             : /// that operates on `Variables` since that'll be more efficient.
     284             : template <typename SymmList, typename IndexList, size_t Dim,
     285             :           typename DerivativeFrame, Requires<Dim == 3> = nullptr>
     286           1 : void cartoon_partial_derivative(
     287             :     gsl::not_null<TensorMetafunctions::prepend_spatial_index<
     288             :         Tensor<DataVector, SymmList, IndexList>, Dim, UpLo::Lo,
     289             :         DerivativeFrame>*>
     290             :         du,
     291             :     const Tensor<DataVector, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     292             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     293             :                           DerivativeFrame>& inverse_jacobian,
     294             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
     295             : 
     296             : template <typename SymmList, typename IndexList, size_t Dim,
     297             :           typename DerivativeFrame, Requires<Dim == 3> = nullptr>
     298           1 : auto cartoon_partial_derivative(
     299             :     const Tensor<DataVector, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     300             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     301             :                           DerivativeFrame>& inverse_jacobian,
     302             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords)
     303             :     -> TensorMetafunctions::prepend_spatial_index<
     304             :         Tensor<DataVector, SymmList, IndexList>, Dim, UpLo::Lo,
     305             :         DerivativeFrame>;
     306             : /// @}
     307             : 
     308             : /// @{
     309             : /// \ingroup NumericalAlgorithmsGroup
     310             : /// \brief Calls the correct partial derivatives function, either normal
     311             : /// partials or cartoon partials, as determined by mesh basis.
     312             : ///
     313             : /// To be used in executables that allow a Cartoon basis, a choice that is
     314             : /// only known at runtime.
     315             : template <typename ResultTags, typename VariableTags, size_t Dim,
     316             :           typename DerivativeFrame>
     317           1 : void partial_derivatives(
     318             :     gsl::not_null<Variables<ResultTags>*> du,
     319             :     const Variables<VariableTags>& u, const Mesh<Dim>& mesh,
     320             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     321             :                           DerivativeFrame>& inverse_jacobian,
     322             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
     323             : /// @}
     324             : 
     325             : /// @{
     326             : /// \ingroup NumericalAlgorithmsGroup
     327             : /// \brief Calls the correct partial derivative function, either normal
     328             : /// partial or cartoon partial, as determined by mesh basis.
     329             : ///
     330             : /// To be used in executables that allow a Cartoon basis, a choice that is
     331             : /// only known at runtime.
     332             : template <typename SymmList, typename IndexList, size_t Dim,
     333             :           typename DerivativeFrame>
     334           1 : void partial_derivative(
     335             :     gsl::not_null<TensorMetafunctions::prepend_spatial_index<
     336             :         Tensor<DataVector, SymmList, IndexList>, Dim, UpLo::Lo,
     337             :         DerivativeFrame>*>
     338             :         du,
     339             :     const Tensor<DataVector, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     340             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     341             :                           DerivativeFrame>& inverse_jacobian,
     342             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
     343             : 
     344             : template <typename SymmList, typename IndexList, size_t Dim,
     345             :           typename DerivativeFrame>
     346           1 : auto partial_derivative(
     347             :     const Tensor<DataVector, SymmList, IndexList>& u, const Mesh<Dim>& mesh,
     348             :     const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     349             :                           DerivativeFrame>& inverse_jacobian,
     350             :     const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords)
     351             :     -> TensorMetafunctions::prepend_spatial_index<
     352             :         Tensor<DataVector, SymmList, IndexList>, Dim, UpLo::Lo,
     353             :         DerivativeFrame>;
     354             : /// @}
     355             : 
     356             : namespace Tags {
     357             : 
     358             : /*!
     359             :  * \ingroup DataBoxTagsGroup
     360             :  * \brief Compute the spatial derivatives of tags in a Variables
     361             :  *
     362             :  * Computes the spatial derivatives of the Tensors in the Variables represented
     363             :  * by `VariablesTag` in the frame mapped to by `InverseJacobianTag`. To only
     364             :  * take the derivatives of a subset of these Tensors you can set the
     365             :  * `DerivTags` template parameter. It takes a `tmpl::list` of the desired
     366             :  * tags and defaults to the full `tags_list` of the Variables.
     367             :  *
     368             :  * For an executable that does not allow a Cartoon basis, the last parameter,
     369             :  * `InertialCoordsTag`, should not be passed.
     370             :  *
     371             :  * This tag may be retrieved via `::Tags::Variables<db::wrap_tags_in<deriv,
     372             :  * DerivTags, Dim, deriv_frame>`.
     373             :  */
     374             : template <typename VariablesTag, typename MeshTag, typename InverseJacobianTag,
     375             :           typename DerivTags = typename VariablesTag::type::tags_list,
     376             :           typename InertialCoordsTag = void>
     377           1 : struct DerivCompute
     378             :     : db::add_tag_prefix<
     379             :           deriv, ::Tags::Variables<DerivTags>,
     380             :           tmpl::size_t<
     381             :               tmpl::back<typename InverseJacobianTag::type::index_list>::dim>,
     382             :           typename tmpl::back<
     383             :               typename InverseJacobianTag::type::index_list>::Frame>,
     384             :       db::ComputeTag {
     385             :  private:
     386           0 :   using inv_jac_indices = typename InverseJacobianTag::type::index_list;
     387           0 :   static constexpr auto Dim = tmpl::back<inv_jac_indices>::dim;
     388           0 :   using deriv_frame = typename tmpl::back<inv_jac_indices>::Frame;
     389             : 
     390             :  public:
     391           0 :   using base = db::add_tag_prefix<
     392             :       deriv, ::Tags::Variables<DerivTags>,
     393             :       tmpl::size_t<
     394             :           tmpl::back<typename InverseJacobianTag::type::index_list>::dim>,
     395             :       typename tmpl::back<
     396             :           typename InverseJacobianTag::type::index_list>::Frame>;
     397           0 :   using return_type = typename base::type;
     398           0 :   static constexpr void function(
     399             :       gsl::not_null<return_type*> du, const typename VariablesTag::type& u,
     400             :       const Mesh<Dim>& mesh,
     401             :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     402             :                             deriv_frame>& inverse_jacobian) {
     403             :     partial_derivatives(du, u, mesh, inverse_jacobian);
     404             :   }
     405           0 :   static constexpr void function(
     406             :       gsl::not_null<return_type*> du, const typename VariablesTag::type& u,
     407             :       const Mesh<Dim>& mesh,
     408             :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     409             :                             deriv_frame>& inverse_jacobian,
     410             :       const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords) {
     411             :     partial_derivatives(du, u, mesh, inverse_jacobian, inertial_coords);
     412             :   }
     413           0 :   using argument_tags = tmpl::conditional_t<
     414             :       std::is_same_v<void, InertialCoordsTag>,
     415             :       tmpl::list<VariablesTag, MeshTag, InverseJacobianTag>,
     416             :       tmpl::list<VariablesTag, MeshTag, InverseJacobianTag, InertialCoordsTag>>;
     417             : };
     418             : 
     419             : /*!
     420             :  * \ingroup DataBoxTagsGroup
     421             :  * \brief Computes the spatial derivative of a single tensor tag not in a
     422             :  * Variables.
     423             :  *
     424             :  * Computes the spatial derivative for a single tensor represented by
     425             :  * 'TensorTag' in the frame mapped to by 'InverseJacobianTag'. It takes a
     426             :  * single Tensor designated by 'TensorTag', the inverse Jacobian, and a mesh.
     427             :  */
     428             : template <typename TensorTag, typename InverseJacobianTag, typename MeshTag>
     429           1 : struct DerivTensorCompute
     430             :     : ::Tags::deriv<TensorTag,
     431             :                     tmpl::size_t<tmpl::back<
     432             :                         typename InverseJacobianTag::type::index_list>::dim>,
     433             :                     typename tmpl::back<
     434             :                         typename InverseJacobianTag::type::index_list>::Frame>,
     435             :       db::ComputeTag {
     436             :  private:
     437           0 :   using inv_jac_indices = typename InverseJacobianTag::type::index_list;
     438           0 :   static constexpr auto Dim = tmpl::back<inv_jac_indices>::dim;
     439           0 :   using deriv_frame = typename tmpl::back<inv_jac_indices>::Frame;
     440             : 
     441             :  public:
     442           0 :   using base = ::Tags::deriv<TensorTag, tmpl::size_t<Dim>, deriv_frame>;
     443           0 :   using return_type = typename base::type;
     444           0 :   static constexpr void (*function)(
     445             :       gsl::not_null<return_type*>, const typename TensorTag::type&,
     446             :       const Mesh<Dim>&,
     447             :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     448             :                             deriv_frame>&) =
     449             :       partial_derivative<
     450             :           typename TensorTag::type::type, typename TensorTag::type::symmetry,
     451             :           typename TensorTag::type::index_list, Dim, deriv_frame>;
     452           0 :   using argument_tags =
     453             :       tmpl::list<TensorTag, domain::Tags::Mesh<Dim>, InverseJacobianTag>;
     454             : };
     455             : }  // namespace Tags

Generated by: LCOV version 1.14