DUNE-ACFEM (unstable)

nitschedirichletmodel.hh
1#ifndef __DUNE_ACFEM_MODELS_MODULES_NITSCHEDIRICHLETMODEL_HH__
2#define __DUNE_ACFEM_MODELS_MODULES_NITSCHEDIRICHLETMODEL_HH__
3
4#include <dune/fem/function/localfunction/const.hh>
5
6#include "../../algorithms/modelparameters.hh"
7#include "../indicators/boundaryindicator.hh"
8#include "../modeltraits.hh"
9#include "../expressions.hh"
10
11namespace Dune {
12
13 namespace ACFem::PDEModel {
14
15 using namespace Literals;
16
29 namespace {
30
31 template<class Model, class Penalty, bool linear, class LinArgs, class Args>
32 class RobinFluxProviderBase;
33
34 template<class Model, class Penalty, bool linear, std::size_t... LinArgsIdx, std::size_t... ArgsIdx>
35 class RobinFluxProviderBase<Model, Penalty, linear,
36 IndexSequence<LinArgsIdx...>,
37 IndexSequence<ModelIntrospection::pointIndex, ModelIntrospection::normalIndex, ArgsIdx...> >
38 {
39 static constexpr std::size_t pointIndex = ModelIntrospection::pointIndex;
40 static constexpr std::size_t normalIndex = ModelIntrospection::normalIndex;
41 static constexpr std::size_t fluxTag = linear ? ModelIntrospection::linearizedFlux : ModelIntrospection::flux;
42 static constexpr std::size_t robinFluxTag = linear ? ModelIntrospection::linearizedRobinFlux : ModelIntrospection::robinFlux;
43 static constexpr std::size_t dirichletTag = linear ? ModelIntrospection::linearizedDirichlet : ModelIntrospection::dirichlet;
44
45 RobinFluxProviderBase(const RobinFluxProviderBase&);
46 public:
47 RobinFluxProviderBase(const Model& m, const Penalty& p)
48 : flux_(m), robinFlux_(m), dirichlet_(m), p_(p)
49 {}
50
51 template<class Quadrature>
52 auto robinMethod(const TupleElement<LinArgsIdx, PDEModel::AllArgs<Model> >&... linArgs,
53 const QuadraturePoint<Quadrature>& x,
54 const typename Model::DomainType& unitOuterNormal,
55 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
56 {
57 auto result = robinFlux_(linArgs..., x, unitOuterNormal, args...);
58 auto dirichlet = dirichlet_(linArgs..., x, args...);
59 const auto flux = flux_(linArgs..., x, args...);
60 const typename Model::RangeFieldType penalty = p_.evaluate(x);
61
62#if 0
63 flux.usmv(-1.0, unitOuterNormal, result);
64 result += (dirichlet *= penalty);
65#else
66 result -= contractInner(flux, unitOuterNormal);
67 result += penalty * dirichlet;
68#endif
69
70 return result;
71 }
72
73 const PDEModel::TaggedModelMethod<Model, fluxTag, SequenceMask<LinArgsIdx..., pointIndex, ArgsIdx...>::value> flux_;
74 const PDEModel::TaggedModelMethod<Model, robinFluxTag, SequenceMask<LinArgsIdx..., pointIndex, normalIndex, ArgsIdx...>::value> robinFlux_;
75 const PDEModel::TaggedModelMethod<Model, dirichletTag, SequenceMask<LinArgsIdx..., pointIndex, ArgsIdx...>::value> dirichlet_;
76 const Penalty& p_;
77 };
78
79 template<class Model, class Penalty, bool linear, bool enable, class LinArgs, class Args>
80 class RobinFluxProvider;
81
82 template<class Model, class Penalty, bool linear, class LinArgs, class Args>
83 class RobinFluxProvider<Model, Penalty, linear, false, LinArgs, Args>
84 {
85 public:
86 RobinFluxProvider(const Model& m, const Penalty& p)
87 {}
88 };
89
90 template<class Model, class Penalty, std::size_t... ArgsIdx>
91 class RobinFluxProvider<Model, Penalty, false, true,
93 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
94 : RobinFluxProviderBase<Model, Penalty, false,
95 IndexSequence<>,
96 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
97 {
98 using BaseType = RobinFluxProviderBase<Model, Penalty, false,
99 IndexSequence<>,
100 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >;
101 using BaseType::robinMethod;
102 public:
103 RobinFluxProvider(const Model& m, const Penalty& p)
104 : BaseType(m, p)
105 {}
106
107 template<class Quadrature>
108 auto
109 robinFlux(const QuadraturePoint<Quadrature>& x,
110 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
111 {
112 return robinMethod(x, args...);
113 }
114 };
115
116 template<class Model, class Penalty, std::size_t... LinArgsIdx, std::size_t... ArgsIdx>
117 class RobinFluxProvider<Model, Penalty, true, true,
118 IndexSequence<LinArgsIdx...>,
119 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
120 : RobinFluxProviderBase<Model, Penalty, true,
121 IndexSequence<LinArgsIdx...>,
122 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
123 {
124 using BaseType = RobinFluxProviderBase<Model, Penalty, true,
125 IndexSequence<LinArgsIdx...>,
126 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >;
127 using BaseType::robinMethod;
128 public:
129 RobinFluxProvider(const Model& m, const Penalty& p)
130 : BaseType(m, p)
131 {}
132
133 template<class Quadrature>
134 auto
135 linearizedRobinFlux(const TupleElement<LinArgsIdx, PDEModel::AllArgs<Model> >&... linArgs,
136 const QuadraturePoint<Quadrature>& x,
137 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
138 {
139 return robinMethod(linArgs..., x, args...);
140 }
141 };
142
143 template<class Model, std::ptrdiff_t symmetry, bool linear, class LinArgs, class PointArgs, class Args>
144 class SingularFluxProviderBase;
145
146 template<class Model, std::ptrdiff_t symmetry, bool linear, std::size_t... LinArgsIdx, std::size_t... PointIdx, std::size_t... ArgsIdx>
147 class SingularFluxProviderBase<Model, symmetry, linear,
148 IndexSequence<LinArgsIdx...>,
149 IndexSequence<PointIdx...>,
150 IndexSequence<ModelIntrospection::normalIndex, ArgsIdx...> >
151 {
152 static constexpr std::size_t pointIndex = ModelIntrospection::pointIndex;
153 static constexpr std::size_t normalIndex = ModelIntrospection::normalIndex;
154 static constexpr std::size_t jacobianIndex = ModelIntrospection::jacobianIndex;
155 static constexpr std::size_t fluxTag = linear ? ModelIntrospection::linearizedFlux : ModelIntrospection::flux;
156 static constexpr std::size_t singularFluxTag = linear ? ModelIntrospection::linearizedSingularFlux : ModelIntrospection::singularFlux;
157 static constexpr std::size_t dirichletTag = linear ? ModelIntrospection::linearizedDirichlet : ModelIntrospection::dirichlet;
158
159 template<class Quadrature>
160 using AllArgs = PDEModel::AllArgs<Model, Quadrature>;
161
162 protected:
163 SingularFluxProviderBase(const Model& m)
164 : flux_(m), singularFlux_(m), dirichlet_(m)
165 {}
166
167 template<class Quadrature = PointWrapperQuadrature<typename Model::DomainType> >
168 auto singularFluxMethod(const TupleElement<LinArgsIdx, AllArgs<Quadrature> >&... linArgs,
169 const TupleElement<PointIdx, AllArgs<Quadrature> >&... xArg,
170 const typename Model::DomainType& unitOuterNormal,
171 const TupleElement<ArgsIdx, AllArgs<Quadrature> >&... args) const
172 {
173 using DomainRangeType = typename Model::DomainRangeType;
174 using DomainJacobianRangeType = typename Model::DomainJacobianRangeType;
175
176 DomainJacobianRangeType result = singularFlux_(linArgs..., xArg..., unitOuterNormal, args...);
177 const auto dirichlet = dirichlet_(linArgs..., xArg..., args...);
178
179 // we know that the first argument of args... must be the values.
180 DomainJacobianRangeType un;
181
182 un = outer(dirichlet, unitOuterNormal);
183
184 result -= flux_(linArgs..., xArg..., DomainRangeType(0), un) * symmetry;
185 if (!ModelTraits<Model>::template IsLinear<fluxTag>::value) {
186 result += flux_(linArgs..., xArg..., DomainRangeType(0), DomainJacobianRangeType(0)) * symmetry;
187 }
188
189 return result;
190 }
191
192 const PDEModel::TaggedModelMethod<Model, fluxTag, SequenceMask<LinArgsIdx..., PointIdx..., ArgsIdx...>::value> flux_;
193 const PDEModel::TaggedModelMethod<Model, singularFluxTag, SequenceMask<LinArgsIdx..., PointIdx..., normalIndex, ArgsIdx...>::value> singularFlux_;
194 const PDEModel::TaggedModelMethod<Model, dirichletTag, SequenceMask<LinArgsIdx..., PointIdx..., ArgsIdx...>::value> dirichlet_;
195 };
196
197 template<class Model, std::ptrdiff_t symmetry, bool linear, bool enable, class LinArgs, class Args>
198 class SingularFluxProvider;
199
200 template<class Model, std::ptrdiff_t symmetry, bool linear, class LinArgs, class Args>
201 class SingularFluxProvider<Model, symmetry, linear, false, LinArgs, Args>
202 {
203 public:
204 SingularFluxProvider(const Model& m)
205 {}
206 };
207
208 template<class Model, std::ptrdiff_t symmetry, std::size_t... ArgsIdx>
209 class SingularFluxProvider<Model, symmetry, false, true,
211 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
212 : SingularFluxProviderBase<Model, symmetry, false,
213 IndexSequence<>,
214 IndexSequence<ModelIntrospection::pointIndex>,
215 IndexSequence<ArgsIdx...> >
216 {
217 using BaseType = SingularFluxProviderBase<Model, symmetry, false,
218 IndexSequence<>,
219 IndexSequence<ModelIntrospection::pointIndex>,
220 IndexSequence<ArgsIdx...> >;
221 using BaseType::singularFluxMethod;
222 public:
223 SingularFluxProvider(const Model& m)
224 : BaseType(m)
225 {}
226
227 template<class Quadrature>
228 auto singularFlux(const QuadraturePoint<Quadrature>& x,
229 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
230 {
231 return BaseType::template singularFluxMethod<Quadrature>(x, args...);
232 }
233 };
234
235 template<class Model, std::ptrdiff_t symmetry, std::size_t... LinArgsIdx, std::size_t... ArgsIdx>
236 class SingularFluxProvider<Model, symmetry, true, true,
237 IndexSequence<LinArgsIdx...>,
238 IndexSequence<ModelIntrospection::pointIndex, ArgsIdx...> >
239 : SingularFluxProviderBase<Model, symmetry, true,
240 IndexSequence<LinArgsIdx...>,
241 IndexSequence<ModelIntrospection::pointIndex>,
242 IndexSequence<ArgsIdx...> >
243 {
244 using BaseType = SingularFluxProviderBase<Model, symmetry, true,
245 IndexSequence<LinArgsIdx...>,
246 IndexSequence<ModelIntrospection::pointIndex>,
247 IndexSequence<ArgsIdx...> >;
248 using BaseType::singularFluxMethod;
249 public:
250
251 SingularFluxProvider(const Model& m)
252 : BaseType(m)
253 {}
254
255 template<class Quadrature>
256 auto linearizedSingularFlux(const TupleElement<LinArgsIdx, PDEModel::AllArgs<Model> >&... linArgs,
257 const QuadraturePoint<Quadrature>& x,
258 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
259 {
260 return BaseType::template singularFluxMethod<Quadrature>(linArgs..., x, args...);
261 }
262 };
263
264 template<class Model, std::ptrdiff_t symmetry, std::size_t... ArgsIdx>
265 class SingularFluxProvider<Model, symmetry, false, true,
267 IndexSequence<ArgsIdx...> >
268 : SingularFluxProviderBase<Model, symmetry, false,
269 IndexSequence<>,
270 IndexSequence<>,
271 IndexSequence<ArgsIdx...> >
272 {
273 using BaseType = SingularFluxProviderBase<Model, symmetry, false,
274 IndexSequence<>,
275 IndexSequence<>,
276 IndexSequence<ArgsIdx...> >;
277 using BaseType::singularFluxMethod;
278 public:
279 SingularFluxProvider(const Model& m)
280 : BaseType(m)
281 {}
282
283 auto singularFlux(const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
284 {
285 return singularFluxMethod(args...);
286 }
287 };
288
289 template<class Model, std::ptrdiff_t symmetry, std::size_t... LinArgsIdx, std::size_t... ArgsIdx>
290 class SingularFluxProvider<Model, symmetry, true, true,
291 IndexSequence<LinArgsIdx...>,
292 IndexSequence<ArgsIdx...> >
293 : SingularFluxProviderBase<Model, symmetry, true,
294 IndexSequence<LinArgsIdx...>,
295 IndexSequence<>,
296 IndexSequence<ArgsIdx...> >
297 {
298 using BaseType = SingularFluxProviderBase<Model, symmetry, true,
299 IndexSequence<LinArgsIdx...>,
300 IndexSequence<>,
301 IndexSequence<ArgsIdx...> >;
302 using BaseType::singularFluxMethod;
303 public:
304
305 SingularFluxProvider(const Model& m)
306 : BaseType(m)
307 {}
308
309 auto linearizedSingularFlux(const TupleElement<LinArgsIdx, PDEModel::AllArgs<Model> >&... linArgs,
310 const TupleElement<ArgsIdx, PDEModel::AllArgs<Model> >&... args) const
311 {
312 return singularFluxMethod(linArgs..., args...);
313 }
314 };
315
316 template<class Model>
317 using NeedRobinFlux = BoolConstant<ModelTraits<Model>::template HasMethod<ModelIntrospection::flux>::value
318 ||
319 ModelTraits<Model>::template HasMethod<ModelIntrospection::robinFlux>::value
320 ||
321 ModelTraits<Model>::template HasMethod<ModelIntrospection::dirichlet>::value>;
322 template<class Model>
323 using NeedLinearizedRobinFlux = BoolConstant<ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedFlux>::value
324 ||
325 ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedRobinFlux>::value
326 ||
327 ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedDirichlet>::value>;
328 template<class Model>
329 using RobinFluxSignature = ModelIntrospection::ArgumentMask<SequenceMask<ModelIntrospection::pointIndex, ModelIntrospection::normalIndex>::value
330 |
331 ModelMethodSignatureClosure<Model, ModelIntrospection::flux>::value
332 |
333 ModelMethodSignatureClosure<Model, ModelIntrospection::robinFlux>::value
334 |
335 ModelMethodSignatureClosure<Model, ModelIntrospection::dirichlet>::value>;
336 template<class Model>
337 using LinearizedRobinFluxSignature = ModelIntrospection::ArgumentMask<SequenceMask<ModelIntrospection::pointIndex, ModelIntrospection::normalIndex>::value
338 |
339 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedFlux>::value
340 |
341 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedRobinFlux>::value
342 |
343 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedDirichlet>::value>;
344
345 template<class Model, class PenaltyFunction>
346 using RobinFluxMethod = RobinFluxProvider<Model, Fem::ConstLocalFunction<PenaltyFunction>,
347 false, NeedRobinFlux<Model>::value,
348 IndexSequence<>, MaskSequence<RobinFluxSignature<Model>::signature()> >;
349 template<class Model, class PenaltyFunction>
350 using LinearizedRobinFluxMethod = RobinFluxProvider<Model, Fem::ConstLocalFunction<PenaltyFunction>,
351 true, NeedLinearizedRobinFlux<Model>::value,
352 MaskSequence<LinearizedRobinFluxSignature<Model>::linearizationSignature()>,
353 MaskSequence<LinearizedRobinFluxSignature<Model>::signature()> >;
354
355 template<class Model>
356 using NeedSingularFlux = BoolConstant<ModelTraits<Model>::template HasMethod<ModelIntrospection::flux>::value
357 ||
358 ModelTraits<Model>::template HasMethod<ModelIntrospection::singularFlux>::value
359 ||
360 ModelTraits<Model>::template HasMethod<ModelIntrospection::dirichlet>::value>;
361 template<class Model>
362 using NeedLinearizedSingularFlux = BoolConstant<ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedFlux>::value
363 ||
364 ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedSingularFlux>::value
365 ||
366 ModelTraits<Model>::template HasMethod<ModelIntrospection::linearizedDirichlet>::value>;
367 template<class Model>
368 using SingularFluxSignature = ModelIntrospection::ArgumentMask<SequenceMask<ModelIntrospection::normalIndex>::value
369 |
370 ModelMethodSignatureClosure<Model, ModelIntrospection::flux>::value
371 |
372 ModelMethodSignatureClosure<Model, ModelIntrospection::singularFlux>::value
373 |
374 ModelMethodSignatureClosure<Model, ModelIntrospection::dirichlet>::value>;
375 template<class Model>
376 using LinearizedSingularFluxSignature = ModelIntrospection::ArgumentMask<SequenceMask<ModelIntrospection::normalIndex>::value
377 |
378 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedFlux>::value
379 |
380 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedSingularFlux>::value
381 |
382 ModelMethodSignatureClosure<Model, ModelIntrospection::linearizedDirichlet>::value>;
383
384 template<class Model, std::ptrdiff_t symmetry>
385 using SingularFluxMethod = SingularFluxProvider<Model, symmetry,
386 false, NeedSingularFlux<Model>::value && symmetry != 0,
387 IndexSequence<>, MaskSequence<SingularFluxSignature<Model>::signature()> >;
388 template<class Model, std::ptrdiff_t symmetry>
389 using LinearizedSingularFluxMethod = SingularFluxProvider<Model, symmetry,
390 true, NeedLinearizedSingularFlux<Model>::value && symmetry != 0,
391 MaskSequence<LinearizedSingularFluxSignature<Model>::linearizationSignature()>,
392 MaskSequence<LinearizedSingularFluxSignature<Model>::signature()> >;
393 }
394
428 template<class Model, class PenaltyFunction, class Symmetrize = SkeletonSymmetrizeDefault<Model> >
430 : public ModelCrop<Model,
431 PDEModel::robinFlux,
432 PDEModel::linearizedRobinFlux,
433 PDEModel::singularFlux,
434 PDEModel::linearizedSingularFlux,
435 PDEModel::dirichlet,
436 PDEModel::linearizedDirichlet>
437 , public RobinFluxMethod<std::decay_t<Model>, PenaltyFunction>
438 , public LinearizedRobinFluxMethod<std::decay_t<Model>, PenaltyFunction>
439 , public SingularFluxMethod<std::decay_t<Model>, Symmetrize{}>
440 , public LinearizedSingularFluxMethod<std::decay_t<Model>, Symmetrize{}>
441 {
443 using TraitsType = ModelTraits<Model>;
444 using BaseType = ModelCrop<Model,
445 PDEModel::robinFlux,
446 PDEModel::linearizedRobinFlux,
447 PDEModel::singularFlux,
448 PDEModel::linearizedSingularFlux,
449 PDEModel::dirichlet,
450 PDEModel::linearizedDirichlet>;
451 using ModelDecay = std::decay_t<Model>;
452 using PenaltyDecay = std::decay_t<PenaltyFunction>;
453 using LocalPenalty = Fem::ConstLocalFunction<PenaltyDecay>;
454 static constexpr std::ptrdiff_t symmetry = Symmetrize{};
455 using RobinFluxBase = RobinFluxMethod<ModelDecay, PenaltyDecay>;
456 using LinearizedRobinFluxBase = LinearizedRobinFluxMethod<ModelDecay, PenaltyDecay>;
457 using SingularFluxBase = SingularFluxMethod<ModelDecay, symmetry>;
458 using LinearizedSingularFluxBase = LinearizedSingularFluxMethod<ModelDecay, symmetry>;
460
462 "PenaltyFunction must provide a local function");
463 static_assert(std::is_convertible<typename PenaltyDecay::FunctionSpaceType::RangeFieldType,
464 typename ModelDecay::RangeFieldType>::value,
465 "PenaltyFunction should be convertible to model's RangeFieldType");
466 static_assert(IsSign<Symmetrize>::value,
467 "Symmetrize must be a sign.");
468
469 public:
470 using ModelType = Model;
471 using typename BaseType::DomainType;
472 using typename BaseType::DomainRangeType;
473 using typename BaseType::DomainJacobianRangeType;
474 using typename BaseType::RangeType;
475 using typename BaseType::BoundaryConditionsType;
476
477 using BaseType::model;
478
479 template<class ModelArg, class FunctionArg,
480 std::enable_if_t<(std::is_constructible<BaseType, ModelArg>::value
481 && std::is_constructible<LocalPenalty, FunctionArg>::value
482 ), int> = 0>
483 NitscheDirichletBoundaryModel(ModelArg&& m, FunctionArg&& penalty,
484 const std::string& name = "")
485 : BaseType(m)
486 , RobinFluxBase(model(), localPenalty_)
487 , LinearizedRobinFluxBase(model(), localPenalty_)
488 , SingularFluxBase(model())
489 , LinearizedSingularFluxBase(model())
490 , localPenalty_(std::forward<FunctionArg>(penalty))
491 , name_(name == "" ? "NitscheDirichlet("+model().name()+")" : name)
492 {}
493
495 : BaseType(other)
496 , RobinFluxBase(model(), localPenalty_)
497 , LinearizedRobinFluxBase(model(), localPenalty_)
498 , SingularFluxBase(model())
499 , LinearizedSingularFluxBase(model())
500 , localPenalty_(other.localPenalty_)
501 , name_(other.name_)
502 {}
503
505 : BaseType(other)
506 , RobinFluxBase(model(), localPenalty_)
507 , LinearizedRobinFluxBase(model(), localPenalty_)
508 , SingularFluxBase(model())
509 , LinearizedSingularFluxBase(model())
510 , localPenalty_(std::move(other.localPenalty_))
511 , name_(std::move(other.name_))
512 {}
513
514 std::string name() const
515 {
516 return name_;
517 }
518
520 template<class Entity>
521 void bind(const Entity& entity)
522 {
523 BaseType::bind(entity);
524 localPenalty_.bind(entity);
525 }
526
528 void unbind()
529 {
530 localPenalty_.unbind();
531 BaseType::unbind();
532 }
533
535 template<class Intersection>
536 auto classifyBoundary(const Intersection& intersection)
537 {
538 // The resulting model has only Robin kind boundary conditions.
539 wrappedSupported_ = model().classifyBoundary(intersection);
540 supported_.first = wrappedSupported_.first;
541 return supported_;
542 }
543
544 protected:
545 LocalPenalty localPenalty_;
546 BoundaryConditionsType wrappedSupported_;
547 BoundaryConditionsType supported_;
548 std::string name_;
549 };
550
552
561 template<class Model,
562 class PenaltyFunction,
563 class Symmetrize = SkeletonSymmetrizeDefault<Model>,
564 std::enable_if_t<(IsProperPDEModel<Model>::value
566 && !Expressions::IsPromotedTopLevel<PenaltyFunction>::value
569 ), int> = 0>
570 auto nitscheDirichletModel(const Model& m, const PenaltyFunction& p, Symmetrize = Symmetrize{})
571 {
572 return expressionClosure(
573 NitscheDirichletBoundaryModel<Model, PenaltyFunction, Symmetrize>(
574 m, p
575 )
576 );
577 }
578
583 template<class Model,
584 class GridPart,
585 class Param = decltype(ModelParameters::nitscheDirichletPenalty()),
586 class Symmetrize = SkeletonSymmetrizeDefault<Model>,
587 std::enable_if_t<(IsPDEModel<Model>::value
588 && ModelMethodExists<Model, ModelIntrospection::dirichlet>::value
589 && IsTensor<Param>::value
590 && IsSign<Symmetrize>::value
591 ), int> = 0>
593 Model&& m,
594 const GridPart& gridPart,
595 Param&& p = ModelParameters::nitscheDirichletPenalty(),
596 Symmetrize = Symmetrize{})
597 {
598 return nitscheDirichletModel(std::forward<Model>(m), std::forward<Param>(p) * meshPenalty(gridPart), Symmetrize{});
599 }
600
605 template<class Model, class... T,
606 std::enable_if_t<(IsProperPDEModel<Model>::value
607 && !ModelMethodExists<Model, ModelIntrospection::dirichlet>::value
608 ), int> = 0>
609 constexpr auto nitscheDirichletModel(Model&& m, T&&...)
610 {
611 return expressionClosure(std::forward<Model>(m));
612 }
613
617 template<class GridFunction,
618 class Param,
619 class Indicator = EntireBoundaryIndicator,
620 class Symmetrize = Sign<1>,
623 && IsTensor<Param>::value
625 ), int> = 0>
626 auto
627 nitscheDirichletModel(GridFunction&& values,
628 Param&& p = ModelParameters::nitscheDirichletPenalty(),
629 Indicator&& where = Indicator(),
630 Symmetrize = Symmetrize{})
631 {
633 dirichletBoundaryModel(std::forward<GridFunction>(values), std::forward<Indicator>(where)),
634 std::forward<Param>(p) * meshPenalty(values.gridPart()),
635 Symmetrize{});
636 }
637
639
641
643
644 } // namespace ACFem::PDEModel
645
646 namespace ACFem {
647
649
650 template<class Model, class PenaltyFunction, class Symmetrize>
651 struct ExpressionTraits<PDEModel::NitscheDirichletBoundaryModel<Model, PenaltyFunction, Symmetrize> >
652 : ExpressionTraits<Model>
653 {
654 using ExpressionType = PDEModel::NitscheDirichletBoundaryModel<Model, PenaltyFunction, Symmetrize>;
655 using Definiteness = typename ExpressionTraits<Model>::Definiteness;
656 static constexpr bool isSymmetric = ExpressionTraits<Model>::isSymmetric && (Symmetrize{} == 1_f);
657 };
658
659 }
660
661} //Namespace Dune
662
663#endif // __DUNE_ACFEM_MODELS_MODULES_NITSCHEDIRICHLETMODEL_HH__
This model constructs from a given other model weak Dirichlet conditions as first introduced by .
Definition: nitschedirichletmodel.hh:441
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
decltype(operate(std::declval< OptOrF >(), std::declval< Rest >()...)) ExpressionType
Generate the type of an expression by calling operate().
Definition: optimizationbase.hh:256
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 meshPenalty(const GridPart &gridPart)
Create a penalty function diverging with the inverse element diameter towards infinity.
Definition: meshpenalty.hh:21
void bind(const Entity &entity)
Unbind from the previously bound entity.
Definition: nitschedirichletmodel.hh:521
constexpr auto dirichletBoundaryModel(T &&values, Indicator &&where, const std::string &name="")
Generate the zero model for the empty indicator.
Definition: dirichletmodel.hh:237
auto nitscheDirichletModel(GridFunction &&values, Param &&p=ModelParameters::nitscheDirichletPenalty(), Indicator &&where=Indicator(), Symmetrize=Symmetrize{})
Create a model supplying weak Dirichet conditions from a given grid-function.
Definition: nitschedirichletmodel.hh:627
void unbind()
Unbind from the previously bound entity.
Definition: nitschedirichletmodel.hh:528
auto classifyBoundary(const Intersection &intersection)
Bind to the given intersection and classify the components w.r.t.
Definition: nitschedirichletmodel.hh:536
std::tuple_element_t< N, std::decay_t< TupleLike > > TupleElement
Forward to std::tuple_element<N, std::decay_t<T> >
Definition: access.hh:125
IndexConstant< SequenceMaskHelper< I... >::value > SequenceMask
Generate a bit-mask from the given index-sequence.
Definition: mask.hh:78
auto outer(T1 &&t1, T2 &&t2)
Outer tensor product.
Definition: expressions.hh:138
constexpr auto contractInner(T1 &&t1, T2 &&t2, IndexConstant< N >=IndexConstant< N >{})
Contraction over the #N inner dimensions.
Definition: expressions.hh:118
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
typename ModelTraits< Model >::template Exists< ModelIntrospection::CheckMethodTag< tag >::value > ModelMethodExists
Check for either non-linear or linearized method.
Definition: modeltraits.hh:906
BoundaryIndicator::Constant< true > EntireBoundaryIndicator
A boundary indicator applying to all parts of the boundary.
Definition: boundaryindicator.hh:376
ModelIntrospection::Traits< Model > ModelTraits
Traits class for models.
Definition: modeltraits.hh:898
TrueType if T is a BoundaryIndicator.
Definition: boundaryindicator.hh:49
A structure defining some basic default types and methods.
Definition: modelbase.hh:41
Definition: fractionconstant.hh:173
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)