Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <array>
7 : #include <cstddef>
8 :
9 : #include "DataStructures/Tensor/TypeAliases.hpp"
10 : #include "NumericalAlgorithms/LinearOperators/PartialDerivatives.hpp"
11 : #include "Utilities/Gsl.hpp"
12 :
13 : /// \cond
14 : class DataVector;
15 : template <size_t Dim, typename T>
16 : class DirectionMap;
17 : template <size_t Dim>
18 : class Mesh;
19 : template <typename TagsList>
20 : class Variables;
21 : /// \endcond
22 :
23 : namespace fd {
24 : /*!
25 : * \ingroup NumericalAlgorithmsGroup
26 : * \brief Compute the logical partial derivatives using cell-centered finite
27 : * difference derivatives.
28 : *
29 : * Up to 8th order stencils are supported.
30 : *
31 : * \note Currently the stride is always one because we transpose the data before
32 : * reconstruction. However, it may be faster to have a non-unit stride without
33 : * the transpose. We have the `stride` parameter in the derivative stencils
34 : * to make testing performance easier in the future.
35 : *
36 : * \note This code does not do any explicit SIMD vectorization. We will want to
37 : * profile and decide if optimization are possible. The Vc SIMD library has an
38 : * example of vectorizing single-precision FD derivatives. There is also a paper
39 : * "Optimization of Finite-Differencing Kernels for Numerical Relativity
40 : * Applications" by Alfieri, Bernuzzi, Perego, and Radice that uses compiler
41 : * auto-vectorization.
42 : */
43 : template <size_t Dim>
44 1 : void logical_partial_derivatives(
45 : const gsl::not_null<std::array<gsl::span<double>, Dim>*>
46 : logical_derivatives,
47 : const gsl::span<const double>& volume_vars,
48 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
49 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order);
50 :
51 : /*!
52 : * \ingroup NumericalAlgorithmsGroup
53 : * \brief Compute the partial derivative on the `DerivativeFrame` using the
54 : * `inverse_jacobian`.
55 : *
56 : * Logical partial derivatives are first computed using the
57 : * `fd::logical_partial_derivatives()` function.
58 : */
59 : template <typename DerivativeTags, size_t Dim, typename DerivativeFrame>
60 1 : void partial_derivatives(
61 : gsl::not_null<Variables<db::wrap_tags_in<
62 : Tags::deriv, DerivativeTags, tmpl::size_t<Dim>, DerivativeFrame>>*>
63 : d_volume_vars,
64 : const gsl::span<const double>& volume_vars,
65 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
66 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order,
67 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
68 : DerivativeFrame>& inverse_jacobian);
69 : /*!
70 : * \ingroup NumericalAlgorithmsGroup
71 : * \brief Compute the partial derivative using the `inverse_jacobian` for
72 : * `Basis::FiniteDifference` dimensions and the Cartoon method for
73 : * `Basis::Cartoon` dimensions.
74 : *
75 : * See DG `cartoon_partial_derivatives()` for information on the Cartoon method.
76 : */
77 : template <typename DerivativeTags, typename VariableTags, size_t Dim,
78 : typename DerivativeFrame, Requires<Dim == 3> = nullptr>
79 1 : void cartoon_partial_derivatives(
80 : gsl::not_null<Variables<db::wrap_tags_in<
81 : Tags::deriv, DerivativeTags, tmpl::size_t<Dim>, DerivativeFrame>>*>
82 : d_volume_vars,
83 : const Variables<VariableTags>& volume_vars,
84 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
85 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order,
86 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
87 : DerivativeFrame>& inverse_jacobian,
88 : const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
89 :
90 : /*!
91 : * \ingroup NumericalAlgorithmsGroup
92 : * \brief Compute the partial derivative, either normal FD or FD/cartoon,
93 : * based on the mesh (only known at runtime).
94 : */
95 : template <typename DerivativeTags, typename VariableTags, size_t Dim,
96 : typename DerivativeFrame>
97 1 : void partial_derivatives(
98 : gsl::not_null<Variables<db::wrap_tags_in<
99 : Tags::deriv, DerivativeTags, tmpl::size_t<Dim>, DerivativeFrame>>*>
100 : d_volume_vars,
101 : const Variables<VariableTags>& volume_vars,
102 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars,
103 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order,
104 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical,
105 : DerivativeFrame>& inverse_jacobian,
106 : const tnsr::I<DataVector, Dim, Frame::Inertial>& inertial_coords);
107 :
108 : } // namespace fd
|