NumericalFluxHelpers.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
7 #include "NumericalAlgorithms/DiscontinuousGalerkin/Protocols.hpp"
8 #include "NumericalAlgorithms/DiscontinuousGalerkin/SimpleBoundaryData.hpp"
9 #include "Utilities/Gsl.hpp"
10 #include "Utilities/ProtocolHelpers.hpp"
11 #include "Utilities/TMPL.hpp"
12 #include "Utilities/TaggedTuple.hpp"
13 
14 namespace dg {
15 namespace NumericalFluxes {
16 
17 namespace detail {
18 template <typename NumericalFluxType, typename... AllFieldTags,
19  typename... AllExtraTags, typename... Args,
20  typename... PackageFieldTags, typename... PackageExtraTags>
21 void package_data_impl(
22  const gsl::not_null<dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
23  tmpl::list<AllExtraTags...>>*>
24  packaged_data,
25  const NumericalFluxType& numerical_flux_computer,
26  tmpl::list<PackageFieldTags...> /*meta*/,
27  tmpl::list<PackageExtraTags...> /*meta*/, const Args&... args) noexcept {
28  numerical_flux_computer.package_data(
29  make_not_null(&get<PackageFieldTags>(packaged_data->field_data))...,
30  make_not_null(&get<PackageExtraTags>(packaged_data->extra_data))...,
31  args...);
32 }
33 
34 template <typename NumericalFluxType, typename... AllFieldTags,
35  typename... AllExtraTags, typename... NormalDotNumericalFluxTypes,
36  typename... PackageFieldTags, typename... PackageExtraTags>
37 void normal_dot_numerical_fluxes_impl(
38  const NumericalFluxType& numerical_flux_computer,
39  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
40  tmpl::list<AllExtraTags...>>&
41  packaged_data_int,
42  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
43  tmpl::list<AllExtraTags...>>&
44  packaged_data_ext,
45  tmpl::list<PackageFieldTags...> /*meta*/,
46  tmpl::list<PackageExtraTags...> /*meta*/,
47  // Taking output arguments last in this detail implementation so the
48  // `NormalDotNumericalFluxTypes` can be inferred
49  const gsl::not_null<
50  NormalDotNumericalFluxTypes*>... n_dot_num_fluxes) noexcept {
51  numerical_flux_computer(
52  n_dot_num_fluxes...,
53  get<PackageFieldTags>(packaged_data_int.field_data)...,
54  get<PackageExtraTags>(packaged_data_int.extra_data)...,
55  get<PackageFieldTags>(packaged_data_ext.field_data)...,
56  get<PackageExtraTags>(packaged_data_ext.extra_data)...);
57 }
58 } // namespace detail
59 
60 // @{
61 /// Helper function to unpack arguments when invoking the numerical flux
62 template <typename NumericalFluxType, typename... AllFieldTags,
63  typename... AllExtraTags, typename... Args>
64 void package_data(
65  const gsl::not_null<dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
66  tmpl::list<AllExtraTags...>>*>
67  packaged_data,
68  const NumericalFluxType& numerical_flux_computer,
69  const Args&... args) noexcept {
70  static_assert(
71  tt::conforms_to_v<NumericalFluxType, protocols::NumericalFlux>,
72  "The 'NumericalFluxType' must conform to 'dg::protocol::NumericalFlux'.");
73  detail::package_data_impl(packaged_data, numerical_flux_computer,
74  typename NumericalFluxType::package_field_tags{},
75  typename NumericalFluxType::package_extra_tags{},
76  args...);
77 }
78 
79 template <typename NumericalFluxType, typename... AllFieldTags,
80  typename... AllExtraTags, typename... NormalDotNumericalFluxTags>
81 void normal_dot_numerical_fluxes(
82  const gsl::not_null<Variables<tmpl::list<NormalDotNumericalFluxTags...>>*>
83  n_dot_num_fluxes,
84  const NumericalFluxType& numerical_flux_computer,
85  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
86  tmpl::list<AllExtraTags...>>&
87  packaged_data_int,
88  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
89  tmpl::list<AllExtraTags...>>&
90  packaged_data_ext) noexcept {
91  static_assert(
92  tt::conforms_to_v<NumericalFluxType, protocols::NumericalFlux>,
93  "The 'NumericalFluxType' must conform to 'dg::protocol::NumericalFlux'.");
94  detail::normal_dot_numerical_fluxes_impl(
95  numerical_flux_computer, packaged_data_int, packaged_data_ext,
96  typename NumericalFluxType::package_field_tags{},
97  typename NumericalFluxType::package_extra_tags{},
98  make_not_null(&get<NormalDotNumericalFluxTags>(*n_dot_num_fluxes))...);
99 }
100 
101 template <typename NumericalFluxType, typename... AllFieldTags,
102  typename... AllExtraTags, typename... NormalDotNumericalFluxes>
103 void normal_dot_numerical_fluxes(
104  const NumericalFluxType& numerical_flux_computer,
105  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
106  tmpl::list<AllExtraTags...>>&
107  packaged_data_int,
108  const dg::SimpleBoundaryData<tmpl::list<AllFieldTags...>,
109  tmpl::list<AllExtraTags...>>&
110  packaged_data_ext,
111  // Need to take these return-by-reference arguments last so the template
112  // parameter pack deduction works
113  gsl::not_null<NormalDotNumericalFluxes*>... n_dot_num_fluxes) noexcept {
114  static_assert(
115  tt::conforms_to_v<NumericalFluxType, protocols::NumericalFlux>,
116  "The 'NumericalFluxType' must conform to 'dg::protocol::NumericalFlux'.");
117  detail::normal_dot_numerical_fluxes_impl(
118  numerical_flux_computer, packaged_data_int, packaged_data_ext,
119  typename NumericalFluxType::package_field_tags{},
120  typename NumericalFluxType::package_extra_tags{}, n_dot_num_fluxes...);
121 }
122 // @}
123 
124 } // namespace NumericalFluxes
125 } // namespace dg
dg
Functionality related to discontinuous Galerkin schemes.
Definition: ComputeNonconservativeBoundaryFluxes.hpp:23
dg::SimpleBoundaryData
Distinguishes between field data, which can be projected to a mortar, and extra data,...
Definition: SimpleBoundaryData.hpp:35
Variables.hpp
Gsl.hpp
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:879
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: Gsl.hpp:182