DUNE-ACFEM (unstable)

boundaryindicator.hh
1#ifndef __DUNE_ACFEM_INDICATORS_BOUNDARYINDICATOR_HH__
2#define __DUNE_ACFEM_INDICATORS_BOUNDARYINDICATOR_HH__
3
4#include "../../common/tostring.hh"
5#include "../../expressions/expressionoperations.hh"
6#include "../../expressions/storage.hh"
7#include "../../expressions/interface.hh"
8#include "../../expressions/terminal.hh"
9#include "../../expressions/traitsdefault.hh"
10#include "../../expressions/optimization.hh"
11
12namespace Dune {
13
14 namespace ACFem {
15
16 namespace BoundaryIndicator {
17
18 using namespace Literals;
19 using Expressions::Storage;
21
39 {};
40
46 template<class T>
48 : BoolConstant<IsBaseOfDecay<BoundaryIndicator, T>::value>
49 {};
50
51 template<class T>
52 struct IsProperOperand
53 : BoolConstant<IsIndicator<T>::value && !Expressions::IsPromotedTopLevel<T>::value>
54 {};
55
57 template<class T0, class T1>
59 : BoolConstant<IsProperOperand<T0>::value && IsProperOperand<T1>::value>
60 {};
61
63 template<class T, std::enable_if_t<(IsIndicator<T>::value && !Expressions::IsClosure<T>::value), int> = 0>
64 constexpr decltype(auto) expressionClosure(T&& t)
65 {
66 return std::forward<T>(t);
67 }
68
69 template<bool Answer = true>
70 struct Constant;
71
72 template<>
73 struct Constant<true>
74 : public Expressions::SelfExpression<Constant<true> >
75 , public BoundaryIndicator
76 , public OneExpression
77 {
78 private:
79 enum { answer = true };
80 public:
81
82 template<class Intersection>
83 bool applies(const Intersection &intersection) const
84 {
85 return answer;
86 }
87
88 static std::string name()
89 {
90 return "\\Chi[true]";
91 }
92 };
93
94 template<>
95 struct Constant<false>
96 : public Expressions::SelfExpression<Constant<false> >
97 , public BoundaryIndicator
98 , public ZeroExpression
99 {
100 private:
101 enum { answer = false };
102 public:
103
104 template<class Intersection>
105 bool applies(const Intersection &intersection) const
106 {
107 return answer;
108 }
109
110 static std::string name()
111 {
112 return "\\Chi[false]";
113 }
114 };
115
117 template<class F, class T>
118 constexpr auto zero(F&&, T&&)
119 {
120 return Constant<false>{};
121 }
122
124 template<class T0, class T1>
125 constexpr auto zero(OperationTraits<LogicalAndOperation>, T0&&, T1&&)
126 {
127 return Constant<false>{};
128 }
129
131 template<class T>
132 constexpr auto one(T&&)
133 {
134 return Constant<true>{};
135 }
136
138 template<class T>
140 {
141 static constexpr bool globalSupport = ExpressionTraits<T>::isOne;
142 static constexpr bool emptySupport = ExpressionTraits<T>::isZero;
143 };
144
147 : public Expressions::SelfExpression<BoundaryIdIndicator>
148 , public BoundaryIndicator
150 {
153 : id_(id)
154 {};
155
157 template<class Intersection>
158 bool applies(const Intersection &intersection) const
159 {
160 return intersection.impl().boundaryId() == id_;
161 }
162
163 std::string name() const
164 {
165 return "\\Chi["+toString(id_)+"]";
166 }
167 protected:
168 const int id_;
169 };
170
172 template<class Indicator>
174 : public Expressions::Storage<OperationTraits<LogicalNotOperation>, Indicator>
175 , public BoundaryIndicator
176 , public std::conditional_t<ExpressionTraits<Indicator>::isZero,
177 OneExpression,
178 std::conditional_t<ExpressionTraits<Indicator>::isOne,
179 ZeroExpression,
180 SemiPositiveExpression> >
181 {
182 using StorageType = Expressions::Storage<OperationTraits<LogicalNotOperation>, Indicator>;
183 using StorageType::operand;
184 using StorageType::operation;
185
186 Complement(Indicator&& indicator)
187 : StorageType(OperationTraits<LogicalNotOperation>{}, std::forward<Indicator>(indicator))
188 {}
189
191 template<class Intersection>
192 bool applies(const Intersection &intersection) const
193 {
194 return !operand(0_c).applies(intersection);
195 }
196
197 std::string name() const
198 {
199 std::string pfx = std::is_reference<Indicator>::value ? (RefersConst<Indicator>::value ? "cref" : "ref") : "";
200 return operationName(operation(), pfx+operand(0_c).name());
201 }
202 };
203
205 template<class T0, class T1>
207 : public Expressions::Storage<OperationTraits<LogicalOrOperation>, T0, T1>
208 , public BoundaryIndicator
209 , public std::conditional_t<ExpressionTraits<T0>::isOne || ExpressionTraits<T1>::isOne,
210 OneExpression,
211 std::conditional_t<ExpressionTraits<T0>::isZero && ExpressionTraits<T1>::isZero,
212 ZeroExpression,
213 SemiPositiveExpression> >
214 {
215 using StorageType = Expressions::Storage<OperationTraits<LogicalOrOperation>, T0, T1>;
216 using StorageType::operand;
217 using StorageType::operation;
218
219 UnionIndicator(T0&& t0, T1&& t1)
220 : StorageType(OperationTraits<LogicalOrOperation>{}, std::forward<T0>(t0), std::forward<T1>(t1))
221 {}
222
224 template<class Intersection>
225 bool applies(const Intersection &intersection) const
226 {
227 return operand(0_c).applies(intersection) || operand(1_c).applies(intersection);
228 }
229
230 std::string name() const
231 {
232 std::string pfxL = std::is_reference<T0>::value ? (RefersConst<T0>::value ? "cref" : "ref") : "";
233 std::string pfxR = std::is_reference<T1>::value ? (RefersConst<T1>::value ? "cref" : "ref") : "";
234
235 return operationName(operation(), pfxL+operand(0_c).name(), pfxR+operand(1_c).name());
236 }
237 };
238
240 template<class T0, class T1>
242 : public Expressions::Storage<OperationTraits<LogicalAndOperation>, T0, T1>
243 , public BoundaryIndicator
244 , public std::conditional_t<ExpressionTraits<T0>::isZero || ExpressionTraits<T1>::isZero,
245 ZeroExpression,
246 std::conditional_t<ExpressionTraits<T0>::isOne && ExpressionTraits<T1>::isOne,
247 OneExpression,
248 SemiPositiveExpression> >
249 {
250 using StorageType = Expressions::Storage<OperationTraits<LogicalAndOperation>, T0, T1>;
251 using StorageType::operand;
252 using StorageType::operation;
253
254 IntersectionIndicator(T0&& t0, T1&& t1)
255 : StorageType(OperationTraits<LogicalAndOperation>{}, std::forward<T0>(t0), std::forward<T1>(t1))
256 {}
257
258 template<class Intersection>
259 bool applies(const Intersection &intersection) const
260 {
261 return operand(0_c).applies(intersection) && operand(1_c).applies(intersection);
262 }
263
264 std::string name() const
265 {
266 std::string pfxL = std::is_reference<T0>::value ? (RefersConst<T0>::value ? "cref" : "ref") : "";
267 std::string pfxR = std::is_reference<T1>::value ? (RefersConst<T1>::value ? "cref" : "ref") : "";
268
269 return operationName(operation(), pfxL+operand(0_c).name(), pfxR+operand(1_c).name());
270 }
271 };
272
274
276
292 template<class T, std::enable_if_t<IsProperOperand<T>::value, int> = 0>
293 constexpr auto operator!(T&& t)
294 {
295 return operate<LogicalNotOperation>(std::forward<T>(t));
296 }
297
299 template<class T, std::enable_if_t<IsProperOperand<T>::value, int> = 0>
300 constexpr auto operate(Expressions::DontOptimize, OperationTraits<LogicalNotOperation>, T&& t)
301 {
302 DUNE_ACFEM_RECORD_OPTIMIZATION;
303
304 return Complement<T>(std::forward<T>(t));
305 }
306
308 template<class T, std::enable_if_t<IsProperOperand<T>::value, int> = 0>
309 auto operator-(T&& t)
310 {
311 return !std::forward<T>(t);
312 }
313
315 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
316 auto operator||(T0&& t0, T1&& t1)
317 {
318 return operate<LogicalOrOperation>(std::forward<T0>(t0), std::forward<T1>(t1));
319 }
320
321 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
322 constexpr auto operate(Expressions::DontOptimize, OperationTraits<LogicalOrOperation>, T0&& t0, T1&& t1)
323 {
324 DUNE_ACFEM_RECORD_OPTIMIZATION;
325
326 return UnionIndicator<T0, T1>(std::forward<T0>(t0), std::forward<T1>(t1));
327 }
328
330 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
331 auto operator+(T0&& t0, T1&& t1)
332 {
333 return std::forward<T0>(t0) || std::forward<T1>(t1);
334 }
335
337 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
338 auto operator&&(T0&& t0, T1&& t1)
339 {
340 return operate<LogicalAndOperation>(std::forward<T0>(t0), std::forward<T1>(t1));
341 }
342
344 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
345 constexpr auto operate(Expressions::DontOptimize, OperationTraits<LogicalAndOperation>, T0&& t0, T1&& t1)
346 {
347 DUNE_ACFEM_RECORD_OPTIMIZATION;
348
349 return IntersectionIndicator<T0, T1>(std::forward<T0>(t0), std::forward<T1>(t1));
350 }
351
353 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
354 auto operator*(T0&& t0, T1&& t1)
355 {
356 return std::forward<T0>(t0) && std::forward<T1>(t1);
357 }
358
360 template<class T0, class T1, std::enable_if_t<AreProperOperands<T0, T1>::value, int> = 0>
361 auto operator-(T0&& t0, T1&& t1)
362 {
363 return std::forward<T0>(t0) && !std::forward<T1>(t1);
364 }
365
367
369
370 } // NS BoundaryIndicator
371
373 using EmptyBoundaryIndicator = BoundaryIndicator::Constant<false>;
374
376 using EntireBoundaryIndicator = BoundaryIndicator::Constant<true>;
377
379 template<class T>
381
383 template<class T>
384 using IsProperBoundaryIndicator = BoundaryIndicator::IsProperOperand<T>;
385
388
391
392 } // ACFem::
393
394} // Dune::
395
396#endif // __DUNE_ACFEM_INDICATORS_BOUNDARYINDICATOR_HH__
constexpr decltype(auto) expressionClosure(T &&t)
BoundaryIndicators do not need a closure.
Definition: boundaryindicator.hh:64
OptimizeTag< 0 > DontOptimize
Bottom level is overloaded to do nothing.
Definition: optimizationbase.hh:74
std::string operationName(F &&f, const std::string &arg)
Verbose print of an operation, helper function to produce noise.
Definition: operationtraits.hh:601
constexpr auto one(T &&t)
Use the one fraction as canonical zero element for scalars.
Definition: constantoperations.hh:88
constexpr auto zero(T &&t)
Use the zero fraction as canonical zero element for scalars.
Definition: constantoperations.hh:80
auto operator||(T0 &&t0, T1 &&t1)
Union of two indicators.
Definition: boundaryindicator.hh:316
auto operator&&(T0 &&t0, T1 &&t1)
Intersection of two indicators.
Definition: boundaryindicator.hh:338
auto operator-(T0 &&t0, T1 &&t1)
Difference in the sense of .
Definition: boundaryindicator.hh:361
auto operator+(T0 &&t0, T1 &&t1)
Union of two indicators.
Definition: boundaryindicator.hh:331
constexpr auto operator!(T &&t)
Boolean negation, take the complement.
Definition: boundaryindicator.hh:293
constexpr auto operate(Expressions::DontOptimize, OperationTraits< LogicalAndOperation >, T0 &&t0, T1 &&t1)
Definition: boundaryindicator.hh:345
integral_constant< T, V > Constant
Short-cut for any integral constant.
Definition: types.hh:40
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
BoolConstant<(std::is_const< T >::value||std::is_const< std::remove_reference_t< T > >::value)> RefersConst
TrueType if const or a reference to a const.
Definition: types.hh:133
BoundaryIndicator::Constant< false > EmptyBoundaryIndicator
A boundary indicator applying to no part of the boundary.
Definition: boundaryindicator.hh:373
BoundaryIndicator::Constant< true > EntireBoundaryIndicator
A boundary indicator applying to all parts of the boundary.
Definition: boundaryindicator.hh:376
BoundaryIndicator::IsProperOperand< T > IsProperBoundaryIndicator
Indentify a boundary indicator after type-normalization.
Definition: boundaryindicator.hh:384
Definition: boundaryindicator.hh:60
Apply to boundary segments which carry the respective id.
Definition: boundaryindicator.hh:150
bool applies(const Intersection &intersection) const
Definition: boundaryindicator.hh:158
BoundaryIdIndicator(int id)
Construct the indicator with the given id.
Definition: boundaryindicator.hh:152
Boundary indicators need to inherit this tag-class in order to signal that they are boundary indicato...
Definition: boundaryindicator.hh:39
Turn any boundary-indicator into its complement.
Definition: boundaryindicator.hh:181
bool applies(const Intersection &intersection) const
Definition: boundaryindicator.hh:192
Paraphrase isOne and isZero to indicator function talk.
Definition: boundaryindicator.hh:140
Intersection of two indicators, apply iff both apply.
Definition: boundaryindicator.hh:249
TrueType if T is a BoundaryIndicator.
Definition: boundaryindicator.hh:49
Union of two indicators, apply to the union of both boundary parts.
Definition: boundaryindicator.hh:214
bool applies(const Intersection &intersection) const
Definition: boundaryindicator.hh:225
Default expression traits definition is a recursion in order to ease disambiguation.
Definition: expressiontraits.hh:54
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
A tag structure which can be attached as base-class to expressions modelling a 1 (in a field,...
Definition: tags.hh:158
Greater equal 0 expression.
Definition: tags.hh:110
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)