LocalLaxFriedrichs.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <cstddef>
7 
11 #include "Options/Options.hpp"
12 #include "Utilities/Gsl.hpp"
14 #include "Utilities/TMPL.hpp"
15 
16 namespace dg {
17 namespace NumericalFluxes {
18 
19 /*!
20  * \ingroup DiscontinuousGalerkinGroup
21  * \ingroup NumericalFluxesGroup
22  * \brief Compute the local Lax-Friedrichs numerical flux.
23  *
24  * Let \f$U\f$ and \f$F^i(U)\f$ be the state vector of the system and its
25  * corresponding volume flux, respectively. Let \f$n_i\f$ be the unit normal to
26  * the interface. Defining \f$F_n(U) := n_i F^i(U)\f$, and denoting the
27  * corresponding projections of the numerical fluxes as \f${F_n}^*(U)\f$, the
28  * local Lax-Friedrichs flux for each variable is
29  *
30  * \f{align*}
31  * {F_n}^*(U) = \frac{F_n(U_\text{int}) + F_n(U_\text{ext})}{2} +
32  * \frac{\alpha}{2}\left( U_\text{int} - U_\text{ext}\right),
33  * \f}
34  *
35  * where "int" and "ext" stand for interior and exterior, respectively,
36  * and \f$\alpha\f$ is the maximum eigenvalue of either
37  * \f$|\Lambda(U_\text{int}; n_\text{int})|\f$ or
38  * \f$|\Lambda(U_\text{ext}; n_\text{ext})|\f$, where
39  * \f$\Lambda(U; n)\f$ is the diagonal matrix whose entries are the
40  * characteristic speeds of the system.
41  */
42 template <typename System>
44  private:
45  using char_speeds_tag = typename System::char_speeds_tag;
46  using variables_tag = typename System::variables_tag;
47 
48  public:
49  // The maximum characteristic speed modulus on one side of the interface.
51  using type = Scalar<DataVector>;
52  static std::string name() noexcept { return "MaxAbsCharSpeed"; }
53  };
54 
55  using package_tags =
56  tmpl::push_back<tmpl::append<db::split_tag<db::add_tag_prefix<
57  ::Tags::NormalDotFlux, variables_tag>>,
60 
61  using argument_tags =
62  tmpl::push_back<tmpl::append<db::split_tag<db::add_tag_prefix<
63  ::Tags::NormalDotFlux, variables_tag>>,
64  db::split_tag<variables_tag>>,
65  char_speeds_tag>;
66 
67  private:
68  template <typename VariablesTagList, typename NormalDoFluxTagList>
69  struct package_data_helper;
70 
71  template <typename... VariablesTags, typename... NormalDotFluxTags>
72  struct package_data_helper<tmpl::list<VariablesTags...>,
73  tmpl::list<NormalDotFluxTags...>> {
74  static void apply(
75  const gsl::not_null<Variables<package_tags>*> packaged_data,
76  const db::item_type<NormalDotFluxTags>&... n_dot_f_to_package,
77  const db::item_type<VariablesTags>&... u_to_package,
78  const db::item_type<char_speeds_tag>& characteristic_speeds) noexcept {
79  expand_pack((get<VariablesTags>(*packaged_data) = u_to_package)...);
81  (get<NormalDotFluxTags>(*packaged_data) = n_dot_f_to_package)...);
82  Scalar<DataVector>& char_speed = get<MaxAbsCharSpeed>(*packaged_data);
83  if (get(char_speed).size() != characteristic_speeds[0].size()) {
84  get(char_speed) = DataVector(characteristic_speeds[0].size());
85  }
86 
87  for (size_t s = 0; s < characteristic_speeds[0].size(); ++s) {
88  double local_max_speed = 0.0;
89  for (size_t u = 0; u < characteristic_speeds.size(); ++u) {
90  local_max_speed = std::max(
91  local_max_speed, std::abs(gsl::at(characteristic_speeds, u)[s]));
92  }
93  get(char_speed)[s] = local_max_speed;
94  }
95  }
96  };
97 
98  template <typename NormalDotNumericalFluxTagList, typename VariablesTagList,
99  typename NormalDotFluxTagList>
100  struct call_operator_helper;
101 
102  template <typename... NormalDotNumericalFluxTags, typename... VariablesTags,
103  typename... NormalDotFluxTags>
104  struct call_operator_helper<tmpl::list<NormalDotNumericalFluxTags...>,
105  tmpl::list<VariablesTags...>,
106  tmpl::list<NormalDotFluxTags...>> {
107  static void apply(
108  const gsl::not_null<
109  db::item_type<NormalDotNumericalFluxTags>*>... n_dot_numerical_f,
110  const db::item_type<NormalDotFluxTags>&... n_dot_f_interior,
111  const db::item_type<VariablesTags>&... u_interior,
112  const db::item_type<MaxAbsCharSpeed>& max_abs_speed_interior,
113  const db::item_type<NormalDotFluxTags>&... minus_n_dot_f_exterior,
114  const db::item_type<VariablesTags>&... u_exterior,
115  const db::item_type<MaxAbsCharSpeed>& max_abs_speed_exterior) noexcept {
116  const Scalar<DataVector> max_abs_speed(DataVector(
117  max(get(max_abs_speed_interior), get(max_abs_speed_exterior))));
118  const auto assemble_numerical_flux = [&max_abs_speed](
119  const auto n_dot_num_f, const auto& n_dot_f_in, const auto& u_in,
120  const auto& minus_n_dot_f_ex, const auto& u_ex) noexcept {
121  for (size_t i = 0; i < n_dot_num_f->size(); ++i) {
122  (*n_dot_num_f)[i] = 0.5 * (n_dot_f_in[i] - minus_n_dot_f_ex[i] +
123  get(max_abs_speed) * (u_in[i] - u_ex[i]));
124  }
125  return nullptr;
126  };
127  expand_pack(assemble_numerical_flux(n_dot_numerical_f, n_dot_f_interior,
128  u_interior, minus_n_dot_f_exterior,
129  u_exterior)...);
130  }
131  };
132 
133  public:
134  using options = tmpl::list<>;
135  static constexpr OptionString help = {
136  "Computes the local Lax-Friedrichs numerical flux."};
137 
138  // clang-tidy: google-runtime-references
139  void pup(PUP::er& /*p*/) noexcept {} // NOLINT
140 
141  template <class... Args>
142  void package_data(const Args&... args) const noexcept {
143  package_data_helper<
144  db::split_tag<variables_tag>,
145  db::split_tag<db::add_tag_prefix<::Tags::NormalDotFlux,
146  variables_tag>>>::apply(args...);
147  }
148 
149  template <class... Args>
150  void operator()(const Args&... args) const noexcept {
151  call_operator_helper<
154  db::split_tag<variables_tag>,
155  db::split_tag<db::add_tag_prefix<::Tags::NormalDotFlux,
156  variables_tag>>>::apply(args...);
157  }
158 };
159 
160 } // namespace NumericalFluxes
161 } // namespace dg
Prefix< DataBox_detail::dispatch_add_tag_prefix_impl< Prefix, Tag, Args... >, Args... > add_tag_prefix
Wrap Tag in Prefix<_, Args...>, also wrapping variables tags if Tag is a Tags::Variables.
Definition: DataBoxTag.hpp:533
Prefix indicating a boundary unit normal vector dotted into the flux.
Definition: Prefixes.hpp:76
Definition: InitializeElement.hpp:63
Defines classes and functions for making classes creatable from input files.
Define prefixes for DataBox tags.
Tags for the DataBox inherit from this type.
Definition: DataBoxTag.hpp:65
tmpl::conditional_t< tmpl::size< typename Subitems< TagList, Tag >::type >::value==0, tmpl::list< Tag >, typename Subitems< TagList, Tag >::type > split_tag
Split a tag into its subitems. Tag cannot be a base tag.
Definition: DataBoxTag.hpp:657
constexpr auto apply(F &&f, const DataBox< BoxTags > &box, Args &&... args)
Apply the function f with argument Tags TagsList from DataBox box
Definition: DataBox.hpp:1595
Compute the local Lax-Friedrichs numerical flux.
Definition: LocalLaxFriedrichs.hpp:43
const char *const OptionString
The string used in option structs.
Definition: Options.hpp:27
Defines classes for Tensor.
Stores a collection of function values.
Definition: DataVector.hpp:46
Wraps the template metaprogramming library used (brigand)
typename DataBox_detail::item_type_impl< TagList, Tag >::type item_type
Get the type that is returned by the Tag. If it is a base tag then a TagList must be passed as a seco...
Definition: DataBoxTag.hpp:410
Defines functions and classes from the GSL.
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
Tensor< T, Symmetry<>, index_list<> > Scalar
Scalar type.
Definition: TypeAliases.hpp:21
Require a pointer to not be a nullptr
Definition: ConservativeFromPrimitive.hpp:12
constexpr void expand_pack(Ts &&...) noexcept
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:545
Defines make_with_value.
constexpr T & at(std::array< T, N > &arr, Size index)
Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid...
Definition: Gsl.hpp:124