DUNE-ACFEM (unstable)

neumannmodel.hh
1 #ifndef __DUNE_ACFEM_MODELS_MODULES_NEUMANNMODEL_HH__
2 #define __DUNE_ACFEM_MODELS_MODULES_NEUMANNMODEL_HH__
3 
4 #include "../../expressions/expressionoperations.hh"
5 #include "../../functions/localfunctiontraits.hh"
6 #include "../../functions/functiontraits.hh"
7 
8 #include "../indicators/boundaryindicator.hh"
9 #include "../modelbase.hh"
10 
11 namespace Dune {
12 
13  namespace ACFem::PDEModel {
14 
44  template<class GridFunction, class Indicator = EntireBoundaryIndicator>
46  : public ModelBase<typename std::decay_t<GridFunction>::FunctionSpaceType>
47  , public Expressions::SelfExpression<NeumannBoundaryModel<GridFunction, Indicator> >
48  , public MPL::UniqueTags<ConditionalType<ExpressionTraits<GridFunction>::isVolatile
49  ||
50  ExpressionTraits<Indicator>::isVolatile,
51  VolatileExpression, void>,
52  ConditionalType<IsConstantExprArg<GridFunction>::value
53  &&
54  IsConstantExprArg<Indicator>::value,
55  ConstantExpression, void>,
56  ConditionalType<IsTypedValue<GridFunction>::value
57  &&
58  IsTypedValue<Indicator>::value,
59  TypedValueExpression, void> >
60  {
62  "GridFunction must provide a local function");
63 
66  protected:
67  using LocalFunctionType = Fem::ConstLocalFunction<std::decay_t<GridFunction> >;
68  public:
69  using GridFunctionType = GridFunction;
70  using IndicatorType = Indicator;
71  using DomainType = typename BaseType::DomainType;
72  using RangeType = typename BaseType::RangeType;
73  using BoundaryConditionsType = typename BaseType::BoundaryConditionsType;
74  using BaseType::dimRange;
75 
76  template<class FunctionArg, class IndicatorArg,
77  std::enable_if_t<(std::is_constructible<LocalFunctionType, FunctionArg>::value
78  && std::is_constructible<Indicator, IndicatorArg>::value
79  && !std::is_default_constructible<IndicatorArg>::value
80  ), int> = 0>
81  NeumannBoundaryModel(FunctionArg&& values,
82  IndicatorArg&& indicator,
83  const std::string& name = "")
84  : localFunction_(std::forward<FunctionArg>(values))
85  , indicator_(std::forward<IndicatorArg>(indicator))
86  , supported_(false, std::bitset<dimRange>())
87  , name_(name == "" ? "Neumann(" + localFunction_.gridFunction().name() + ")" : name)
88  {}
89 
90  template<class FunctionArg, class IndicatorArg,
91  std::enable_if_t<(std::is_constructible<LocalFunctionType, FunctionArg>::value
92  && std::is_constructible<Indicator, IndicatorArg>::value
93  && std::is_default_constructible<IndicatorArg>::value
94  ), int> = 0>
95  NeumannBoundaryModel(FunctionArg&& values,
96  IndicatorArg&& indicator = IndicatorArg(),
97  const std::string& name = "")
98  : localFunction_(std::forward<FunctionArg>(values))
99  , indicator_(std::forward<IndicatorArg>(indicator))
100  , supported_(false, std::bitset<dimRange>())
101  , name_(name == "" ? "Neumann(" + localFunction_.gridFunction().name() + ")" : name)
102  {}
103 
105  std::string name() const
106  {
107  return name_;
108  }
109 
111  template<class Entity>
112  void bind(const Entity& entity)
113  {
115  localFunction_.bind(entity);
116  }
117  }
118 
120  void unbind()
121  {
123  localFunction_.unbind();
124  }
125  }
126 
128  template<class Intersection>
129  auto classifyBoundary(const Intersection& intersection)
130  {
131  supported_.first = IndicatorTraits<IndicatorType>::globalSupport || indicator_.applies(intersection);
132  return supported_;
133  }
134 
149  template<class Quadrature>
151  const DomainType& unitOuterNormal) const
152  {
154  &&
155  (IndicatorTraits<Indicator>::globalSupport || supported_.first)) {
156  RangeType result;
157  localFunction_.evaluate(x, result);
158  return -result;
159  }
160  return RangeType(0.);
161  }
162 
163  protected:
164  LocalFunctionType localFunction_;
165  IndicatorType indicator_;
166  BoundaryConditionsType supported_;
167  std::string name_;
168  };
169 
171 
184  template<class Fct, class Indicator = EntireBoundaryIndicator,
187  ), int> = 0>
188  constexpr auto
189  neumannBoundaryModel(Fct&& values,
190  Indicator&& where = std::decay_t<Indicator>{},
191  const std::string& name = "")
192  {
193  return expressionClosure(NeumannBoundaryModel<Fct, Indicator>(std::forward<Fct>(values), std::forward<Indicator>(where), name));
194  }
195 
196  template<class Fct, class Indicator = EntireBoundaryIndicator,
197  std::enable_if_t<GridFunction::HasRegularity<Fct, 1UL>::value, int> = 0>
198  constexpr auto
199  neumannBoundaryModel(Fct&& values,
200  Indicator&& where = std::decay_t<Indicator>{},
201  const std::string& name = "")
202  {
203  using namespace Literals;
204  return neumannBoundaryModel(gridFunction(values.gridPart(), std::forward<Fct>(values), 0_c),
205  std::forward<Indicator>(where),
206  name);
207  }
208 
209  template<class Fct, class Indicator = EntireBoundaryIndicator,
210  std::enable_if_t<ExpressionTraits<Fct>::isZero || ExpressionTraits<Indicator>::isZero, int> = 0>
211  constexpr auto
212  neumannBoundaryModel(Fct&& values,
213  Indicator&& where = std::decay_t<Indicator>{},
214  const std::string& name = "")
215  {
216  return zeroModel(values);
217  }
218 
220 
222 
224 
225  } // namespace ACFem::PDEModel::
226 
227  namespace ACFem {
228 
230 
231  }
232 
233 } //Namespace Dune
234 
235 
236 #endif // __DUNE_ACFEM_MODELS_MODULES_NEUMANNMODEL_HH__
A Neumann-boundary model.
Definition: neumannmodel.hh:60
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
std::is_base_of< Tag, std::decay_t< A > > HasTag
Evaluate to std::true_type if std::decay_t<A> is derived from Tag, otherwise to std::false_type.
Definition: tags.hh:176
auto gridFunction(const GridPart &gridPart, T &&t, IndexConstant< MaxOrder > maxOrder=IndexConstant< MaxOrder >{}, IndexConstant< IndeterminateId > id=IndexConstant< IndeterminateId >{})
Generate a BindableGridFunction which wraps a copy of T.
Definition: gridfunction.hh:23
std::string name() const
Definition: neumannmodel.hh:105
void bind(const Entity &entity)
Definition: neumannmodel.hh:112
void unbind()
Definition: neumannmodel.hh:120
auto classifyBoundary(const Intersection &intersection)
Definition: neumannmodel.hh:129
auto zeroModel(const T &t, const std::string &name, F closure=F{})
Generate a zero model fitting the specified object.
Definition: zeromodel.hh:77
RangeType robinFlux(const QuadraturePoint< Quadrature > &x, const DomainType &unitOuterNormal) const
The non-linearized Robin-type flux term.
Definition: neumannmodel.hh:150
constexpr auto neumannBoundaryModel(Fct &&values, Indicator &&where=std::decay_t< Indicator >{}, const std::string &name="")
Generate NeumannBoundaryModel from given grid-function and boundary indicator.
Definition: neumannmodel.hh:189
BoundaryIndicator::Constant< true > EntireBoundaryIndicator
A boundary indicator applying to all parts of the boundary.
Definition: boundaryindicator.hh:376
Fem::QuadraturePointWrapper< Quadrature > QuadraturePoint
Shortcut.
Definition: quadraturepoint.hh:23
Paraphrase isOne and isZero to indicator function talk.
Definition: boundaryindicator.hh:140
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
Definition: functiontraits.hh:98
A structure defining some basic default types and methods.
Definition: modelbase.hh:41
std::pair< bool, std::bitset< dimRange > > BoundaryConditionsType
The type returned by classifyBoundary().
Definition: modelbase.hh:98
typename FunctionSpaceType::DomainType DomainType
The type returned by classifyBoundary().
Definition: modelbase.hh:61
typename FunctionSpaceType::RangeType RangeType
The type returned by classifyBoundary().
Definition: modelbase.hh:62
static constexpr int dimRange
The type returned by classifyBoundary().
Definition: modelbase.hh:86
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 5, 22:29, 2024)