ryujin 2.1.1 revision ef0fcd4010d109b860652ece4a7b8963fb7d46b1
convenience_macros.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2020 - 2023 by the ryujin authors
4//
5
6#pragma once
7
8#include <compile_time_options.h>
9
10#include <deal.II/base/function.h>
11
16
17namespace ryujin
18{
19#ifndef DOXYGEN
20 namespace
21 {
22 template <int dim, typename Number, typename Callable>
23 class ToFunction : public dealii::Function<dim, Number>
24 {
25 public:
26 ToFunction(const Callable &callable, const unsigned int k)
27 : dealii::Function<dim, Number>(1)
28 , callable_(callable)
29 , k_(k)
30 {
31 }
32
33 Number value(const dealii::Point<dim> &point,
34 unsigned int /*component*/) const override
35 {
36 return callable_(point)[k_];
37 }
38
39 private:
40 const Callable callable_;
41 const unsigned int k_;
42 };
43 } // namespace
44#endif
45
46
70 template <int dim, typename Number, typename Callable>
71 ToFunction<dim, Number, Callable> to_function(const Callable &callable,
72 const unsigned int k)
73 {
74 return {callable, k};
75 }
76
77
81 template <typename FT,
82 int problem_dim = FT::dimension,
83 typename TT = typename FT::value_type,
84 typename T = typename TT::value_type>
85 DEAL_II_ALWAYS_INLINE inline dealii::Tensor<1, problem_dim, T>
86 contract(const FT &flux_ij, const TT &c_ij)
87 {
88 dealii::Tensor<1, problem_dim, T> result;
89 for (unsigned int k = 0; k < problem_dim; ++k)
90 result[k] = flux_ij[k] * c_ij;
91 return result;
92 }
93
94
98 template <typename FT, int problem_dim = FT::dimension>
99 DEAL_II_ALWAYS_INLINE inline FT add(const FT &flux_left_ij,
100 const FT &flux_right_ij)
101 {
102 FT result;
103 for (unsigned int k = 0; k < problem_dim; ++k)
104 result[k] = flux_left_ij[k] + flux_right_ij[k];
105 return result;
106 }
107
108
109} // namespace ryujin
110
111
122#define AssertThrowSIMD(variable, condition, exception) \
123 if constexpr (std::is_same< \
124 typename std::remove_const<decltype(variable)>::type, \
125 double>::value || \
126 std::is_same< \
127 typename std::remove_const<decltype(variable)>::type, \
128 float>::value) { \
129 AssertThrow(condition(variable), exception); \
130 } else { \
131 for (unsigned int k = 0; k < decltype(variable)::size(); ++k) { \
132 AssertThrow(condition((variable)[k]), exception); \
133 } \
134 }
135
136#ifndef DOXYGEN
137namespace
138{
139 template <typename T>
140 class is_dereferenceable
141 {
142 template <typename C>
143 static auto test(...) -> std::false_type;
144
145 template <typename C>
146 static auto test(C *) -> decltype(*std::declval<C>(), std::true_type());
147
148 public:
149 using type = decltype(test<T>(nullptr));
150 static constexpr auto value = type::value;
151 };
152
153 template <typename T, typename>
154 auto dereference(T &t) -> decltype(dereference(*t)) &;
155
156 template <typename T>
157 auto dereference(T &t) -> T &
158 requires(!is_dereferenceable<T>::value)
159 {
160 return t;
161 }
162
163 template <typename T>
164 auto dereference(T &t) -> decltype(*t) &
165 requires is_dereferenceable<T>::value
166 {
167 return *t;
168 }
169} /* anonymous namespace */
170#endif
171
186#define ACCESSOR_READ_ONLY(member) \
187 inline const auto &member() const \
188 { \
189 return dereference(member##_); \
190 }
191
192
198#define ACCESSOR(member) \
199 inline auto &member() \
200 { \
201 return dereference(member##_); \
202 }
203
204
211#define ACCESSOR_READ_ONLY_NO_DEREFERENCE(member) \
212 inline const auto &member() const \
213 { \
214 return member##_; \
215 }
216
217
223#define ASM_LABEL(label) asm("#" label);
224
ToFunction< dim, Number, Callable > to_function(const Callable &callable, const unsigned int k)
DEAL_II_ALWAYS_INLINE FT add(const FT &flux_left_ij, const FT &flux_right_ij)
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, problem_dim, T > contract(const FT &flux_ij, const TT &c_ij)