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 : * \brief Compute the logical partial derivatives using cell-centered finite 26 : * difference derivatives. 27 : * 28 : * Up to 8th order stencils are supported. 29 : * 30 : * \note Currently the stride is always one because we transpose the data before 31 : * reconstruction. However, it may be faster to have a non-unit stride without 32 : * the transpose. We have the `stride` parameter in the derivative stencils 33 : * to make testing performance easier in the future. 34 : * 35 : * \note This code does not do any explicit SIMD vectorization. We will want to 36 : * profile and decide if optimization are possible. The Vc SIMD library has an 37 : * example of vectorizing single-precision FD derivatives. There is also a paper 38 : * "Optimization of Finite-Differencing Kernels for Numerical Relativity 39 : * Applications" by Alfieri, Bernuzzi, Perego, and Radice that uses compiler 40 : * auto-vectorization. 41 : */ 42 : template <size_t Dim> 43 1 : void logical_partial_derivatives( 44 : const gsl::not_null<std::array<gsl::span<double>, Dim>*> 45 : logical_derivatives, 46 : const gsl::span<const double>& volume_vars, 47 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars, 48 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order); 49 : 50 : /*! 51 : * \brief Compute the partial derivative on the `DerivativeFrame` using the 52 : * `inverse_jacobian`. 53 : * 54 : * Logical partial derivatives are first computed using the 55 : * `fd::logical_partial_derivatives()` function. 56 : */ 57 : template <typename DerivativeTags, size_t Dim, typename DerivativeFrame> 58 1 : void partial_derivatives( 59 : gsl::not_null<Variables<db::wrap_tags_in< 60 : Tags::deriv, DerivativeTags, tmpl::size_t<Dim>, DerivativeFrame>>*> 61 : partial_derivatives, 62 : const gsl::span<const double>& volume_vars, 63 : const DirectionMap<Dim, gsl::span<const double>>& ghost_cell_vars, 64 : const Mesh<Dim>& volume_mesh, size_t number_of_variables, size_t fd_order, 65 : const InverseJacobian<DataVector, Dim, Frame::ElementLogical, 66 : DerivativeFrame>& inverse_jacobian); 67 : } // namespace fd