Protocols.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
7 #include "Utilities/TMPL.hpp"
8 #include "Utilities/TypeTraits.hpp"
9 #include "Utilities/TypeTraits/CreateHasTypeAlias.hpp"
10 #include "Utilities/TypeTraits/CreateIsCallable.hpp"
11 #include "Utilities/TypeTraits/IsCallable.hpp"
12 
13 namespace dg {
14 /// \ref protocols related to Discontinuous Galerkin functionality
15 namespace protocols {
16 
17 namespace detail {
18 CREATE_HAS_TYPE_ALIAS(variables_tags)
19 CREATE_HAS_TYPE_ALIAS_V(variables_tags)
20 CREATE_HAS_TYPE_ALIAS(argument_tags)
21 CREATE_HAS_TYPE_ALIAS_V(argument_tags)
22 CREATE_HAS_TYPE_ALIAS(package_field_tags)
23 CREATE_HAS_TYPE_ALIAS_V(package_field_tags)
24 CREATE_HAS_TYPE_ALIAS(package_extra_tags)
25 CREATE_HAS_TYPE_ALIAS_V(package_extra_tags)
26 CREATE_IS_CALLABLE(package_data)
27 
28 template <typename NumericalFluxType, typename ArgumentTags,
29  typename PackageFieldTags, typename PackageExtraTags>
30 struct IsPackageDataCallableImpl;
31 
32 template <typename NumericalFluxType, typename... ArgumentTags,
33  typename... PackageFieldTags, typename... PackageExtraTags>
34 struct IsPackageDataCallableImpl<NumericalFluxType, tmpl::list<ArgumentTags...>,
35  tmpl::list<PackageFieldTags...>,
36  tmpl::list<PackageExtraTags...>>
37  : is_package_data_callable_r_t<
38  void, NumericalFluxType,
39  gsl::not_null<db::item_type<PackageFieldTags>*>...,
40  gsl::not_null<db::item_type<PackageExtraTags>*>...,
41  db::const_item_type<ArgumentTags>...> {};
42 
43 template <typename NumericalFluxType>
44 struct IsPackageDataCallable
45  : IsPackageDataCallableImpl<
46  NumericalFluxType, typename NumericalFluxType::argument_tags,
47  typename NumericalFluxType::package_field_tags,
48  typename NumericalFluxType::package_extra_tags> {};
49 
50 template <typename NumericalFluxType, typename VariablesTags,
51  typename PackageFieldTags, typename PackageExtraTags>
52 struct IsNumericalFluxCallableImpl;
53 
54 template <typename NumericalFluxType, typename... VariablesTags,
55  typename... PackageFieldTags, typename... PackageExtraTags>
56 struct IsNumericalFluxCallableImpl<
57  NumericalFluxType, tmpl::list<VariablesTags...>,
58  tmpl::list<PackageFieldTags...>, tmpl::list<PackageExtraTags...>>
59  : tt::is_callable_t<NumericalFluxType,
60  gsl::not_null<db::item_type<VariablesTags>*>...,
61  db::const_item_type<PackageFieldTags>...,
62  db::const_item_type<PackageExtraTags>...,
63  db::const_item_type<PackageFieldTags>...,
64  db::const_item_type<PackageExtraTags>...> {};
65 
66 template <typename NumericalFluxType>
67 struct IsNumericalFluxCallable
68  : IsNumericalFluxCallableImpl<
69  NumericalFluxType, typename NumericalFluxType::variables_tags,
70  typename NumericalFluxType::package_field_tags,
71  typename NumericalFluxType::package_extra_tags> {};
72 } // namespace detail
73 
74 /*!
75  * \ingroup ProtocolsGroup
76  * \brief Defines the interface for DG numerical fluxes
77  *
78  * This protocol defines the interface that a class must conform to so that it
79  * can be used as a numerical flux in DG boundary schemes. Essentially, the
80  * class must be able to compute the quantity \f$G\f$ that appears, for example,
81  * in the strong first-order DG boundary scheme
82  * \f$G_\alpha(n_i^\mathrm{int}, u_\alpha^\mathrm{int}, n_i^\mathrm{ext},
83  * u_\alpha^\mathrm{ext}) - n_i^\mathrm{int} F^{i,\mathrm{int}}_\alpha\f$
84  * where \f$u_\alpha\f$ are the system variables and \f$F^i_\alpha\f$ their
85  * corresponding fluxes. See also Eq. (2.20) in \cite Teukolsky2015ega where the
86  * quantity \f$G\f$ is denoted \f$n_i F^{i*}\f$, which is why we occasionally
87  * refer to it as the "normal-dot-numerical-fluxes".
88  *
89  * Requires the `ConformingType` has these type aliases:
90  * - `variables_tags`: A typelist of DataBox tags that the class computes
91  * numerical fluxes for.
92  * - `argument_tags`: A typelist of DataBox tags that will be retrieved on
93  * interfaces and passed to the `package_data` function (see below). The
94  * `ConformingType` may also have a `volume_tags` typelist that specifies the
95  * subset of `argument_tags` that should be retrieved from the volume instead
96  * of the interface.
97  * - `package_field_tags`: A typelist of DataBox tags with `Tensor` types that
98  * the `package_data` function will compute from the `argument_tags`. These
99  * quantities will be made available on both sides of a mortar and passed to
100  * the call operator to compute the numerical flux.
101  * - `package_extra_tags`: Additional non-tensor tags that will be made
102  * available on both sides of a mortar, e.g. geometric quantities.
103  *
104  * Requires the `ConformingType` has these member functions:
105  * - `package_data`: Takes the types of the `package_field_tags` and the
106  * `package_extra_tags` by `gsl::not_null` pointer, followed by the types of the
107  * `argument_tags`.
108  * - `operator()`: Takes the types of the `variables_tags` by `gsl::not_null`
109  * pointer, followed by the types of the `package_field_tags` and the
110  * `package_extra_tags` from the interior side of the mortar and from the
111  * exterior side. Note that the data from the exterior side was computed
112  * entirely with data from the neighboring element, including its interface
113  * normal which is (at least when it's independent of the system variables)
114  * opposite to the interior element's interface normal. Therefore, make sure to
115  * take into account the sign flip for quantities that include the interface
116  * normal.
117  *
118  * Here's an example for a simple "central" numerical flux
119  * \f$G_\alpha(n_i^\mathrm{int}, u_\alpha^\mathrm{int}, n_i^\mathrm{ext},
120  * u_\alpha^\mathrm{ext}) = \frac{1}{2}\left(n_i^\mathrm{int}
121  * F^{i,\mathrm{int}}_\alpha - n_i^\mathrm{ext} F^{i,\mathrm{ext}}_\alpha
122  * \right)\f$:
123  *
124  * \snippet DiscontinuousGalerkin/Test_Protocols.cpp numerical_flux_example
125  *
126  * Note that this numerical flux reduces to the interface average
127  * \f$G_\alpha=\frac{n^\mathrm{int}_i}{2}\left(F^{i,\mathrm{int}}_\alpha +
128  * F^{i,\mathrm{ext}}_\alpha\right)\f$ for the case where the interface normal
129  * is independent of the system variables and therefore \f$n_i^\mathrm{ext} =
130  * -n_i^\mathrm{int}\f$.
131  */
132 template <typename ConformingType>
134  tmpl2::flat_all_v<detail::has_variables_tags_v<ConformingType>,
135  detail::has_argument_tags_v<ConformingType>,
136  detail::has_package_field_tags_v<ConformingType>,
137  detail::has_package_extra_tags_v<ConformingType>>,
139  detail::IsNumericalFluxCallable<ConformingType>>,
141 
142 } // namespace protocols
143 } // namespace dg
#define CREATE_IS_CALLABLE(METHOD_NAME)
Generate a type trait to check if a class has a member function that can be invoked with arguments of...
Definition: CreateIsCallable.hpp:32
#define CREATE_HAS_TYPE_ALIAS(ALIAS_NAME)
Generate a type trait to check if a class has a type alias with a particular name, optionally also checking its type.
Definition: CreateHasTypeAlias.hpp:28
Functionality related to discontinuous Galerkin schemes.
Definition: ApplyBoundaryFluxesLocalTimeStepping.hpp:33
typename is_callable< T, Args... >::type is_callable_t
Definition: IsCallable.hpp:73
A logical AND on the template parameters.
Definition: TypeTraits.hpp:70
Definition: Determinant.hpp:11
#define CREATE_HAS_TYPE_ALIAS_V(ALIAS_NAME)
Generate a type trait to check if a class has a type alias with a particular name, optionally also checking its type.
Definition: CreateHasTypeAlias.hpp:41
Wraps the template metaprogramming library used (brigand)
tmpl::flatten< tmpl::list< Tags... > > ArgumentTags
List of Tags to get from the DataBox to be used as arguments.
Definition: DataBox.hpp:1245
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...