SpECTRE Documentation Coverage Report
Current view: top level - NumericalAlgorithms/LinearOperators - PartialDerivatives.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 55.6 % 36 20
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              : /// 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              :  * For an executable that does not allow a Cartoon basis, the last parameter,
     429              :  * `InertialCoordsTag`, should not be passed.
     430              :  */
     431              : template <typename TensorTag, typename InverseJacobianTag, typename MeshTag,
     432              :           typename InertialCoordsTag = void>
     433            1 : struct DerivTensorCompute
     434              :     : ::Tags::deriv<TensorTag,
     435              :                     tmpl::size_t<tmpl::back<
     436              :                         typename InverseJacobianTag::type::index_list>::dim>,
     437              :                     typename tmpl::back<
     438              :                         typename InverseJacobianTag::type::index_list>::Frame>,
     439              :       db::ComputeTag {
     440              :  private:
     441            0 :   using inv_jac_indices = typename InverseJacobianTag::type::index_list;
     442            0 :   static constexpr auto Dim = tmpl::back<inv_jac_indices>::dim;
     443            0 :   using deriv_frame = typename tmpl::back<inv_jac_indices>::Frame;
     444              : 
     445              :  public:
     446            0 :   using base = ::Tags::deriv<TensorTag, tmpl::size_t<Dim>, deriv_frame>;
     447            0 :   using return_type = typename base::type;
     448            0 :   static constexpr void function(
     449              :       const gsl::not_null<return_type*> du, const typename TensorTag::type& u,
     450              :       const Mesh<Dim>& mesh,
     451              :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     452              :                             deriv_frame>& inverse_jacobian) {
     453              :     partial_derivative(du, u, mesh, inverse_jacobian);
     454              :   }
     455            0 :   static constexpr void function(
     456              :       const gsl::not_null<return_type*> du, const typename TensorTag::type& u,
     457              :       const Mesh<Dim>& mesh,
     458              :       const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
     459              :                             deriv_frame>& inverse_jacobian,
     460              :       const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords) {
     461              :     partial_derivative(du, u, mesh, inverse_jacobian, inertial_coords);
     462              :   }
     463            0 :   using argument_tags = tmpl::conditional_t<
     464              :       std::is_same_v<void, InertialCoordsTag>,
     465              :       tmpl::list<TensorTag, MeshTag, InverseJacobianTag>,
     466              :       tmpl::list<TensorTag, MeshTag, InverseJacobianTag, InertialCoordsTag>>;
     467              : };
     468              : }  // namespace Tags
        

Generated by: LCOV version 2.0-1