DUNE-ACFEM (unstable)

modeltraits.hh
1#ifndef __DUNE_ACFEM_MODELTRAITS_HH__
2#define __DUNE_ACFEM_MODELTRAITS_HH__
3
4#include "../mpl/mpl.hh"
5#include "../common/quadraturepoint.hh"
6#include "../expressions/traitsdefault.hh"
7
8#include "modelbase.hh"
9
10namespace Dune {
11
12 namespace ACFem {
13
16 namespace ModelIntrospection {
17
23 enum MethodTag {
24 flux, linearizedFlux,
25 source, linearizedSource,
26 robinFlux, linearizedRobinFlux,
27 singularFlux, linearizedSingularFlux,
28 dirichlet, linearizedDirichlet,
29 fluxDivergence,
30 numMethodTags,
31 };
32
38 template<MethodTag tag>
40
44 template<std::size_t tag>
46
48 template<std::size_t tag>
50
55 template<std::size_t tag>
58 ? tag
59 : (tag == fluxDivergence
60 ? linearizedFlux
61 : tag+1))>;
62
67 template<std::size_t tag>
68 using NonLinearTag = CheckMethodTag<(IsLinearMethodTag<tag>::value ? (tag-1) : tag == fluxDivergence ? flux : tag)>;
69
71 template<MethodTag... Tags>
73
76
77 namespace {
78 template<std::size_t methods>
79 struct NonLinearClosureFunctor
80 {
81 template<class T, T tag, std::size_t N>
82 using Apply = BoolConstant<
84 &&
85 (hasBit(methods, tag) || hasBit(methods, LinearizedTag<tag>::value)))>;
86 };
87 }
88
95 template<std::size_t methods>
97 IndexConstant<sequenceMask(FilteredSequence<NonLinearClosureFunctor<methods>, AllMethodTags>{})>;
98
103 linearizationValueIndex = 0, linearizationJacobianIndex,
104 pointIndex, normalIndex, valueIndex, jacobianIndex, hessianIndex,
105 maxNumArguments
106 };
107
109 template<std::size_t mask>
111 : public IndexConstant<mask>
112 {
113 static_assert((mask & (~(std::size_t)0 << maxNumArguments)) == 0,
114 "Unsupported argument mask");
115 using BaseType = IndexConstant<mask>;
116 static constexpr std::size_t linArgsMask =
118 public:
119 using BaseType::value;
120 using typename BaseType::value_type;
121
124
126 ArgumentMask(const BaseType&) {}
127
130
132 static constexpr value_type linearizationSignature()
133 {
134 return LinearizationSignature::value;
135 }
136
141
145 static constexpr value_type signature()
146 {
147 return Signature::value;
148 }
149 };
150
151 namespace {
152
153 struct TraitsHelper
154 {
155 protected:
156#if DUNE_ACFEM_IS_CLANG(0, 4) // seemingly 5 does not need it.
157# warning Clang < 5 will very likely not work.
158#endif
159 template<class Model>
160 using DomainFieldType = typename Model::FunctionSpaceType::DomainFieldType;
161
162 template<class Model>
163 using DomainType = typename Model::FunctionSpaceType::DomainType;
164
165 template<class Model>
166 using RangeFieldType = typename Model::FunctionSpaceType::RangeFieldType;
167 template<class Model>
168 using DomainRangeFieldType = typename Model::DomainFunctionSpaceType::RangeFieldType;
169 template<class Model>
170 using RangeRangeFieldType = typename Model::RangeFunctionSpaceType::RangeFieldType;
171
172 template<class Model>
173 using RangeType = typename Model::FunctionSpaceType::RangeType;
174 template<class Model>
175 using DomainRangeType = typename Model::DomainFunctionSpaceType::RangeType;
176 template<class Model>
177 using RangeRangeType = typename Model::RangeFunctionSpaceType::RangeType;
178
179 template<class Model>
180 using JacobianRangeType = typename Model::FunctionSpaceType::JacobianRangeType;
181 template<class Model>
182 using DomainJacobianRangeType = typename Model::DomainFunctionSpaceType::JacobianRangeType;
183 template<class Model>
184 using RangeJacobianRangeType = typename Model::RangeFunctionSpaceType::JacobianRangeType;
185
186 template<class Model>
187 using HessianRangeType = typename Model::HessianRangeType;
188 template<class Model>
189 using RangeHessianRangeType = typename Model::RangeHessianRangeType;
190 template<class Model>
191 using DomainHessianRangeType = typename Model::DomainHessianRangeType;
192
201 template<class Model, class Quadrature = PointWrapperQuadrature<DomainType<Model> > >
202 using AllArguments = std::tuple<DomainRangeType<Model>,
203 DomainJacobianRangeType<Model>,
205 DomainType<Model>,
206 DomainRangeType<Model>,
207 DomainJacobianRangeType<Model>,
208 DomainHessianRangeType<Model> >;
209
213 template<class Model>
214 using MethodReturnType =
215 std::tuple<JacobianRangeType<Model>, // flux
216 JacobianRangeType<Model>,
217 RangeType<Model>, // source
218 RangeType<Model>,
219 RangeType<Model>, // robinFlux
220 RangeType<Model>,
221 JacobianRangeType<Model>, // singularFlux
222 JacobianRangeType<Model>,
223 RangeType<Model>, // dirichlet
224 RangeType<Model>,
225 RangeType<Model> // fluxDivergence
226 >;
227
229 template<class Model>
230 using DomainEqRange = std::is_same<DomainType<Model>, DomainRangeType<Model> >;
231
236 template<MethodTag tag, class dummy = void>
237 struct SupportedCallSignatures;
238
239 public:
243 template<MethodTag tag>
244 using MethodSignatures = typename SupportedCallSignatures<tag>::Type;
245
249 template<MethodTag tag>
251
252 protected:
260 template<class dummy>
261 struct SupportedCallSignatures<flux, dummy>
262 {
263 static constexpr std::size_t closure = SequenceMask<pointIndex, valueIndex, jacobianIndex>::value;
264 using Type = SubMaskSequence<closure>;
266 "Implementation error: closure does not close");
267 };
268
269 template<class dummy>
270 struct SupportedCallSignatures<fluxDivergence, dummy>
271 {
272 static constexpr std::size_t closure = SequenceMask<pointIndex, valueIndex, jacobianIndex, hessianIndex>::value;
273 using Type = SubMaskSequence<closure>;
274 static_assert(closure == AccumulateSequence<BitwiseOrFunctor, Type>::value,
275 "Implementation error: closure does not close");
276 };
277
278 template<class dummy>
279 struct SupportedCallSignatures<source, dummy>
280 {
281 static constexpr std::size_t closure = SequenceMask<pointIndex, valueIndex, jacobianIndex>::value;
282 using Type = SubMaskSequence<closure>;
283 static_assert(closure == AccumulateSequence<BitwiseOrFunctor, Type>::value,
284 "Implementation error: closure does not close");
285 };
286
287 template<class dummy>
288 struct SupportedCallSignatures<robinFlux, dummy>
289 {
290 // normal has always to be there in order to avoid ambiguouties
291 static constexpr std::size_t fixed = SequenceMask<normalIndex>::value;
292 static constexpr std::size_t varying = SequenceMask<pointIndex, valueIndex, jacobianIndex>::value;
293 static constexpr std::size_t closure = fixed|varying;
294 using Type = SubMaskSequence<varying, fixed>;
295 static_assert(closure == AccumulateSequence<BitwiseOrFunctor, Type>::value,
296 "Implementation error: closure does not close");
297 };
298
299 template<class dummy>
300 struct SupportedCallSignatures<singularFlux, dummy>
301 {
302 // normal has always to be there in order to avoid ambiguouties
303 static constexpr std::size_t fixed = SequenceMask<normalIndex>::value;
304 static constexpr std::size_t varying = SequenceMask<pointIndex, valueIndex, jacobianIndex>::value;
305 static constexpr std::size_t closure = fixed|varying;
306 using Type = SubMaskSequence<varying, fixed>;
307 static_assert(closure == AccumulateSequence<BitwiseOrFunctor, Type>::value,
308 "Implementation error: closure does not close");
309 };
310
311 template<class dummy>
312 struct SupportedCallSignatures<dirichlet, dummy>
313 {
314 static constexpr std::size_t closure = SequenceMask<pointIndex, valueIndex>::value;
315 using Type = SubMaskSequence<closure>;
316 };
317
328 template<MethodTag tag>
329 using LinearizedMethodTag = std::integral_constant<std::enable_if_t<tag != fluxDivergence, MethodTag>, tag+1>;
330
338 template<MethodTag tag, class dummy>
339 struct SupportedCallSignatures
340 {
341 static_assert(IsLinearMethodTag<tag>::value,
342 "Implementation failure: non-linear call-signatures not specialized.");
343 typedef
345 AddBitShiftRightFunctor<valueIndex, valueIndex>,
347 AddBitShiftRightFunctor<jacobianIndex, valueIndex>,
348 MethodSignatures<NonLinearTag<tag>::value> > >
349 Type;
350 static constexpr std::size_t closure = AccumulateSequence<BitwiseOrFunctor, Type>::value;
351 };
352
355 struct GetSignatureClosure
356 {
357 template<class T, T tag, std::size_t N>
358 using Apply = MethodSignatureClosure<CheckMethodTag<tag>::value>;
359 };
360
361 public:
363 using MethodSignaturesClosureType = TransformedSequence<GetSignatureClosure, AllMethodTags>;
364
365 protected:
366 /*********************************************************************
367 *
368 * Individual method-introspection proto-below, one
369 * packer-expander pair for each method.
370 *
371 */
372
374 template<class Model, class Tuple, std::size_t... I>
375 static
376 decltype(std::declval<Model>().flux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
377 fluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
378
380 template<class Model, std::size_t ArgMaskValue>
381 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<flux>&, const ArgumentMask<ArgMaskValue>&,
382 decltype(fluxHelper(std::declval<const Model&>(),
383 std::declval<const AllArguments<Model> >(),
384 MaskSequence<ArgMaskValue>())) * = nullptr);
385
387 template<class Model, class Tuple, std::size_t... I>
388 static
389 decltype(std::declval<Model>().linearizedFlux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
390 linearizedFluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
391
393 template<class Model, std::size_t ArgMaskValue>
394 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<linearizedFlux>&, const ArgumentMask<ArgMaskValue>&,
395 decltype(linearizedFluxHelper(std::declval<const Model&>(),
396 std::declval<const AllArguments<Model> >(),
397 MaskSequence<ArgMaskValue>())) * = nullptr);
398
400 template<class Model, class Tuple, std::size_t... I>
401 static
402 decltype(std::declval<Model>().fluxDivergence(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
403 fluxDivergenceHelper(Model&&, Tuple&&, std::index_sequence<I...>);
404
406 template<class Model, std::size_t ArgMaskValue>
407 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<fluxDivergence>&, const ArgumentMask<ArgMaskValue>&,
408 decltype(fluxDivergenceHelper(std::declval<const Model&>(),
409 std::declval<const AllArguments<Model> >(),
410 MaskSequence<ArgMaskValue>())) * = nullptr);
411
413 template<class Model, class Tuple, std::size_t... I>
414 static
415 decltype(std::declval<Model>().source(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
416 sourceHelper(Model&&, Tuple&&, std::index_sequence<I...>);
417
419 template<class Model, std::size_t ArgMaskValue>
420 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<source>&, const ArgumentMask<ArgMaskValue>&,
421 decltype(sourceHelper(std::declval<const Model&>(),
422 std::declval<const AllArguments<Model> >(),
423 MaskSequence<ArgMaskValue>())) * = nullptr);
424
426 template<class Model, class Tuple, std::size_t... I>
427 static
428 decltype(std::declval<Model>().linearizedSource(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
429 linearizedSourceHelper(Model&&, Tuple&&, std::index_sequence<I...>);
430
432 template<class Model, std::size_t ArgMaskValue>
433 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<linearizedSource>&, const ArgumentMask<ArgMaskValue>&,
434 decltype(linearizedSourceHelper(std::declval<const Model&>(),
435 std::declval<const AllArguments<Model> >(),
436 MaskSequence<ArgMaskValue>())) * = nullptr);
437
439 template<class Model, class Tuple, std::size_t... I>
440 static
441 decltype(std::declval<Model>().robinFlux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
442 robinFluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
443
445 template<class Model, std::size_t ArgMaskValue>
446 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<robinFlux>&, const ArgumentMask<ArgMaskValue>&,
447 decltype(robinFluxHelper(std::declval<const Model&>(),
448 std::declval<const AllArguments<Model> >(),
449 MaskSequence<ArgMaskValue>())) * = nullptr);
450
452 template<class Model, class Tuple, std::size_t... I>
453 static
454 decltype(std::declval<Model>().linearizedRobinFlux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
455 linearizedRobinFluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
456
458 template<class Model, std::size_t ArgMaskValue>
459 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<linearizedRobinFlux>&, const ArgumentMask<ArgMaskValue>&,
460 decltype(linearizedRobinFluxHelper(std::declval<const Model&>(),
461 std::declval<const AllArguments<Model> >(),
462 MaskSequence<ArgMaskValue>())) * = nullptr);
463
465 template<class Model, class Tuple, std::size_t... I>
466 static
467 decltype(std::declval<Model>().singularFlux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
468 singularFluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
469
471 template<class Model, std::size_t ArgMaskValue>
472 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<singularFlux>&, const ArgumentMask<ArgMaskValue>&,
473 decltype(singularFluxHelper(std::declval<const Model&>(),
474 std::declval<const AllArguments<Model> >(),
475 MaskSequence<ArgMaskValue>())) * = nullptr);
477 template<class Model, class Tuple, std::size_t... I>
478 static
479 decltype(std::declval<Model>().linearizedSingularFlux(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
480 linearizedSingularFluxHelper(Model&&, Tuple&&, std::index_sequence<I...>);
481
483 template<class Model, std::size_t ArgMaskValue>
484 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<linearizedSingularFlux>&, const ArgumentMask<ArgMaskValue>&,
485 decltype(linearizedSingularFluxHelper(std::declval<const Model&>(),
486 std::declval<const AllArguments<Model> >(),
487 MaskSequence<ArgMaskValue>())) * = nullptr);
488
490 template<class Model, class Tuple, std::size_t... I>
491 static
492 decltype(std::declval<Model>().dirichlet(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
493 dirichletHelper(Model&&, Tuple&&, std::index_sequence<I...>);
494
496 template<class Model, std::size_t ArgMaskValue>
497 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<dirichlet>&, const ArgumentMask<ArgMaskValue>&,
498 decltype(dirichletHelper(std::declval<const Model&>(),
499 std::declval<const AllArguments<Model> >(),
500 MaskSequence<ArgMaskValue>())) * = nullptr);
502 template<class Model, class Tuple, std::size_t... I>
503 static
504 decltype(std::declval<Model>().linearizedDirichlet(std::declval<const decltype(std::get<I>(std::declval<Tuple>()))&>()...))
505 linearizedDirichletHelper(Model&&, Tuple&&, std::index_sequence<I...>);
506
508 template<class Model, std::size_t ArgMaskValue>
509 static std::true_type methodIntrospection(const Model&, const MethodTagConstant<linearizedDirichlet>&, const ArgumentMask<ArgMaskValue>&,
510 decltype(linearizedDirichletHelper(std::declval<const Model&>(),
511 std::declval<const AllArguments<Model> >(),
512 MaskSequence<ArgMaskValue>())) * = nullptr);
513
519 template<class Model, MethodTag tag>
520 static std::false_type
521 methodIntrospection(const Model&, const MethodTagConstant<tag>&, ...);
522
523 /*********************************************************************
524 *
525 * Post-process the detected call-signatures.
526 *
527 * @note clang fails to compile the stuff if the
528 * post-processing comes right after the "catch-all" and the
529 * specializations are placed in-class after the
530 * post-processing templates.
531 *
532 */
533
537 template<class Model, MethodTag tag>
538 struct SignatureFilter
539 {
540 template<class T, T mask, std::size_t N = 0>
541 struct Apply
542 : BoolConstant<decltype(methodIntrospection(std::declval<Model>(),
543 MethodTagConstant<tag>{},
544 ArgumentMask<mask>{}))::value>
545 {};
546 };
547
551 template<class Model, MethodTag tag>
552 using FilteredSignatures = FilteredSequence<SignatureFilter<Model, tag>, MethodSignatures<tag> >;
553
554#if false && defined(__clang__)
555 // ?????? NumCallSignatures is only access in THIS
556 // struct. So what is this? Seemingly clang has problems
557 // with variable templates.
558#if 0
559//modeltraits.hh:674:42: error: 'NumCallSignatures' is a protected member of
560// 'Dune::ACFem::ModelIntrospection::(anonymous namespace)::TraitsHelper'
561// using HasMethod = BoolConstant<NumCallSignatures<Model, tag> == 1>;
562#endif
564 template<class Model, MethodTag tag>
565 static constexpr std::size_t NumCallSignatures = size<FilteredSignatures<Model, tag> >();
566#else
568 template<class Model, MethodTag tag>
569 using NumCallSignatures = IndexConstant<size<FilteredSignatures<Model, tag> >()>;
570#endif
571
573 template<class Model, MethodTag tag>
574 using HasMethod = BoolConstant<NumCallSignatures<Model, tag>::value == 1>;
575
577 template<class Model>
578 struct HasMethodFunctor
579 {
580 template<class T, T tag, std::size_t>
581 using Apply = HasMethod<Model, CheckMethodTag<tag>::value>;
582 };
583
584 template<class Model>
585 struct GetMethodSignature
586 {
587 template<class T, T tag, class = void>
588 struct ApplyHelper {
589 static_assert(!std::is_convertible<RangeType<Model>,
590 HessianRangeType<Model> >::value,
591 "RangeType convertible to HessianRangeType");
592 static_assert(NumCallSignatures<Model, CheckMethodTag<tag>::value>::value == 0,
593 "More than one call-signature found for method-tag");
594 using Type = Constant<T, 0>;
595 };
596
597 template<class T, T tag>
598 struct ApplyHelper<T, tag, std::enable_if_t<HasMethod<Model, CheckMethodTag<tag>::value>::value> >
599 {
600 using Type = Head<FilteredSignatures<Model, CheckMethodTag<tag>::value> >;
601 };
602
603 template<class T, T V, std::size_t>
604 using Apply = typename ApplyHelper<T, V>::Type;
605 };
606
611 template<class Model>
612 using MethodCallSignatures = TransformedSequence<GetMethodSignature<Model>, AllMethodTags>;
613
615 template<class Model>
616 using ModelMethods = FilteredSequence<HasMethodFunctor<Model>, AllMethodTags>;
617 }; // TraitsHelper class
618
619 } // namespace
620
624 template<MethodTag tag>
625 using MethodSignatures = typename TraitsHelper::SupportedCallSignatures<tag>::Type;
626
630 template<std::size_t tag>
631 using MethodSignatureClosure = TraitsHelper::MethodSignatureClosure<CheckMethodTag<tag>::value>;
632
634 using MethodSignaturesClosureType = TraitsHelper::MethodSignaturesClosureType;
635
637 template<class Model>
638 using Methods = TraitsHelper::template ModelMethods<std::decay_t<Model> >;
639
641 template<class Model>
642 constexpr inline bool isZero = Methods<Model>::size() == 0;
643
645 template<class Model>
647
648 template<class Model, class SFINAE = void>
649 struct IsModel
650 : FalseType
651 {};
652
653 template<class Model>
654 struct IsModel<Model, std::enable_if_t<!IsDecay<Model>::value> >
655 : IsModel<std::decay_t<Model> >
656 {}; //
657
659 template<class Model>
660 struct IsModel<
661 Model,
662 std::enable_if_t<(IsDecay<Model>::value
663 && std::is_base_of<ModelBase<typename Model::DomainFunctionSpaceType,
664 typename Model::RangeFunctionSpaceType>,
665 Model>::value
666 )> >
667 : TrueType
668 {};
669
670 template<class Model, class SFINAE = void>
671 struct Traits
672 {};
673
674 template<class T>
675 struct Traits<T, std::enable_if_t<!IsDecay<T>::value> >
676 : Traits<std::decay_t<T> >
677 {};
678
685 template<class Model>
686 struct Traits<Model, std::enable_if_t<IsModel<Model>::value && IsDecay<Model>::value> >
687 : private TraitsHelper
688 {
689 private:
690 using BaseType = TraitsHelper;
691 public:
692 using ModelType = Model;
693
694 using FunctionSpaceType = typename ModelType::FunctionSpaceType;
695 using DomainFunctionSpaceType = typename ModelType::DomainFunctionSpaceType;
696 using RangeFunctionSpaceType = typename ModelType::RangeFunctionSpaceType;
697
698 static constexpr std::size_t dimDomain = static_cast<std::size_t>(FunctionSpaceType::dimDomain);
699 static constexpr std::size_t dimRange = static_cast<std::size_t>(FunctionSpaceType::dimRange);
700 static constexpr std::size_t dimRangeRange = static_cast<std::size_t>(RangeFunctionSpaceType::dimRange);
701 static constexpr std::size_t dimDomainRange = static_cast<std::size_t>(DomainFunctionSpaceType::dimRange);
702
703 using DomainFieldType = BaseType::DomainFieldType<Model>;
704 using DomainType = BaseType::DomainType<Model>;
705
706 using RangeFieldType = BaseType::RangeFieldType<Model>;
707 using RangeType = BaseType::RangeType<Model>;
708 using JacobianRangeType = BaseType::JacobianRangeType<Model>;
709 using HessianRangeType = BaseType::HessianRangeType<Model>;
710
711 using RangeRangeFieldType = BaseType::RangeRangeFieldType<Model>;
712 using RangeRangeType = BaseType::RangeRangeType<Model>;
713 using RangeJacobianRangeType = BaseType::RangeJacobianRangeType<Model>;
714 using RangeHessianRangeType = BaseType::RangeHessianRangeType<Model>;
715
716 // Check alias data types
717 static_assert(std::is_same<RangeType, RangeRangeType>::value,
718 "RangeType and RangeRangeType must coincide");
719 static_assert(std::is_same<JacobianRangeType, RangeJacobianRangeType>::value,
720 "JacobianRangeType and RangeJacobianRangeType must coincide");
721 static_assert(std::is_same<HessianRangeType, RangeHessianRangeType>::value,
722 "HessianRangeType and RangeHessianRangeType must coincide");
723
724 using DomainRangeFieldType = BaseType::DomainRangeFieldType<Model>;
725 using DomainRangeType = BaseType::DomainRangeType<Model>;
726 using DomainJacobianRangeType = BaseType::DomainJacobianRangeType<Model>;
727 using DomainHessianRangeType = BaseType::DomainHessianRangeType<Model>;
728
732 template<class Quadrature>
733 using AllArguments = typename BaseType::AllArguments<Model, Quadrature>;
734
736 template<MethodTag tag>
737 using FilteredSignatures = typename BaseType::FilteredSignatures<Model, tag>;
738
739 static_assert(std::is_same<typename Model::FunctionSpaceType,
740 typename Model::RangeFunctionSpaceType>::value,
741 "Implementation bug: FunctionSpaceType MUST be an alias of RangeFunctionSpaceType");
742
744 template<MethodTag tag>
746
757 using Methods = typename BaseType::ModelMethods<Model>;
758
763 using MethodCallSignatures = typename BaseType::MethodCallSignatures<Model>;
764
766 template<std::size_t tag>
767 using CallSignature = Get<CheckMethodTag<tag>::value, MethodCallSignatures>;
768
773 template<std::size_t tag>
776 |
777 ((tag == fluxDivergence || CallSignature<tag>::value != (std::size_t)0)
778 ? (std::size_t)0
780
784 static constexpr std::size_t methodsMask = sequenceMask(Methods{});
785
787 template<std::size_t tag>
788 using HasMethod = BaseType::HasMethod<Model, CheckMethodTag<tag>::value>;
789
791 struct ExistsFunctor
792 {
793 template<class T, T tag, std::size_t N = 0>
794 using Apply = BoolConstant<
795 HasMethod<NonLinearTag<tag>::value>::value ||
796 HasMethod<LinearizedTag<tag>::value>::value>;
797 };
798
800 template<std::size_t tag>
801 using Exists = typename ExistsFunctor::template Apply<MethodTag, CheckMethodTag<tag>::value>;
802
804 struct IsLoadFunctor
805 {
806 template<class T, T tag, std::size_t N = 0>
807 using Apply = BoolConstant<
809 ||
810 (HasMethod<NonLinearTag<CheckMethodTag<tag>::value>::value>::value
811 &&
812 (Get<NonLinearTag<CheckMethodTag<tag>::value>::value, MethodCallSignatures>::value
813 &
815 };
816
818 template<std::size_t tag>
819 using IsLoad = typename IsLoadFunctor::template Apply<MethodTag, CheckMethodTag<tag>::value>;
820
822 struct IsPiecewiseConstantFunctor
823 {
824 template<class T, T tag, std::size_t N = 0>
825 using Apply = BoolConstant<
826 !HasMethod<CheckMethodTag<tag>::value>::value
827 ||
828 (Get<CheckMethodTag<tag>::value, MethodCallSignatures>::value
829 &
831 };
832
834 template<std::size_t tag>
835 using IsPiecewiseConstant = typename IsPiecewiseConstantFunctor::template Apply<MethodTag, CheckMethodTag<tag>::value>;
836
838 struct IsLinearFunctor
839 {
840 template<class T, T tag, std::size_t N = 0>
842 };
843
845 template<std::size_t tag>
846 using IsLinear = typename IsLinearFunctor::template Apply<MethodTag, CheckMethodTag<tag>::value>;
847
849 struct IsAffineLinearFunctor
850 {
851 template<class T, T tag, std::size_t N = 0>
852 using Apply = BoolConstant<
853 (Get<LinearizedTag<CheckMethodTag<tag>::value>::value, MethodCallSignatures>::value
854 &
856 };
857
859 template<std::size_t tag>
860 using IsAffineLinear = typename IsAffineLinearFunctor::template Apply<MethodTag, CheckMethodTag<tag>::value>;
861
871
874
876 static constexpr bool isZero = Methods::size() == 0;
877
880
886
888 }; // Traits
889
890 } // namespace ModelIntrospection
891
893 template<class Model>
894 using IsPDEModel = ModelIntrospection::template IsModel<Model>;
895
897 template<class Model>
898 using ModelTraits = ModelIntrospection::Traits<Model>;
899
901 template<class Model, std::size_t tag>
902 using ModelHasMethod = typename ModelTraits<Model>::template HasMethod<ModelIntrospection::CheckMethodTag<tag>::value>;
903
905 template<class Model, std::size_t tag>
906 using ModelMethodExists = typename ModelTraits<Model>::template Exists<ModelIntrospection::CheckMethodTag<tag>::value>;
907
909 template<class Model, std::size_t tag>
911 typename ModelTraits<Model>::template CallSignature<ModelIntrospection::CheckMethodTag<tag>::value>;
912
918 template<class Model, std::size_t tag>
920 typename ModelTraits<Model>::template CallSignatureClosure<ModelIntrospection::CheckMethodTag<tag>::value>;
921
924
927
929
931
932 } // namespace ACFem
933
934} //Namespace Dune
935
936#endif // __DUNE_ACFEM_MODELTRAITS_HH__
Integral constant holding an argument mask.
Definition: modeltraits.hh:112
IndexConstant< value &linArgsMask > LinearizationSignature
The part of the mask referring to the point of linearization.
Definition: modeltraits.hh:129
ArgumentMask()
Default constructor.
Definition: modeltraits.hh:123
static constexpr value_type linearizationSignature()
The part of the mask referring to the point of linearization.
Definition: modeltraits.hh:132
static constexpr value_type signature()
The part of the mask referring to the arguments except the point of linearization.
Definition: modeltraits.hh:145
IndexConstant< value &~linArgsMask > Signature
The part of the mask referring to the arguments except the point of linearization.
Definition: modeltraits.hh:140
ArgumentMask(const BaseType &)
Allow implicit initialization from base type.
Definition: modeltraits.hh:126
Constant< typename Seq::value_type, AccumulateSequenceHelper< Seq, F >::value > AccumulateSequence
Accumulate the values of the sequence according to the supplied functor.
Definition: accumulate.hh:73
std::tuple_element_t< N, std::decay_t< TupleLike > > TupleElement
Forward to std::tuple_element<N, std::decay_t<T> >
Definition: access.hh:125
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
TransformSequence< Seq, Sequence< typename Seq::value_type >, IdentityFunctor, UnaryFilterFunctor< F, typename Seq::value_type > > FilteredSequence
Create a new sequence by filtering out certain elements.
Definition: filter.hh:115
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
constexpr bool hasBit(const std::size_t &mask, const std::size_t &bit)
std::true_type if Mask has Bit set.
Definition: mask.hh:92
constexpr auto sequenceMask(const IndexSequence< I... > &)
Generate a bit-mask from the given index-sequence.
Definition: mask.hh:82
typename SubMaskSequenceHelper< IndexSequence<>, MaskSequence< Mask >, MaskSequence< RequiredMask > >::type SubMaskSequence
Generate a sequence of pair-wise distinct sub-bitmasks starting from a given bit-mask.
Definition: submask.hh:79
IndexConstant< SequenceMaskHelper< I... >::value > SequenceMask
Generate a bit-mask from the given index-sequence.
Definition: mask.hh:78
TransformSequence< Seq, Seq, F, AcceptEqualFunctor< false > > CatTransformUnique
Concat the result of TransformUnique with the original sequence.
Definition: transform.hh:295
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
std::integer_sequence< T, V... > Sequence
Sequence of any type of integer values.
Definition: types.hh:56
Constant< std::size_t, V > IndexConstant
Short-cut for integral constant of type std::size_t.
Definition: types.hh:44
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
MakeIndexSequence< numMethodTags > AllMethodTags
Sequence of all supported methods.
Definition: modeltraits.hh:75
MethodTagConstant<(MethodTag) tag > CheckMethodTag
Alias, used where we want to express that we do check the value.
Definition: modeltraits.hh:45
MethodTag
An enum in order to parametrize the call-signature introspection.
Definition: modeltraits.hh:23
IndexConstant< sequenceMask(FilteredSequence< NonLinearClosureFunctor< methods >, AllMethodTags >{})> NonLinearMethodsClosure
Compute a bit-mask corresponding to the "closure" of non-linear methods.
Definition: modeltraits.hh:97
TraitsHelper::template ModelMethods< std::decay_t< Model > > Methods
Shortcut to the methods implemented by the model.
Definition: modeltraits.hh:638
Sequence< MethodTag, Tags... > MethodTagSequence
Sequence alias for method-tags.
Definition: modeltraits.hh:72
ArgumentPositions
Positions of the respective arguments inside the argument closure tuple.
Definition: modeltraits.hh:102
TraitsHelper::template MethodCallSignatures< std::decay_t< Model > > MethodCallSignatures
Shortcut the the call-signature tuple.
Definition: modeltraits.hh:646
TraitsHelper::MethodSignatureClosure< CheckMethodTag< tag >::value > MethodSignatureClosure
Type alias extracting the "closure" of all supported call-signatures.
Definition: modeltraits.hh:631
TraitsHelper::MethodSignaturesClosureType MethodSignaturesClosureType
A sequence with the closure patterns for each method.
Definition: modeltraits.hh:634
constexpr bool isZero
Shortcut identifying a zero model.
Definition: modeltraits.hh:642
typename TraitsHelper::SupportedCallSignatures< tag >::Type MethodSignatures
Type alias extracting the index_sequence holding all allowed call-signatures for the given tag.
Definition: modeltraits.hh:625
CheckMethodTag<(IsLinearMethodTag< tag >::value ? tag :(tag==fluxDivergence ? linearizedFlux :tag+1))> LinearizedTag
Compute the tag value of the respective linearized method.
Definition: modeltraits.hh:61
CheckMethodTag<(IsLinearMethodTag< tag >::value ?(tag-1) :tag==fluxDivergence ? flux :tag)> NonLinearTag
Compute the tag value of the respective non-linear method.
Definition: modeltraits.hh:68
Constant< MethodTag, tag > MethodTagConstant
Wrap into integral_constant in order to have a type.
Definition: modeltraits.hh:39
BoolConstant< CheckMethodTag< tag >::value &1 > IsLinearMethodTag
Evaluate to std::true_type for tags corresponding to linear methods.
Definition: modeltraits.hh:49
ModelIntrospection::MethodSignaturesClosureType ModelMethodClosureSignatures
A sequence with the closure signatures for all methods.
Definition: modeltraits.hh:926
typename ModelTraits< Model >::template Exists< ModelIntrospection::CheckMethodTag< tag >::value > ModelMethodExists
Check for either non-linear or linearized method.
Definition: modeltraits.hh:906
Fem::QuadraturePointWrapper< Quadrature > QuadraturePoint
Shortcut.
Definition: quadraturepoint.hh:23
ModelIntrospection::AllMethodTags ModelAdmissibleMethods
A sequence with the tags of all possible model-methods.
Definition: modeltraits.hh:923
ModelIntrospection::template IsModel< Model > IsPDEModel
std::true_type if Model is derived from ModelBase.
Definition: modeltraits.hh:894
ModelIntrospection::Traits< Model > ModelTraits
Traits class for models.
Definition: modeltraits.hh:898
typename ModelTraits< Model >::template HasMethod< ModelIntrospection::CheckMethodTag< tag >::value > ModelHasMethod
Check for method.
Definition: modeltraits.hh:902
typename ModelTraits< Model >::template CallSignature< ModelIntrospection::CheckMethodTag< tag >::value > ModelMethodSignature
Call signature for given model and method.
Definition: modeltraits.hh:911
typename ModelTraits< Model >::template CallSignatureClosure< ModelIntrospection::CheckMethodTag< tag >::value > ModelMethodSignatureClosure
Compute the closure call-signature for the given model for a call to the method designated by tag,...
Definition: modeltraits.hh:920
STL namespace.
Gets the type of the n-th element of a tuple-like or the std::integral_constant corresponding to the ...
Definition: access.hh:42
typename IsLoadFunctor::template Apply< MethodTag, CheckMethodTag< tag >::value > IsLoad
Method defines only a load contribution.
Definition: modeltraits.hh:819
typename ExistsFunctor::template Apply< MethodTag, CheckMethodTag< tag >::value > Exists
Linearized or non-linearized method is implemented.
Definition: modeltraits.hh:801
typename IsPiecewiseConstantFunctor::template Apply< MethodTag, CheckMethodTag< tag >::value > IsPiecewiseConstant
Method does not depend on the quadrature point.
Definition: modeltraits.hh:835
typename BaseType::ModelMethods< Model > Methods
The index sequence with all implemented methods.
Definition: modeltraits.hh:757
TupleElement< tag, BaseType::MethodReturnType< Model > > ReturnType
Generate the return type for the given method tag.
Definition: modeltraits.hh:745
typename IsAffineLinearFunctor::template Apply< MethodTag, CheckMethodTag< tag >::value > IsAffineLinear
Linear method does not need point of linearization.
Definition: modeltraits.hh:860
typename IsLinearFunctor::template Apply< MethodTag, CheckMethodTag< tag >::value > IsLinear
Non-linear method is not implemented.
Definition: modeltraits.hh:846
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)