Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
userfunctions.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_FORMS_USERFUNCTIONS_HH
8#define DUNE_FUFEM_FORMS_USERFUNCTIONS_HH
9
10#include <cstddef>
11#include <type_traits>
12#include <utility>
13
17
19
20#if DUNE_VERSION_GTE(DUNE_FUNCTIONS, 2, 11)
22#else
23#include <dune/typetree/childextraction.hh>
24#endif
25
36
37
38
39
40namespace Dune::Fufem::Forms::Impl {
41
42
43
44 // ************************************************************
45 // Implementation of compose(outerOp, innerOp)
46 // ************************************************************
47
48 template<class OuterTransform, class InnerTransform, class InnerOp>
49 requires isOperator_v<InnerOp>
50 auto composeImpl(const OuterTransform& outerTransform, const TransformedOperator<InnerTransform, InnerOp>& op)
51 {
52 return TransformedOperator(LocalOperators::localCompose(outerTransform, op.transformation()), op.baseOperator());
53 }
54
55 template<class OuterOp, class InnerOp>
56 requires isOperator_v<InnerOp>
57 auto composeImpl(const OuterOp& outerOp, const InnerOp& op)
58 {
59 return TransformedOperator(outerOp, op);
60 }
61
62 template<class OuterOp, class... InnerOps>
63 auto composeImpl(const OuterOp& outerOp, const Dune::Fufem::Forms::SumOperator<InnerOps...>& innerOps)
64 {
65 if constexpr(SumOperator<InnerOps...>::arity==0)
66 return TransformedOperator(outerOp, innerOps);
67 else
68 return std::apply([&](const auto&...op_i) {
69 return Dune::Fufem::Forms::SumOperator(composeImpl(outerOp, op_i) ...);
70 }, innerOps.operators());
71 }
72
73
74
75 // ************************************************************
76 // Implementation of sum(l,r).
77 // ************************************************************
78
79 // This has four special cases to collapse nested sums
80 // and two for the case that one argument is a constant.
81
82 template<class L, class R>
83 requires (isOperator_v<L> and isOperator_v<R>)
84 auto sum(const L& l, const R& r)
85 {
86 return SumOperator<L, R>(l, r);
87 }
88
89 template<class L, class... Ri>
90 requires isOperator_v<L>
91 auto sum(const L& l, const SumOperator<Ri...>& r)
92 {
93 return std::apply([&](const auto&... ri) {
94 return SumOperator<L, Ri...>(l, ri...);
95 }, r.operators());
96 }
97
98 template<class... Li, class R>
99 requires isOperator_v<R>
100 auto sum(const SumOperator<Li...>& l, const R& r)
101 {
102 return std::apply([&](const auto&... li) {
103 return SumOperator<Li..., R>(li..., r);
104 }, l.operators());
105 }
106
107 template<class... Li, class... Rj>
108 auto sum(const SumOperator<Li...>& l, const SumOperator<Rj...>& r)
109 {
110 return std::apply([&](const auto&...li) {
111 return std::apply([&](const auto&...rj) {
112 return SumOperator<Li..., Rj...>(li..., rj...);
113 }, r.operators());
114 }, l.operators());
115 }
116
117 // Overload for for the case that R is a constant
118 template<class L, class R>
119 requires (isOperatorOrSumOperator_v<L> and not isOperatorOrSumOperator_v<R>)
120 auto sum(const L& l, const R& r)
121 {
122 return Impl::composeImpl([r](auto&& l_value) {
124 }, l);
125 }
126
127 // Overload for for the case that L is a constant
128 template<class L, class R>
129 requires (not isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
130 auto sum(const L& l, const R& r)
131 {
132 return Impl::composeImpl([l](auto&& r_value) {
134 }, r);
135 }
136
137
138
139 // ************************************************************
140 // Implementation of product(p, left, right)
141 // ************************************************************
142
143 // The following are the generic functions for producing
144 // product operators from a binary operator and two other
145 // terms. At least one of those terms should be a operator.
146
147 // Overload for two plain operators
148 template<class Op, class L, class R>
149 requires (isOperator_v<L> and isOperator_v<R>
150 and Dune::IsCallable<Op(const typename L::Range, const typename R::Range)>::value)
151 auto productImpl(const Op& op, const L& l, const R& r)
152 {
153 static_assert(L::arity+R::arity<=2, "Trying to construct multi-linear operator with arity>2");
154
155 if constexpr((L::arity==1) and (L::arity==1))
156 {
157 if constexpr(L::argIndex==1)
158 return ProductOperator(LocalOperators::TransposedBinaryOp(op), r, l);
159 else
160 return ProductOperator(op, l, r);
161 }
162 else
163 return ProductOperator(op, l, r);
164 }
165
166 // Overload for one raw value and one operator
167 // This will wrap the raw value into a operator.
168 template<class Op, class L, class R>
169 requires (not isOperatorOrSumOperator_v<L> and isOperator_v<R>
170 and Dune::IsCallable<Op(const L, const typename R::Range)>::value)
171 auto productImpl(const Op& op, const L& l, const R& r)
172 {
173 using namespace std::placeholders;
174 return composeImpl(std::bind(op, l, _1), r);
175 }
176
177 // Overload for one operator and one raw value
178 // This will wrap the raw value into a operator.
179 template<class Op, class L, class R>
180 requires (isOperator_v<L> and not isOperatorOrSumOperator_v<R>
181 and Dune::IsCallable<Op(const typename L::Range, const R)>::value)
182 auto productImpl(const Op& op, const L& l, const R& r)
183 {
184 using namespace std::placeholders;
185 return composeImpl(std::bind(op, _1, r), l);
186 }
187
188 // Overload for one sum-operator and one plain term
189 // This will multiply out the product for the sum-operator.
190 template<class Op, class... Li, class R>
191 requires requires (const Op op, const Li... li, const R r) { (productImpl(op, li, r),...); }
192 auto productImpl(const Op& op, const SumOperator<Li...>& l, const R& r)
193 {
194 return std::apply([&](const auto&... li) {
195 return (productImpl(op, li, r) + ...);
196 }, l.operators());
197 }
198
199 // Overload for one plain term and one sum-operator
200 // This will multiply out the product for the sum-operator.
201 template<class Op, class L, class... Ri>
202 requires requires (const Op op, const L l, const Ri... ri) { (productImpl(op, l, ri),...); }
203 auto productImpl(const Op& op, const L& l, const SumOperator<Ri...>& r)
204 {
205 return std::apply([&](const auto&...ri) {
206 return (productImpl(op, l, ri) + ...);
207 }, r.operators());
208 }
209
210 // Overload for two sum-operators
211 // This will multiply out the product for both sum-operators.
212 template<class Op, class... Li, class... Rj>
213 requires requires (const Op op, const Li... li, const SumOperator<Rj...> r) { (productImpl(op, li, r),...); }
214 auto productImpl(const Op& op, const SumOperator<Li...>& l, const SumOperator<Rj...>& r)
215 {
216 return std::apply([&](const auto&...li) {
217 return (productImpl(op, li, r) + ...);
218 }, l.operators());
219 }
220
221
222
223 // ************************************************************
224 // Implementation of dot(l, r).
225 // ************************************************************
226
227 // These specializations only exist for optimization of special cases.
228
229 // This is the default implementation.
230 template<class L, class R>
231 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
232 and requires (LocalOperators::DotOp dot, const L l, const R r) { productImpl(dot, l, r); })
233 auto dotImpl(const L& l, const R& r)
234 {
235 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
236 }
237
238 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
239 auto dotImpl(const FEFunctionOperator<B,TP,argIndex_L>& l, const FEFunctionOperator<B,TP,argIndex_R>& r);
240
241 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
242 auto dotImpl(const FEFunctionJacobianOperator<B,TP,argIndex_L>& l, const FEFunctionJacobianOperator<B,TP,argIndex_R>& r);
243
244 template<class InnerOp>
245 using TransposedOperator = TransformedOperator<Dune::Fufem::Forms::LocalOperators::TransposeOp, InnerOp>;
246
247 template<class L, class R>
248 auto dotImpl(const Impl::TransposedOperator<L>& l, const Impl::TransposedOperator<R>& r)
249 {
250 using namespace Dune::Indices;
251 return Dune::Fufem::Forms::Impl::dotImpl(l.baseOperator(), r.baseOperator());
252 }
253
254 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
255 auto dotImpl(const FEFunctionOperator<B,TP,argIndex_L>& l, const FEFunctionOperator<B,TP,argIndex_R>& r)
256 {
258 if constexpr (Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>)
259 {
261 [&](auto... i) {
262 return (Dune::Fufem::Forms::Impl::dotImpl(l.childOperator(i), r.childOperator(i)) + ...);
263 },
264 std::make_index_sequence<Node::degree()>{});
265 }
266 else
267 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
268 }
269
270 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
271 auto dotImpl(const FEFunctionJacobianOperator<B,TP,argIndex_L>& l, const FEFunctionJacobianOperator<B,TP,argIndex_R>& r)
272 {
274 if constexpr (Dune::Fufem::Impl::Concept::UniformInnerTreeNode<Node>)
275 {
277 [&](auto... i) {
278 return (Dune::Fufem::Forms::Impl::dotImpl(l.childOperator(i), r.childOperator(i)) + ...);
279 },
280 std::make_index_sequence<Node::degree()>{});
281 }
282 else
283 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
284 }
285
286
287
288} // namespace Dune::Fufem::Forms::Impl
289
290
291
292namespace Dune::Fufem::Forms {
293
294
295
296 // ************************************************************
297 // Linear combination of operators of the same arity
298 // ************************************************************
299
315#ifdef DOXYGEN
316 template<class L, class R>
317 auto operator+ (const L& l, const R& r);
318#else
319 // Overload for two operators of the same arity
320 template<class L, class R>
321 requires (isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
322 auto operator+ (const L& l, const R& r)
323 {
324 if constexpr (isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
325 static_assert(L::arity==R::arity, "The operators passed to operator+ do not have the same arity");
326 else if constexpr (isOperatorOrSumOperator_v<R>)
327 static_assert(R::arity==0, "Plain values can only be added to 0-linear operators");
328 else if constexpr (isOperatorOrSumOperator_v<L>)
329 static_assert(L::arity==0, "Plain values can only be added to 0-linear operators");
330 return Impl::sum(l, r);
331 }
332#endif
333
343 template<class Op>
344 requires isOperatorOrSumOperator_v<Op>
345 auto operator- (const Op& op)
346 {
347 if constexpr (requires(typename Op::Range x) { -x; })
348 return Impl::composeImpl(std::negate(), op);
349 else if constexpr (requires(typename Op::Range x) { -1*x; })
350 return Impl::composeImpl([](auto&& x) { return -1*x;}, op);
351 }
352
366#ifdef DOXYGEN
367 template<class L, class R>
368 auto operator- (const L& l, const R& r);
369#else
370 template<class L, class R>
371 requires (isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
372 auto operator- (const L& l, const R& r)
373 {
374 if constexpr (isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
375 static_assert(L::arity==R::arity, "The operators passed to operator- do not have the same arity");
376 else if constexpr (isOperatorOrSumOperator_v<R>)
377 static_assert(R::arity==0, "Differences with plain values can only be used with 0-linear operators");
378 else if constexpr (isOperatorOrSumOperator_v<L>)
379 static_assert(L::arity==0, "Differences with plain values can only be used with 0-linear operators");
380 return Impl::sum(l, -r);
381 }
382#endif
383
384
385
386 // ************************************************************
387 // Bilinear combination of operators
388 // ************************************************************
389
406 template<class Op, class L, class R>
407 auto product(const Op& op, const L& l, const R& r)
408 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
409 and requires (const Op op, const L l, const R r) { Impl::productImpl(op, l, r); })
410 {
411 return Impl::productImpl(op, l, r);
412 }
413
429 template<class L, class R, class Dummy=void>
430 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
431 and requires (LocalOperators::MultOp mult, const L l, const R r) { Impl::productImpl(mult, l, r); })
432 auto operator* (const L& l, const R& r)
433 {
434 // This overload is recursively constrained to cases where `operator*` makes sense.
435 // Otherwise Dune::dot(a,b) may be activated for operators because it relies on availability
436 // of a*b. This is a problem, because it leads to ambiguity with Forms::dot(a,b).
437 return Impl::productImpl(LocalOperators::MultOp{}, l, r);
438 }
439
455 template<class L, class R>
456 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
457 and requires (const L l, const R r) { Impl::dotImpl(l, r); })
458 auto dot(const L& l, const R& r)
459 {
460 return Impl::dotImpl(l, r);
461 }
462
463
464
465 // ************************************************************
466 // Utilities for range transformations
467 // ************************************************************
468
480 template<class OuterOp, class InnerOp>
481 requires (isOperatorOrSumOperator_v<InnerOp>
482 and requires (const OuterOp outerOp, typename InnerOp::Range inner_range) { outerOp(inner_range); })
483 auto compose(const OuterOp& outerOp, const InnerOp& innerOp)
484 {
485 return Impl::composeImpl(outerOp, innerOp);
486 }
487
488
489
508 template<class OuterOp>
510 {
511 public:
512 RangeOperator(const OuterOp& outerOp) : outerOp_(outerOp) {}
513
514 template<class Op, class... Args>
515 requires isOperatorOrSumOperator_v<Op>
516 auto operator()(Op&& baseOperator, Args... args) const
517 {
518 using namespace std::placeholders;
519 return compose(std::bind(outerOp_, _1, args...), std::forward<Op>(baseOperator));
520 }
521
522 template<class Op>
523 requires isOperatorOrSumOperator_v<Op>
524 auto operator()(Op&& baseOperator) const
525 {
526 return compose(outerOp_, std::forward<Op>(baseOperator));
527 }
528
529 template<class Arg0, class... Args>
530 requires (not isOperatorOrSumOperator_v<Arg0>)
531 auto operator()(Arg0&& arg0, Args&&... args) const
532 {
533 return outerOp_(std::forward<Arg0>(arg0), std::forward<Args>(args)...);
534 }
535
536 private:
537 OuterOp outerOp_;
538 };
539
540
541
542 // ************************************************************
543 // Predefined linear range transformations
544 // ************************************************************
545
558 template<class Op>
559 auto transpose(const Op& op)
560 {
562 }
563
576 template<class Op>
577 auto symmetrize(const Op& op)
578 {
580 }
581
594 template<class Op>
595 auto trace(const Op& op)
596 {
598 }
599
600
601
602 // ************************************************************
603 // Predefined non-linear range transformations
604 // ************************************************************
605
620 template<class Op>
621 auto inv(const Op& op)
622 {
623 if constexpr(isOperatorOrSumOperator_v<Op>)
624 static_assert(Op::arity==0, "inv(op) can only be applied to 0-linear operators");
626 }
627
645 template<class L, class R>
646 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
647 and requires (LocalOperators::MultOp mult, const L l, const R r) { product(mult, l, inv(r)); })
648 auto operator/ (const L& l, const R& r)
649 {
650 // Since inv() does not exist if R is a non-nullary operator,
651 // we don't need to guard this further here.
652 return product(LocalOperators::MultOp{}, l, inv(r));
653 }
654
655
656
657 // ************************************************************
658 // Convenience functions for creating operators
659 // ************************************************************
660
678
693 template<class Basis>
694 auto testFunction(const Basis& basis)
695 {
696 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
697 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 0>(basis.rootBasis(), basis.prefixPath());
698 }
699
716 template<class Basis>
717 auto testFunction(const Basis& basis, NonAffineFamily tag)
718 {
719 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
720 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 0>(basis.rootBasis(), basis.prefixPath(), false);
721 }
722
741 template<class Basis, class... Args>
742 requires (sizeof...(Args)>0)
743 auto testFunction(const Basis& basis, Args&&... args)
744 {
745 using LastArg = typename Dune::Functions::LastType<std::decay_t<Args>...>::type;
747 {
748 return Dune::applyPartial([&](auto&&... treePathArgs){
749 return testFunction(Dune::Functions::subspaceBasis(basis, treePathArgs...), NonAffineFamily{});
750 },
752 std::make_index_sequence<sizeof...(Args)-1>{}
753 );
754 }
755 else
756 return testFunction(Dune::Functions::subspaceBasis(basis, args...));
757 }
758
773 template<class Basis>
774 auto trialFunction(const Basis& basis)
775 {
776 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
777 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 1>(basis.rootBasis(), basis.prefixPath());
778 }
779
796 template<class Basis>
797 auto trialFunction(const Basis& basis, NonAffineFamily tag)
798 {
799 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
800 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 1>(basis.rootBasis(), basis.prefixPath(), false);
801 }
802
821 template<class Basis, class... Args>
822 requires (sizeof...(Args)>0)
823 auto trialFunction(const Basis& basis, Args&&... args)
824 {
825 using LastArg = typename Dune::Functions::LastType<std::decay_t<Args>...>::type;
827 {
828 return Dune::applyPartial([&](auto&&... treePathArgs){
829 return trialFunction(Dune::Functions::subspaceBasis(basis, treePathArgs...), NonAffineFamily{});
830 },
832 std::make_index_sequence<sizeof...(Args)-1>{}
833 );
834 }
835 else
836 return trialFunction(Dune::Functions::subspaceBasis(basis, args...));
837 }
838
862 template<class Op>
863 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
864 auto outside(const Op& op)
865 {
866 if constexpr (isOperator_v<Op>)
867 return OutsideOperator(op);
868 if constexpr (isSumOperator_v<Op>)
869 return std::apply([&](const auto&...op_i) {
871 }, op.operators());
872 }
873
887 template<class Op>
888 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
889 auto avg(const Op& op)
890 {
891 return 0.5*(op+outside(op));
892 }
893
910 template<class Op>
911 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
912 auto jump(const Op& op)
913 {
914 return op-outside(op);
915 }
916
930 template<class GridView>
931 auto meshSize(const GridView& gridView)
932 {
933 return MeshSizeOperator(gridView);
934 }
935
948 template<class GridView>
949 auto meshSize()
950 {
952 }
953
966 template<class GridView>
967 auto faceNormal(const GridView& gridView)
968 {
969 return FaceNormalOperator(gridView);
970 }
971
983 template<class GridView>
985 {
987 }
988
1008 template<class Op, class V>
1009 requires isOperatorOrSumOperator_v<Op>
1010 auto bindToCoefficients(const Op& op, V&& vector)
1011 {
1012 using Basis = std::decay_t<decltype(std::get<0>(op.basis()))>;
1013 // Small helper functions to wrap vectors using istlVectorBackend
1014 // if they do not already satisfy the VectorBackend interface.
1015 auto toConstVectorBackend = [&](auto&& v) -> decltype(auto) {
1016 if constexpr (models<Dune::Functions::Concept::ConstVectorBackend<Basis>, decltype(v)>()) {
1017 return std::forward<decltype(v)>(v);
1018 } else {
1020 }
1021 };
1022 return BoundUnaryOperator(op, toConstVectorBackend(std::forward<V>(vector)));
1023 }
1024
1025
1026
1041 template<class Op, class V>
1042 requires (isOperatorOrSumOperator_v<Op> and not isOperatorOrSumOperator_v<std::decay_t<V>>)
1043 auto operator|(const Op& op, V&& v)
1044 {
1045 return bindToCoefficients(op, std::forward<V>(v));
1046 }
1047
1048
1049
1050 // ************************************************************
1051 // Differential operators
1052 // ************************************************************
1053
1054 // Overloads for elementary operators
1055
1063 template<class B, class TP, std::size_t argIndex>
1068
1076 template<class B, class TP, std::size_t argIndex>
1081
1091 template<class B, class TP, std::size_t argIndex>
1098
1099 // Overloads for sums of operators
1100
1108 template<class... Ops>
1109 requires requires(const Ops&... ops) { SumOperator(jacobian(ops)...); }
1111 {
1112 return std::apply([&](const auto&...op) {
1113 return SumOperator(jacobian(op) ...);
1114 }, op.operators());
1115 }
1116
1124 template<class... Ops>
1125 requires requires(const Ops&... ops) { SumOperator(jacobian(ops)...); }
1127 {
1128 return std::apply([&](const auto&...op) {
1129 return SumOperator(divergence(op) ...);
1130 }, op.operators());
1131 }
1132
1142 template<class... Ops>
1143 requires requires(const Ops&... ops) { SumOperator(curl(ops)...); }
1145 {
1146 return std::apply([&](const auto&...op) {
1147 return SumOperator(curl(op) ...);
1148 }, op.operators());
1149 }
1150
1151 // Other operators that are essetially shot cuts to the others
1152
1166 template<class Op>
1167 auto gradient(const Op& op)
1168 requires requires {Fufem::Forms::transpose(jacobian(op));}
1169 {
1171 }
1172
1186 template<class Op>
1187 auto grad(const Op& op)
1188 requires requires {Fufem::Forms::transpose(jacobian(op));}
1189 {
1191 }
1192
1200 template<class Op>
1201 auto div(const Op& op)
1202 requires requires {divergence(op);}
1203 {
1204 return divergence(op);
1205 }
1206
1216 template<class Op>
1217 auto rot(const Op& op)
1218 requires requires {curl(op);}
1219 {
1220 return curl(op);
1221 }
1222
1234 template<class Op>
1235 auto D(const Op& op, std::size_t k)
1236 requires requires {grad(op);}
1237 {
1238 return compose([k](auto&& g) { return g[k]; }, grad(op));
1239 }
1240
1241
1242
1243} // namespace Dune::Fufem::Forms
1244
1245
1246#endif // DUNE_FUFEM_FORMS_USERFUNCTIONS_HH
auto istlVectorBackend(Vector &v)
auto subspaceBasis(const RootBasis &rootBasis, const TypeTree::TreePath< PrefixTreeIndices... > &prefixPath)
This header provides fallback implementations for dune-typetree<2.11.
decltype(auto) applyPartial(F &&f, ArgTuple &&args, std::integer_sequence< I, i... >)
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
size_type dim() const
auto testFunction(const Basis &basis)
Create unary identity operator on test function space.
Definition userfunctions.hh:694
auto trialFunction(const Basis &basis)
Create unary identity operator on trial function space.
Definition userfunctions.hh:774
auto meshSize()
Construct mesh size operator.
Definition userfunctions.hh:949
auto bindToCoefficients(const Op &op, V &&vector)
Bind a linear operator to a coefficient vector.
Definition userfunctions.hh:1010
auto faceNormal()
Construct operator representing the face normals.
Definition userfunctions.hh:984
auto avg(const Op &op)
Construct intersection average of a given operator.
Definition userfunctions.hh:889
auto outside(const Op &op)
Construct outside version of a given operator.
Definition userfunctions.hh:864
auto jump(const Op &op)
Construct intersection jump of a given operator.
Definition userfunctions.hh:912
auto gradient(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1167
auto divergence(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1077
auto jacobian(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the jacobian of an operator.
Definition userfunctions.hh:1064
auto div(const Op &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1201
auto curl(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the curl of an operator.
Definition userfunctions.hh:1092
auto D(const Op &op, std::size_t k)
Obtain the i-th partial derivative of an operator.
Definition userfunctions.hh:1235
auto grad(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1187
auto rot(const Op &op)
Obtain the curl of an operator.
Definition userfunctions.hh:1217
auto operator-(const Op &op)
Negate an operator.
Definition userfunctions.hh:345
auto dot(const L &l, const R &r)
Exterior product of two multilinear operators based on pointwise dot-product.
Definition userfunctions.hh:458
auto product(const Op &op, const L &l, const R &r)
Generic exterior product of two multilinear operators.
Definition userfunctions.hh:407
auto trace(const Op &op)
Transform an operator by pointwise computation of the matrix trace.
Definition userfunctions.hh:595
auto compose(const OuterOp &outerOp, const InnerOp &innerOp)
Generic composition of a multilinear operators with a pointwise outer operator.
Definition userfunctions.hh:483
auto transpose(const Op &op)
Transform an operator by pointwise matrix transposition.
Definition userfunctions.hh:559
auto symmetrize(const Op &op)
Transform an operator by pointwise matrix symmetrization.
Definition userfunctions.hh:577
auto inv(const Op &op)
Transform an operator by pointwise computation of the matrix inverse.
Definition userfunctions.hh:621
Definition baseclass.hh:22
auto localCompose(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:549
Sum of several multilinear operators.
Definition sumoperator.hh:38
auto & operators()
Definition sumoperator.hh:172
Wrapper binding a linear operator to a coefficient vector.
Definition boundunaryoperator.hh:65
Operator representing the normal field on intersection.
Definition geometryoperators.hh:41
Operator representing the mesh size of entities.
Definition geometryoperators.hh:179
Definition localoperators.hh:66
Definition localoperators.hh:250
Definition localoperators.hh:341
Definition localoperators.hh:419
Definition localoperators.hh:446
Definition localoperators.hh:456
Definition localoperators.hh:470
Operator for switching to the outside entity.
Definition outsideoperator.hh:58
auto basis() const
Definition unaryoperators.hh:179
auto treePath() const
Definition unaryoperators.hh:184
bool isAffine() const
Definition unaryoperators.hh:189
Linear map representing the elements of an FE-space.
Definition unaryoperators.hh:222
Linear map representing the jacobians of the elements of an FE-space.
Definition unaryoperators.hh:346
Linear map representing the divergenc of the elements of an FE-space.
Definition unaryoperators.hh:473
Adaptor for making a callback compatible with Dune::Fufem::Forms.
Definition userfunctions.hh:510
auto operator()(Op &&baseOperator, Args... args) const
Definition userfunctions.hh:516
RangeOperator(const OuterOp &outerOp)
Definition userfunctions.hh:512
auto operator()(Op &&baseOperator) const
Definition userfunctions.hh:524
Tag type to classify non-affine finite element families.
Definition userfunctions.hh:677
T apply(T... args)
T bind(T... args)
T forward_as_tuple(T... args)
T forward(T... args)