DUNE-ACFEM (2.5.1)

boundarysupportedfunction.hh
1 #ifndef __DUNE_ACFEM_BOUNDARY_SUPPORTED_FUNCTION_HH__
2 #define __DUNE_ACFEM_BOUNDARY_SUPPORTED_FUNCTION_HH__
3 
4 #include <dune/fem/function/common/function.hh>
5 
6 #include "../models/boundaryindicator.hh"
7 #include "../common/stringhelper.hh"
8 #include "../functions/gridfunctionexpressionbase.hh"
9 
10 namespace Dune
11 {
12 
13  namespace ACFem
14  {
15 
35  {};
36 
41  {};
42 
43  // forward
44  template<class GridFunction, class Indicator = EntireBoundaryIndicatorType>
46 
51  template<class F, bool bndrySupport = std::is_base_of<HasBoundarySupport, F>::value>
53 
61  template<class F>
62  struct BoundaryFunctionTraits<F, true>
63  {
64  enum {
65  hasBoundarySupport = true
66  };
67  typedef F FunctionType;
68  typedef typename F::FunctionSpaceType FunctionSpaceType;
69  typedef typename F::IndicatorType IndicatorType;
70  typedef typename F::LocalFunctionType LocalFunctionType;
71  typedef typename F::GridPartType GridPartType;
72  typedef typename F::EntityType EntityType;
73  typedef typename GridPartType::IntersectionType IntersectionType;
74 
75  enum {
77  globalSupport = std::is_same<IndicatorType, EntireBoundaryIndicatorType>::value
78  };
79 
80  template<class OtherIndicator>
81  struct ProductIndicator
82  {
83  typedef
84  typename std::decay<decltype(*std::declval<IndicatorType>()
85  &&
86  *std::declval<OtherIndicator>())>::type
87  Type;
88 
89  // form zero expressions, when appropriate
90  enum {
91  emptySupport = ExpressionTraits<Type>::isZero,
92  globalSupport = std::is_same<Type, EntireBoundaryIndicatorType>::value
93  };
94 
95  typedef BoundarySupportedFunction<FunctionType, OtherIndicator> BoundaryFunctionType;
96  typedef typename
97  std::conditional<emptySupport,
98  GridFunctionExpression<FunctionSpaceType, BoundaryFunctionType, ZeroExpression>,
99  GridFunctionExpression<FunctionSpaceType, BoundaryFunctionType, ExpressionTemplate>
100  >::type
101  ExpressionBaseType;
102  };
103 
109  static void init(LocalFunctionType& lf,
110  const EntityType& entity,
111  const IntersectionType& intersection)
112  {
113  lf.init(entity, intersection);
114  }
115 
118  static bool supported(const LocalFunctionType& lf)
119  {
120  return globalSupport || (!emptySupport && lf.supported());
121  }
122 
126  static typename F::IndicatorType indicator(const F& f)
127  {
128  return f.indicator();
129  }
130  };
131 
137  template<class F>
138  struct BoundaryFunctionTraits<F, false>
139  {
140  enum {
141  hasBoundarySupport = false
142  };
143  typedef F FunctionType;
144  typedef typename F::FunctionSpaceType FunctionSpaceType;
145  typedef EntireBoundaryIndicatorType IndicatorType;
146  typedef typename F::LocalFunctionType LocalFunctionType;
147  typedef typename F::GridPartType GridPartType;
148 
150  typedef typename F::EntityType EntityType;
151 
153  typedef typename GridPartType::IntersectionType IntersectionType;
154 
155  enum {
156  emptySupport = false,
157  globalSupport = true
158  };
159 
160  template<class OtherIndicator>
161  struct ProductIndicator
162  {
163  typedef OtherIndicator Type;
164 
165  // Convenience
166  enum {
167  emptySupport = std::is_same<Type, EmptyBoundaryIndicatorType>::value,
168  globalSupport = std::is_same<Type, EntireBoundaryIndicatorType>::value
169  };
170  typedef BoundarySupportedFunction<FunctionType, OtherIndicator> BoundaryFunctionType;
171  typedef typename
172  std::conditional<emptySupport,
173  GridFunctionExpression<FunctionSpaceType, BoundaryFunctionType, ZeroExpression>,
174  GridFunctionExpression<FunctionSpaceType, BoundaryFunctionType, ExpressionTemplate>
175  >::type
176  ExpressionBaseType;
177  };
178 
180  static void init(LocalFunctionType& lf,
181  const EntityType& entity,
182  const IntersectionType& intersection)
183  {
184  lf.init(entity);
185  }
186 
188  static bool supported(const LocalFunctionType& lf)
189  {
190  return true;
191  }
192 
194  static IndicatorType indicator(const F& ignored)
195  {
196  return EntireBoundaryIndicatorType();
197  }
198  };
199 
200 
230  template<class GridFunction, class Indicator>
232  : public BoundaryFunctionTraits<GridFunction>::template ProductIndicator<Indicator>::ExpressionBaseType,
233  public HasBoundarySupport
234  {
237  typedef typename
238  BoundaryTraitsType::template ProductIndicator<Indicator>::ExpressionBaseType
239  ExpressionBaseType;
240  class LocalFunction;
241  using ExpressionBaseType::expressionName_;
242 
243  typedef typename BoundaryTraitsType::IndicatorType InnerIndicatorType;
244  public:
247 
249  typedef
250  typename std::decay<decltype(*std::declval<Indicator>()
251  &&
252  *std::declval<InnerIndicatorType>())>::type
254  typedef Indicator OuterIndicatorType;
255 
256  enum {
257  emptySupport = std::is_same<IndicatorType, EmptyBoundaryIndicatorType>::value,
258  globalSupport = std::is_same<IndicatorType, EntireBoundaryIndicatorType>::value
259  };
260 
262  typedef GridFunction GridFunctionType;
263 
265  typedef typename GridFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
266  typedef typename GridFunctionType::FunctionSpaceType FunctionSpaceType;
267  typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType;
268 
270  typedef typename DiscreteFunctionSpaceType::GridType GridType;
271 
273  typedef typename DiscreteFunctionSpaceType::DomainFieldType DomainFieldType;
275  typedef typename DiscreteFunctionSpaceType::RangeFieldType RangeFieldType;
277  typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
279  typedef typename DiscreteFunctionSpaceType::RangeType RangeType;
281  typedef typename DiscreteFunctionSpaceType::JacobianRangeType JacobianRangeType;
283  typedef typename DiscreteFunctionSpaceType::HessianRangeType HessianRangeType;
284 
285  typedef typename GridFunctionType::EntityType EntityType;
286  typedef typename GridPartType::IntersectionType IntersectionType;
287 
288  // Do not define a default argument for indicator, otherwise
289  // this could result in automatic type-casts from any function into this type.
290  BoundarySupportedFunction(const Fem::Function<FunctionSpaceType, GridFunctionType>& function,
291  const BoundaryIndicatorInterface<Indicator>& indicator)
292  : gridFunction_(function),
293  outerIndicator_(indicator),
294  indicator_(*asImp(outerIndicator()) && *BoundaryTraitsType::indicator(gridFunction_()))
295  {
296  expressionName_ = makeName(gridFunction_().name());
297  }
298 
300  void evaluate(const DomainType &global, RangeType &result) const
301  {
302  if (emptySupport) {
303  result = 0.;
304  return;
305  }
306  function().evaluate(global, result);
307  }
308 
310  void jacobian(const DomainType &global, JacobianRangeType &result) const
311  {
312  if (emptySupport) {
313  result = 0.;
314  return;
315  }
316  function().jacobian(global, result);
317  }
318 
320  void hessian(const DomainType &global, HessianRangeType &result) const
321  {
322  if (emptySupport) {
323  result = 0.;
324  return;
325  }
326  function().hessian(global, result);
327  }
328 
335  const LocalFunctionType localFunction(const EntityType &entity) const
336  {
337  return LocalFunctionType(entity, *this);
338  }
339 
346  LocalFunctionType localFunction(const EntityType &entity)
347  {
348  return LocalFunctionType(entity, *this);
349  }
350 
355  const LocalFunctionType localFunction(const EntityType& entity,
356  const IntersectionType &intersection) const
357  {
358  return LocalFunctionType(entity, intersection, *this);
359  }
360 
365  LocalFunctionType localFunction(const EntityType& entity,
366  const IntersectionType &intersection)
367  {
368  return LocalFunctionType(entity, intersection, *this);
369  }
370 
371  const DiscreteFunctionSpaceType& space() const
372  {
373  return function().space();
374  }
375 
376  const GridPartType& gridPart() const
377  {
378  return function().gridPart();
379  }
380 
381  const GridFunctionType& function() const
382  {
383  return gridFunction_();
384  }
385 
386  const IndicatorType& indicator() const
387  {
388  return indicator_();
389  }
390 
391  const OuterIndicatorType& outerIndicator() const
392  {
393  return outerIndicator_();
394  }
395 
396  protected:
397  // Remove any outer redundant parenthesis and wrap into "B(.)"
398  static std::string makeName(const std::string& name)
399  {
400  std::string result(name);
401  trimParenthesis(result);
402  result = "B(" + result + ")";
403  return result;
404  }
405 
406  ExpressionStorage<GridFunctionType> gridFunction_;
407  ExpressionStorage<OuterIndicatorType> outerIndicator_;
408  ExpressionStorage<IndicatorType> indicator_;
409  };
410 
415  template<class GridFunction, class Indicator>
416  class BoundarySupportedFunction<GridFunction, Indicator>::LocalFunction
417  {
418  public:
419  typedef GridFunction GridFunctionType;
420  typedef typename GridFunctionType::FunctionSpaceType FunctionSpaceType;
421  typedef typename GridFunctionType::LocalFunctionType BulkLocalFunctionType;
422  typedef Indicator IndicatorType;
424 
425  enum {
427  emptySupport = DiscreteFunctionType::emptySupport,
429  globalSupport = DiscreteFunctionType::globalSupport
430  };
431 
432  typedef typename DiscreteFunctionType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
433  typedef typename DiscreteFunctionType::GridPartType GridPartType;
434  typedef typename DiscreteFunctionType::EntityType EntityType;
435  typedef typename DiscreteFunctionType::IntersectionType IntersectionType;
436 
437  enum {
438  dimRange = DiscreteFunctionSpaceType::dimRange,
439  dimDomain = GridPartType::dimensionworld,
440  dimension = GridPartType::dimension
441  };
442 
444  typedef typename DiscreteFunctionSpaceType::DomainFieldType DomainFieldType;
446  typedef typename DiscreteFunctionSpaceType::RangeFieldType RangeFieldType;
448  typedef typename DiscreteFunctionSpaceType::DomainType DomainType;
450  typedef typename DiscreteFunctionSpaceType::RangeType RangeType;
452  typedef typename DiscreteFunctionSpaceType::JacobianRangeType JacobianRangeType;
454  typedef typename DiscreteFunctionSpaceType::HessianRangeType HessianRangeType;
455 
457  LocalFunction(const EntityType& entity, const DiscreteFunctionType& df)
458  : intersection_(0),
459  df_(df),
460  localFunction_(df_.function().localFunction(entity)),
461  supported_(true)
462  {}
463 
466  : intersection_(0),
467  df_(df),
468  localFunction_(df_.function()),
469  supported_(true)
470  {}
471 
473  LocalFunction(const EntityType& entity,
474  const IntersectionType& intersection,
475  const DiscreteFunctionType& df)
476  : df_(df),
477  localFunction_(BulkLocalFunctionType(df_.function()))
478  {
479  init(entity, intersection);
480  }
481 
488  template<class PointType>
489  void evaluate(const PointType &x, RangeType &ret) const
490  {
491  if (!supported()) {
492  ret = 0;
493  } else {
494  localFunction_.evaluate(x, ret);
495  }
496  }
497 
504  template<class PointType>
505  void jacobian(const PointType &x, JacobianRangeType &ret) const
506  {
507  if (!supported()) {
508  ret = 0;
509  } else {
510  localFunction_.jacobian(x, ret);
511  }
512  }
513 
520  template<class PointType>
521  void hessian(const PointType &x, HessianRangeType &ret) const
522  {
523  if (!supported()) {
524  ret = 0;
525  } else {
526  localFunction_.hessian(x, ret);
527  }
528  }
529 
531  template<class QuadratureType, class VectorType>
532  void evaluateQuadrature(const QuadratureType& quadrature, VectorType& values) const
533  {
534  assert(values.size() == quadrature.nop());
535  DiscreteFunctionType::evaluateQuadratureImp(*this, quadrature, values, values[0]);
536  }
537 
539  int order() const
540  {
541  return localFunction_.order();
542  }
543 
545  void init(const EntityType &entity)
546  {
547  localFunction_.init(entity);
548  supported_ = true;
549  }
550 
552  void init(const EntityType& entity, const IntersectionType& isect)
553  {
554  intersection_ = &isect;
555  BoundaryTraitsType::init(localFunction_, entity, intersection());
556  supported_ = globalSupport || (!emptySupport && df_.indicator().applies(intersection()));
557  }
558 
559  const EntityType& entity() const
560  {
561  localFunction_.entity();
562  }
563 
564  const IntersectionType& intersection() const
565  {
566  assert(intersection_ != 0);
567  return *intersection_;
568  }
569 
578  bool supported() const
579  {
580  return globalSupport || (!emptySupport && supported_);
581  }
582 
583  protected:
584  const IntersectionType* intersection_;
585  const DiscreteFunctionType& df_;
586  BulkLocalFunctionType localFunction_;
587  bool supported_;
588  };
589 
602  template<class GridFunction, class Indicator = EntireBoundaryIndicatorType>
604  boundarySupportedFunction(const Fem::Function<typename GridFunction::FunctionSpaceType,
605  GridFunction>& f,
607  c = EntireBoundaryIndicatorType())
608  {
610 
611  return FunctionType(f, c);
612  }
613 
615  template<class GridFunction, class Indicator>
616  BoundarySupportedFunction<GridFunction, Indicator>
618  const EntireBoundaryIndicatorType& = EntireBoundaryIndicatorType())
619  {
620  return f;
621  }
622 
629  } // ACFem::
630 
631 } // Dune::
632 
633 #endif // __DUNE_ACFEM_BOUNDARY_SUPPORTED_FUNCTION_HH__
A simple interface class for a boundary-indicator.
Definition: boundaryindicator.hh:41
LocalFunction object which takes the value of a indicator into account.
Definition: boundarysupportedfunction.hh:417
A function with potentially partial support on the boundary.
Definition: boundarysupportedfunction.hh:234
static void trimParenthesis(std::string &name)
Remove any outer redundant parenthesis.
Definition: stringhelper.hh:40
const Implementation & asImp(const Fem::BartonNackmanInterface< Interface, Implementation > &arg)
Up-cast to the implementation for any Fem::BartonNackmanInterface.
Definition: expressionoperations.hh:71
BoundarySupportedFunction< GridFunction, Indicator > boundarySupportedFunction(const Fem::Function< typename GridFunction::FunctionSpaceType, GridFunction > &f, const BoundaryIndicatorInterface< Indicator > &c=EntireBoundaryIndicatorType())
Generate a function with partial support on the boundary.
Definition: boundarysupportedfunction.hh:604
static void init(LocalFunctionType &lf, const EntityType &entity, const IntersectionType &intersection)
For BoundarySupportedFunction's we pass the intersection as well as the bulk entity on to the local f...
Definition: boundarysupportedfunction.hh:109
DiscreteFunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: boundarysupportedfunction.hh:283
LocalFunction(const EntityType &entity, const DiscreteFunctionType &df)
Bulk entity constructor.
Definition: boundarysupportedfunction.hh:457
DiscreteFunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: boundarysupportedfunction.hh:279
void hessian(const PointType &x, HessianRangeType &ret) const
Evaluate Hessian of local function.
Definition: boundarysupportedfunction.hh:521
GridPartType::IntersectionType IntersectionType
Type of Intersection.
Definition: boundarysupportedfunction.hh:153
const LocalFunctionType localFunction(const EntityType &entity, const IntersectionType &intersection) const
Initialize a wrapped local function object for the given intersection.
Definition: boundarysupportedfunction.hh:355
static bool supported(const LocalFunctionType &lf)
Decide if we are supported on this IntersectionType.
Definition: boundarysupportedfunction.hh:118
DiscreteFunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: boundarysupportedfunction.hh:444
LocalFunctionType localFunction(const EntityType &entity, const IntersectionType &intersection)
Initialize a wrapped local function object for the given intersection.
Definition: boundarysupportedfunction.hh:365
static IndicatorType indicator(const F &ignored)
Not boundary-supported: implicity everywhere supported.
Definition: boundarysupportedfunction.hh:194
bool supported() const
Return true if potentially non-zero.
Definition: boundarysupportedfunction.hh:578
void jacobian(const PointType &x, JacobianRangeType &ret) const
Evaluate Jacobian of local function.
Definition: boundarysupportedfunction.hh:505
void init(const EntityType &entity)
Bulk-entity initialization.
Definition: boundarysupportedfunction.hh:545
DiscreteFunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: boundarysupportedfunction.hh:446
LocalFunctionType localFunction(const EntityType &entity)
Generate an ordinary local-function object which is ignorant of the value of the boundary-indicator,...
Definition: boundarysupportedfunction.hh:346
DiscreteFunctionSpaceType::RangeFieldType RangeFieldType
range type (from function space)
Definition: boundarysupportedfunction.hh:275
void jacobian(const DomainType &global, JacobianRangeType &result) const
evaluate function on local coordinate local
Definition: boundarysupportedfunction.hh:310
DiscreteFunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: boundarysupportedfunction.hh:452
DiscreteFunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: boundarysupportedfunction.hh:277
void init(const EntityType &entity, const IntersectionType &isect)
Intersection initialization.
Definition: boundarysupportedfunction.hh:552
LocalFunction(const DiscreteFunctionType &df)
Bulk entity constructor.
Definition: boundarysupportedfunction.hh:465
int order() const
Return a bound on or suggestion for the piece-wise polynomial order.
Definition: boundarysupportedfunction.hh:539
LocalFunction LocalFunctionType
Type of local function to export.
Definition: boundarysupportedfunction.hh:246
DiscreteFunctionSpaceType::HessianRangeType HessianRangeType
hessian type (from function space)
Definition: boundarysupportedfunction.hh:454
void evaluateQuadrature(const QuadratureType &quadrature, VectorType &values) const
evaluate function or jacobian of function for given quadrature
Definition: boundarysupportedfunction.hh:532
std::decay< decltype(*std::declval< Indicator >) &&*std::declval< InnerIndicatorType >))>::type IndicatorType
Resulting Boundary indicator type.
Definition: boundarysupportedfunction.hh:253
const LocalFunctionType localFunction(const EntityType &entity) const
Generate an ordinary local-function object which is ignorant of the value of the boundary-indicator,...
Definition: boundarysupportedfunction.hh:335
F::EntityType EntityType
Type of Entity.
Definition: boundarysupportedfunction.hh:150
static void init(LocalFunctionType &lf, const EntityType &entity, const IntersectionType &intersection)
Call the ordinary init-method for not BoundarySupportedFunction's.
Definition: boundarysupportedfunction.hh:180
void hessian(const DomainType &global, HessianRangeType &result) const
evaluate function on local coordinate local
Definition: boundarysupportedfunction.hh:320
void evaluate(const DomainType &global, RangeType &result) const
evaluate function on local coordinate local
Definition: boundarysupportedfunction.hh:300
GridFunction GridFunctionType
Type of wrapped grid-function.
Definition: boundarysupportedfunction.hh:262
DiscreteFunctionSpaceType::GridType GridType
type of grid
Definition: boundarysupportedfunction.hh:270
void evaluate(const PointType &x, RangeType &ret) const
Evaluate local function.
Definition: boundarysupportedfunction.hh:489
DiscreteFunctionSpaceType::RangeType RangeType
range type (from function space)
Definition: boundarysupportedfunction.hh:450
static bool supported(const LocalFunctionType &lf)
Not boundary-supported: implicity everywhere supported.
Definition: boundarysupportedfunction.hh:188
static F::IndicatorType indicator(const F &f)
Return the underlying BoundarySupportedFunction's indicator.
Definition: boundarysupportedfunction.hh:126
DiscreteFunctionSpaceType::JacobianRangeType JacobianRangeType
jacobian type (from function space)
Definition: boundarysupportedfunction.hh:281
DiscreteFunctionSpaceType::DomainType DomainType
domain type (from function space)
Definition: boundarysupportedfunction.hh:448
DiscreteFunctionSpaceType::DomainFieldType DomainFieldType
domain type (from function space)
Definition: boundarysupportedfunction.hh:273
LocalFunction(const EntityType &entity, const IntersectionType &intersection, const DiscreteFunctionType &df)
Boundary intersection constructor.
Definition: boundarysupportedfunction.hh:473
Helper traits in order to treat function w/o dedicated boundary support in the same way,...
Definition: boundarysupportedfunction.hh:52
A traits class in order to collect properties of expressions.
Definition: expressionoperations.hh:465
Tag-structure to indicate additional functionality.
Definition: boundarysupportedfunction.hh:35
Negative tag-structure for use with std::conditional, complementary to HasBoundarySupport.
Definition: boundarysupportedfunction.hh:41
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)