ryujin 2.1.1 revision c38afcfdec63b34961924f05408760247496a1f0
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 <deal.II/base/function.h>
9
14
15namespace ryujin
16{
17#ifndef DOXYGEN
18 namespace
19 {
20 template <int dim, typename Number, typename Callable>
21 class ToFunction : public dealii::Function<dim, Number>
22 {
23 public:
24 ToFunction(const Callable &callable, const unsigned int k)
25 : dealii::Function<dim, Number>(1)
26 , callable_(callable)
27 , k_(k)
28 {
29 }
30
31 Number value(const dealii::Point<dim> &point,
32 unsigned int /*component*/) const override
33 {
34 return callable_(point)[k_];
35 }
36
37 private:
38 const Callable callable_;
39 const unsigned int k_;
40 };
41 } // namespace
42#endif
43
44
68 template <int dim, typename Number, typename Callable>
69 ToFunction<dim, Number, Callable> to_function(const Callable &callable,
70 const unsigned int k)
71 {
72 return {callable, k};
73 }
74
75
79 template <typename FT,
80 int problem_dim = FT::dimension,
81 typename TT = typename FT::value_type,
82 typename T = typename TT::value_type>
83 DEAL_II_ALWAYS_INLINE inline dealii::Tensor<1, problem_dim, T>
84 contract(const FT &flux_ij, const TT &c_ij)
85 {
86 dealii::Tensor<1, problem_dim, T> result;
87 for (unsigned int k = 0; k < problem_dim; ++k)
88 result[k] = flux_ij[k] * c_ij;
89 return result;
90 }
91
92
96 template <typename FT, int problem_dim = FT::dimension>
97 DEAL_II_ALWAYS_INLINE inline FT add(const FT &flux_left_ij,
98 const FT &flux_right_ij)
99 {
100 FT result;
101 for (unsigned int k = 0; k < problem_dim; ++k)
102 result[k] = flux_left_ij[k] + flux_right_ij[k];
103 return result;
104 }
105
106
107} // namespace ryujin
108
109
120#define AssertThrowSIMD(variable, condition, exception) \
121 if constexpr (std::is_same< \
122 typename std::remove_const<decltype(variable)>::type, \
123 double>::value || \
124 std::is_same< \
125 typename std::remove_const<decltype(variable)>::type, \
126 float>::value) { \
127 AssertThrow(condition(variable), exception); \
128 } else { \
129 for (unsigned int k = 0; k < decltype(variable)::size(); ++k) { \
130 AssertThrow(condition((variable)[k]), exception); \
131 } \
132 }
133
134#ifndef DOXYGEN
135namespace
136{
137 template <typename T>
138 class is_dereferenceable
139 {
140 template <typename C>
141 static auto test(...) -> std::false_type;
142
143 template <typename C>
144 static auto test(C *) -> decltype(*std::declval<C>(), std::true_type());
145
146 public:
147 using type = decltype(test<T>(nullptr));
148 static constexpr auto value = type::value;
149 };
150
151 template <typename T, typename>
152 auto dereference(T &t) -> decltype(dereference(*t)) &;
153
154 template <
155 typename T,
156 typename = typename std::enable_if<!is_dereferenceable<T>::value>::type>
157 auto dereference(T &t) -> T &
158 {
159 return t;
160 }
161
162 template <
163 typename T,
164 typename = typename std::enable_if<is_dereferenceable<T>::value>::type>
165 auto dereference(T &t) -> decltype(*t) &
166 {
167 return *t;
168 }
169} /* anonymous namespace */
170#endif
171
186#define ACCESSOR_READ_ONLY(member) \
187 inline 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)