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 
12 namespace 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>
47  struct IsIndicator
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
149  , public SemiPositiveExpression
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>
173  struct Complement
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.80.0 (Apr 30, 22:37, 2024)