Protocols.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include "Utilities/Gsl.hpp"
7 #include "Utilities/TMPL.hpp"
8 
9 namespace dg {
10 /// \ref protocols related to Discontinuous Galerkin functionality
11 namespace protocols {
12 
13 namespace detail {
14 template <typename NumericalFluxType, typename VariablesTags,
15  typename PackageFieldTags, typename PackageExtraTags>
16 struct TestCallOperatorImpl;
17 
18 template <typename NumericalFluxType, typename... VariablesTags,
19  typename... PackageFieldTags, typename... PackageExtraTags>
20 struct TestCallOperatorImpl<NumericalFluxType, tmpl::list<VariablesTags...>,
21  tmpl::list<PackageFieldTags...>,
22  tmpl::list<PackageExtraTags...>> {
23  using type = decltype(std::declval<NumericalFluxType>()(
24  std::declval<gsl::not_null<tmpl::type_from<VariablesTags>*>>()...,
25  std::declval<tmpl::type_from<PackageFieldTags>>()...,
26  std::declval<tmpl::type_from<PackageExtraTags>>()...,
27  std::declval<tmpl::type_from<PackageFieldTags>>()...,
28  std::declval<tmpl::type_from<PackageExtraTags>>()...));
29 };
30 } // namespace detail
31 
32 /*!
33  * \ingroup ProtocolsGroup
34  * \brief Defines the interface for DG numerical fluxes
35  *
36  * This protocol defines the interface that a class must conform to so that it
37  * can be used as a numerical flux in DG boundary schemes. Essentially, the
38  * class must be able to compute the quantity \f$G\f$ that appears, for example,
39  * in the strong first-order DG boundary scheme
40  * \f$G_\alpha(n_i^\mathrm{int}, u_\alpha^\mathrm{int}, n_i^\mathrm{ext},
41  * u_\alpha^\mathrm{ext}) - n_i^\mathrm{int} F^{i,\mathrm{int}}_\alpha\f$
42  * where \f$u_\alpha\f$ are the system variables and \f$F^i_\alpha\f$ their
43  * corresponding fluxes. See also Eq. (2.20) in \cite Teukolsky2015ega where the
44  * quantity \f$G\f$ is denoted \f$n_i F^{i*}\f$, which is why we occasionally
45  * refer to it as the "normal-dot-numerical-fluxes".
46  *
47  * Requires the `ConformingType` has these type aliases:
48  * - `variables_tags`: A typelist of DataBox tags that the class computes
49  * numerical fluxes for.
50  * - `argument_tags`: A typelist of DataBox tags that will be retrieved on
51  * interfaces and passed to the `package_data` function (see below). The
52  * `ConformingType` may also have a `volume_tags` typelist that specifies the
53  * subset of `argument_tags` that should be retrieved from the volume instead
54  * of the interface.
55  * - `package_field_tags`: A typelist of DataBox tags with `Tensor` types that
56  * the `package_data` function will compute from the `argument_tags`. These
57  * quantities will be made available on both sides of a mortar and passed to
58  * the call operator to compute the numerical flux.
59  * - `package_extra_tags`: Additional non-tensor tags that will be made
60  * available on both sides of a mortar, e.g. geometric quantities.
61  *
62  * Requires the `ConformingType` has these member functions:
63  * - `package_data`: Takes the types of the `package_field_tags` and the
64  * `package_extra_tags` by `gsl::not_null` pointer, followed by the types of the
65  * `argument_tags`.
66  * - `operator()`: Takes the types of the `variables_tags` by `gsl::not_null`
67  * pointer, followed by the types of the `package_field_tags` and the
68  * `package_extra_tags` from the interior side of the mortar and from the
69  * exterior side. Note that the data from the exterior side was computed
70  * entirely with data from the neighboring element, including its interface
71  * normal which is (at least when it's independent of the system variables)
72  * opposite to the interior element's interface normal. Therefore, make sure to
73  * take into account the sign flip for quantities that include the interface
74  * normal.
75  *
76  * Here's an example for a simple "central" numerical flux
77  * \f$G_\alpha(n_i^\mathrm{int}, u_\alpha^\mathrm{int}, n_i^\mathrm{ext},
78  * u_\alpha^\mathrm{ext}) = \frac{1}{2}\left(n_i^\mathrm{int}
79  * F^{i,\mathrm{int}}_\alpha - n_i^\mathrm{ext} F^{i,\mathrm{ext}}_\alpha
80  * \right)\f$:
81  *
82  * \snippet DiscontinuousGalerkin/Test_Protocols.cpp numerical_flux_example
83  *
84  * Note that this numerical flux reduces to the interface average
85  * \f$G_\alpha=\frac{n^\mathrm{int}_i}{2}\left(F^{i,\mathrm{int}}_\alpha +
86  * F^{i,\mathrm{ext}}_\alpha\right)\f$ for the case where the interface normal
87  * is independent of the system variables and therefore \f$n_i^\mathrm{ext} =
88  * -n_i^\mathrm{int}\f$.
89  */
90 struct NumericalFlux {
91  template <typename ConformingType>
92  struct test {
93  using variables_tags = typename ConformingType::variables_tags;
94  using argument_tags = typename ConformingType::argument_tags;
95  using package_field_tags = typename ConformingType::package_field_tags;
96  using package_extra_tags = typename ConformingType::package_extra_tags;
97  // We can't currently check that the package_data function is callable
98  // because the `argument_tags` may contain base tags and we can't resolve
99  // their types.
100  static_assert(
101  std::is_same_v<typename detail::TestCallOperatorImpl<
102  ConformingType, variables_tags, package_field_tags,
103  package_extra_tags>::type,
104  void>,
105  "The 'operator()' must return 'void'.");
106  };
107 };
108 
109 } // namespace protocols
110 } // namespace dg
dg::protocols::NumericalFlux
Defines the interface for DG numerical fluxes.
Definition: Protocols.hpp:90
dg
Functionality related to discontinuous Galerkin schemes.
Definition: ComputeNonconservativeBoundaryFluxes.hpp:23
dg::protocols::NumericalFlux::test
Definition: Protocols.hpp:92
Gsl.hpp
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:183