Dune-Fufem 2.12-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
18
20
30
31
32
33
34namespace Dune::Fufem::Forms::Impl {
35
36
37
38 // ************************************************************
39 // Implementation of compose(outerOp, innerOp)
40 // ************************************************************
41
42 template<class OuterTransform, class InnerTransform, class InnerOp>
43 requires isOperator_v<InnerOp>
44 auto composeImpl(const OuterTransform& outerTransform, const TransformedOperator<InnerTransform, InnerOp>& op)
45 {
46 return TransformedOperator(LocalOperators::localCompose(outerTransform, op.transformation()), op.baseOperator());
47 }
48
49 template<class OuterOp, class InnerOp>
50 requires isOperator_v<InnerOp>
51 auto composeImpl(const OuterOp& outerOp, const InnerOp& op)
52 {
53 return TransformedOperator(outerOp, op);
54 }
55
56 template<class OuterOp, class... InnerOps>
57 auto composeImpl(const OuterOp& outerOp, const Dune::Fufem::Forms::SumOperator<InnerOps...>& innerOps)
58 {
59 if constexpr(SumOperator<InnerOps...>::arity==0)
60 return TransformedOperator(outerOp, innerOps);
61 else
62 return std::apply([&](const auto&...op_i) {
63 return Dune::Fufem::Forms::SumOperator(composeImpl(outerOp, op_i) ...);
64 }, innerOps.operators());
65 }
66
67
68
69 // ************************************************************
70 // Implementation of sum(l,r).
71 // ************************************************************
72
73 // This has four special cases to collapse nested sums
74 // and two for the case that one argument is a constant.
75
76 template<class L, class R>
77 requires (isOperator_v<L> and isOperator_v<R>)
78 auto sum(const L& l, const R& r)
79 {
80 return SumOperator<L, R>(l, r);
81 }
82
83 template<class L, class... Ri>
84 requires isOperator_v<L>
85 auto sum(const L& l, const SumOperator<Ri...>& r)
86 {
87 return std::apply([&](const auto&... ri) {
88 return SumOperator<L, Ri...>(l, ri...);
89 }, r.operators());
90 }
91
92 template<class... Li, class R>
93 requires isOperator_v<R>
94 auto sum(const SumOperator<Li...>& l, const R& r)
95 {
96 return std::apply([&](const auto&... li) {
97 return SumOperator<Li..., R>(li..., r);
98 }, l.operators());
99 }
100
101 template<class... Li, class... Rj>
102 auto sum(const SumOperator<Li...>& l, const SumOperator<Rj...>& r)
103 {
104 return std::apply([&](const auto&...li) {
105 return std::apply([&](const auto&...rj) {
106 return SumOperator<Li..., Rj...>(li..., rj...);
107 }, r.operators());
108 }, l.operators());
109 }
110
111 // Overload for for the case that R is a constant
112 template<class L, class R>
113 requires (isOperatorOrSumOperator_v<L> and not isOperatorOrSumOperator_v<R>)
114 auto sum(const L& l, const R& r)
115 {
116 return Impl::composeImpl([r](auto&& l_value) {
118 }, l);
119 }
120
121 // Overload for for the case that L is a constant
122 template<class L, class R>
123 requires (not isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
124 auto sum(const L& l, const R& r)
125 {
126 return Impl::composeImpl([l](auto&& r_value) {
128 }, r);
129 }
130
131
132
133 // ************************************************************
134 // Implementation of product(p, left, right)
135 // ************************************************************
136
137 // The following are the generic functions for producing
138 // product operators from a binary operator and two other
139 // terms. At least one of those terms should be a operator.
140
141 // Overload for two plain operators
142 template<class Op, class L, class R>
143 requires (isOperator_v<L> and isOperator_v<R>
144 and Dune::IsCallable<Op(const typename L::Range, const typename R::Range)>::value)
145 auto productImpl(const Op& op, const L& l, const R& r)
146 {
147 static_assert(L::arity+R::arity<=2, "Trying to construct multi-linear operator with arity>2");
148
149 if constexpr((L::arity==1) and (L::arity==1))
150 {
151 if constexpr(L::argIndex==1)
152 return ProductOperator(LocalOperators::TransposedBinaryOp(op), r, l);
153 else
154 return ProductOperator(op, l, r);
155 }
156 else
157 return ProductOperator(op, l, r);
158 }
159
160 // Overload for one raw value and one operator
161 // This will wrap the raw value into a operator.
162 template<class Op, class L, class R>
163 requires (not isOperatorOrSumOperator_v<L> and isOperator_v<R>
164 and Dune::IsCallable<Op(const L, const typename R::Range)>::value)
165 auto productImpl(const Op& op, const L& l, const R& r)
166 {
167 using namespace std::placeholders;
168 return composeImpl(std::bind(op, l, _1), r);
169 }
170
171 // Overload for one operator and one raw value
172 // This will wrap the raw value into a operator.
173 template<class Op, class L, class R>
174 requires (isOperator_v<L> and not isOperatorOrSumOperator_v<R>
175 and Dune::IsCallable<Op(const typename L::Range, const R)>::value)
176 auto productImpl(const Op& op, const L& l, const R& r)
177 {
178 using namespace std::placeholders;
179 return composeImpl(std::bind(op, _1, r), l);
180 }
181
182 // Overload for one sum-operator and one plain term
183 // This will multiply out the product for the sum-operator.
184 template<class Op, class... Li, class R>
185 requires requires (const Op op, const Li... li, const R r) { (productImpl(op, li, r),...); }
186 auto productImpl(const Op& op, const SumOperator<Li...>& l, const R& r)
187 {
188 return std::apply([&](const auto&... li) {
189 return (productImpl(op, li, r) + ...);
190 }, l.operators());
191 }
192
193 // Overload for one plain term and one sum-operator
194 // This will multiply out the product for the sum-operator.
195 template<class Op, class L, class... Ri>
196 requires requires (const Op op, const L l, const Ri... ri) { (productImpl(op, l, ri),...); }
197 auto productImpl(const Op& op, const L& l, const SumOperator<Ri...>& r)
198 {
199 return std::apply([&](const auto&...ri) {
200 return (productImpl(op, l, ri) + ...);
201 }, r.operators());
202 }
203
204 // Overload for two sum-operators
205 // This will multiply out the product for both sum-operators.
206 template<class Op, class... Li, class... Rj>
207 requires requires (const Op op, const Li... li, const SumOperator<Rj...> r) { (productImpl(op, li, r),...); }
208 auto productImpl(const Op& op, const SumOperator<Li...>& l, const SumOperator<Rj...>& r)
209 {
210 return std::apply([&](const auto&...li) {
211 return (productImpl(op, li, r) + ...);
212 }, l.operators());
213 }
214
215
216
217 // ************************************************************
218 // Implementation of dot(l, r).
219 // ************************************************************
220
221 // These specializations only exist for optimization of special cases.
222
223 // This is the default implementation.
224 template<class L, class R>
225 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
226 and requires (LocalOperators::DotOp dot, const L l, const R r) { productImpl(dot, l, r); })
227 auto dotImpl(const L& l, const R& r)
228 {
229 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
230 }
231
232 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
233 auto dotImpl(const FEFunctionOperator<B,TP,argIndex_L>& l, const FEFunctionOperator<B,TP,argIndex_R>& r);
234
235 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
236 auto dotImpl(const FEFunctionJacobianOperator<B,TP,argIndex_L>& l, const FEFunctionJacobianOperator<B,TP,argIndex_R>& r);
237
238 template<class InnerOp>
239 using TransposedOperator = TransformedOperator<Dune::Fufem::Forms::LocalOperators::TransposeOp, InnerOp>;
240
241 template<class L, class R>
242 auto dotImpl(const Impl::TransposedOperator<L>& l, const Impl::TransposedOperator<R>& r)
243 {
244 using namespace Dune::Indices;
245 return Dune::Fufem::Forms::Impl::dotImpl(l.baseOperator(), r.baseOperator());
246 }
247
248 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
249 auto dotImpl(const FEFunctionOperator<B,TP,argIndex_L>& l, const FEFunctionOperator<B,TP,argIndex_R>& r)
250 {
253 {
255 [&](auto... i) {
256 return (Dune::Fufem::Forms::Impl::dotImpl(l.childOperator(i), r.childOperator(i)) + ...);
257 },
258 std::make_index_sequence<Node::degree()>{});
259 }
260 else
261 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
262 }
263
264 template<class B, class TP, std::size_t argIndex_L, std::size_t argIndex_R>
265 auto dotImpl(const FEFunctionJacobianOperator<B,TP,argIndex_L>& l, const FEFunctionJacobianOperator<B,TP,argIndex_R>& r)
266 {
269 {
271 [&](auto... i) {
272 return (Dune::Fufem::Forms::Impl::dotImpl(l.childOperator(i), r.childOperator(i)) + ...);
273 },
274 std::make_index_sequence<Node::degree()>{});
275 }
276 else
277 return productImpl(Dune::Fufem::Forms::LocalOperators::DotOp(), l, r);
278 }
279
280
281
282} // namespace Dune::Fufem::Forms::Impl
283
284
285
286namespace Dune::Fufem::Forms {
287
288
289
290 // ************************************************************
291 // Linear combination of operators of the same arity
292 // ************************************************************
293
309#ifdef DOXYGEN
310 template<class L, class R>
311 auto operator+ (const L& l, const R& r);
312#else
313 // Overload for two operators of the same arity
314 template<class L, class R>
315 requires (isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
316 auto operator+ (const L& l, const R& r)
317 {
318 if constexpr (isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
319 static_assert(L::arity==R::arity, "The operators passed to operator+ do not have the same arity");
320 else if constexpr (isOperatorOrSumOperator_v<R>)
321 static_assert(R::arity==0, "Plain values can only be added to 0-linear operators");
322 else if constexpr (isOperatorOrSumOperator_v<L>)
323 static_assert(L::arity==0, "Plain values can only be added to 0-linear operators");
324 return Impl::sum(l, r);
325 }
326#endif
327
337 template<class Op>
338 requires isOperatorOrSumOperator_v<Op>
339 auto operator- (const Op& op)
340 {
341 if constexpr (requires(typename Op::Range x) { -x; })
342 return Impl::composeImpl(std::negate(), op);
343 else if constexpr (requires(typename Op::Range x) { -1*x; })
344 return Impl::composeImpl([](auto&& x) { return -1*x;}, op);
345 }
346
360#ifdef DOXYGEN
361 template<class L, class R>
362 auto operator- (const L& l, const R& r);
363#else
364 template<class L, class R>
365 requires (isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
366 auto operator- (const L& l, const R& r)
367 {
368 if constexpr (isOperatorOrSumOperator_v<L> and isOperatorOrSumOperator_v<R>)
369 static_assert(L::arity==R::arity, "The operators passed to operator- do not have the same arity");
370 else if constexpr (isOperatorOrSumOperator_v<R>)
371 static_assert(R::arity==0, "Differences with plain values can only be used with 0-linear operators");
372 else if constexpr (isOperatorOrSumOperator_v<L>)
373 static_assert(L::arity==0, "Differences with plain values can only be used with 0-linear operators");
374 return Impl::sum(l, -r);
375 }
376#endif
377
378
379
380 // ************************************************************
381 // Bilinear combination of operators
382 // ************************************************************
383
400 template<class Op, class L, class R>
401 auto product(const Op& op, const L& l, const R& r)
402 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
403 and requires (const Op op, const L l, const R r) { Impl::productImpl(op, l, r); })
404 {
405 return Impl::productImpl(op, l, r);
406 }
407
423 template<class L, class R, class Dummy=void>
424 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
425 and requires (LocalOperators::MultOp mult, const L l, const R r) { Impl::productImpl(mult, l, r); })
426 auto operator* (const L& l, const R& r)
427 {
428 // This overload is recursively constrained to cases where `operator*` makes sense.
429 // Otherwise Dune::dot(a,b) may be activated for operators because it relies on availability
430 // of a*b. This is a problem, because it leads to ambiguity with Forms::dot(a,b).
431 return Impl::productImpl(LocalOperators::MultOp{}, l, r);
432 }
433
449 template<class L, class R>
450 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
451 and requires (const L l, const R r) { Impl::dotImpl(l, r); })
452 auto dot(const L& l, const R& r)
453 {
454 return Impl::dotImpl(l, r);
455 }
456
457
458
459 // ************************************************************
460 // Utilities for range transformations
461 // ************************************************************
462
474 template<class OuterOp, class InnerOp>
475 requires (isOperatorOrSumOperator_v<InnerOp>
476 and requires (const OuterOp outerOp, typename InnerOp::Range inner_range) { outerOp(inner_range); })
477 auto compose(const OuterOp& outerOp, const InnerOp& innerOp)
478 {
479 return Impl::composeImpl(outerOp, innerOp);
480 }
481
482
483
502 template<class OuterOp>
504 {
505 public:
506 RangeOperator(const OuterOp& outerOp) : outerOp_(outerOp) {}
507
508 template<class Op, class... Args>
509 requires isOperatorOrSumOperator_v<Op>
510 auto operator()(Op&& baseOperator, Args... args) const
511 {
512 using namespace std::placeholders;
513 return compose(std::bind(outerOp_, _1, args...), std::forward<Op>(baseOperator));
514 }
515
516 template<class Op>
517 requires isOperatorOrSumOperator_v<Op>
518 auto operator()(Op&& baseOperator) const
519 {
520 return compose(outerOp_, std::forward<Op>(baseOperator));
521 }
522
523 template<class Arg0, class... Args>
524 requires (not isOperatorOrSumOperator_v<Arg0>)
525 auto operator()(Arg0&& arg0, Args&&... args) const
526 {
527 return outerOp_(std::forward<Arg0>(arg0), std::forward<Args>(args)...);
528 }
529
530 private:
531 OuterOp outerOp_;
532 };
533
534
535
536 // ************************************************************
537 // Predefined linear range transformations
538 // ************************************************************
539
552 template<class Op>
553 auto transpose(const Op& op)
554 {
556 }
557
570 template<class Op>
571 auto symmetrize(const Op& op)
572 {
574 }
575
588 template<class Op>
589 auto trace(const Op& op)
590 {
592 }
593
594
595
596 // ************************************************************
597 // Predefined non-linear range transformations
598 // ************************************************************
599
614 template<class Op>
615 auto inv(const Op& op)
616 {
617 if constexpr(isOperatorOrSumOperator_v<Op>)
618 static_assert(Op::arity==0, "inv(op) can only be applied to 0-linear operators");
620 }
621
639 template<class L, class R>
640 requires ((isOperatorOrSumOperator_v<L> or isOperatorOrSumOperator_v<R>)
641 and requires (LocalOperators::MultOp mult, const L l, const R r) { product(mult, l, inv(r)); })
642 auto operator/ (const L& l, const R& r)
643 {
644 // Since inv() does not exist if R is a non-nullary operator,
645 // we don't need to guard this further here.
646 return product(LocalOperators::MultOp{}, l, inv(r));
647 }
648
649
650
651 // ************************************************************
652 // Convenience functions for creating operators
653 // ************************************************************
654
672
687 template<class Basis>
688 auto testFunction(const Basis& basis)
689 {
690 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
691 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 0>(basis.rootBasis(), basis.prefixPath());
692 }
693
710 template<class Basis>
711 auto testFunction(const Basis& basis, NonAffineFamily tag)
712 {
713 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
714 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 0>(basis.rootBasis(), basis.prefixPath(), false);
715 }
716
735 template<class Basis, class... Args>
736 requires (sizeof...(Args)>0)
737 auto testFunction(const Basis& basis, Args&&... args)
738 {
739 using LastArg = typename Dune::Functions::LastType<std::decay_t<Args>...>::type;
741 {
742 return Dune::applyPartial([&](auto&&... treePathArgs){
743 return testFunction(Dune::Functions::subspaceBasis(basis, treePathArgs...), NonAffineFamily{});
744 },
746 std::make_index_sequence<sizeof...(Args)-1>{}
747 );
748 }
749 else
750 return testFunction(Dune::Functions::subspaceBasis(basis, args...));
751 }
752
767 template<class Basis>
768 auto trialFunction(const Basis& basis)
769 {
770 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
771 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 1>(basis.rootBasis(), basis.prefixPath());
772 }
773
790 template<class Basis>
791 auto trialFunction(const Basis& basis, NonAffineFamily tag)
792 {
793 using RootBasis = std::decay_t<decltype(basis.rootBasis())>;
794 return FEFunctionOperator<RootBasis, typename Basis::PrefixPath, 1>(basis.rootBasis(), basis.prefixPath(), false);
795 }
796
815 template<class Basis, class... Args>
816 requires (sizeof...(Args)>0)
817 auto trialFunction(const Basis& basis, Args&&... args)
818 {
819 using LastArg = typename Dune::Functions::LastType<std::decay_t<Args>...>::type;
821 {
822 return Dune::applyPartial([&](auto&&... treePathArgs){
823 return trialFunction(Dune::Functions::subspaceBasis(basis, treePathArgs...), NonAffineFamily{});
824 },
826 std::make_index_sequence<sizeof...(Args)-1>{}
827 );
828 }
829 else
830 return trialFunction(Dune::Functions::subspaceBasis(basis, args...));
831 }
832
856 template<class Op>
857 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
858 auto outside(const Op& op)
859 {
860 if constexpr (isOperator_v<Op>)
861 return OutsideOperator(op);
862 if constexpr (isSumOperator_v<Op>)
863 return std::apply([&](const auto&...op_i) {
865 }, op.operators());
866 }
867
881 template<class Op>
882 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
883 auto avg(const Op& op)
884 {
885 return 0.5*(op+outside(op));
886 }
887
904 template<class Op>
905 requires (isOperatorOrSumOperator_v<Op> and (Op::arity<=1))
906 auto jump(const Op& op)
907 {
908 return op-outside(op);
909 }
910
924 template<class GridView>
925 auto meshSize(const GridView& gridView)
926 {
927 return MeshSizeOperator(gridView);
928 }
929
942 template<class GridView>
943 auto meshSize()
944 {
946 }
947
960 template<class GridView>
961 auto faceNormal(const GridView& gridView)
962 {
963 return FaceNormalOperator(gridView);
964 }
965
977 template<class GridView>
979 {
981 }
982
1002 template<class Op, class V>
1003 requires isOperatorOrSumOperator_v<Op>
1004 auto bindToCoefficients(const Op& op, V&& vector)
1005 {
1006 using Basis = std::decay_t<decltype(std::get<0>(op.basis()))>;
1007 // Small helper functions to wrap vectors using istlVectorBackend
1008 // if they do not already satisfy the VectorBackend interface.
1009 auto toConstVectorBackend = [&](auto&& v) -> decltype(auto) {
1010 if constexpr (models<Dune::Functions::Concept::ConstVectorBackend<Basis>, decltype(v)>()) {
1011 return std::forward<decltype(v)>(v);
1012 } else {
1014 }
1015 };
1016 return BoundUnaryOperator(op, toConstVectorBackend(std::forward<V>(vector)));
1017 }
1018
1019
1020
1035 template<class Op, class V>
1036 requires (isOperatorOrSumOperator_v<Op> and not isOperatorOrSumOperator_v<std::decay_t<V>>)
1037 auto operator|(const Op& op, V&& v)
1038 {
1039 return bindToCoefficients(op, std::forward<V>(v));
1040 }
1041
1042
1043
1044 // ************************************************************
1045 // Differential operators
1046 // ************************************************************
1047
1048 // Overloads for elementary operators
1049
1057 template<class B, class TP, std::size_t argIndex>
1059 {
1061 }
1062
1070 template<class B, class TP, std::size_t argIndex>
1072 {
1074 }
1075
1085 template<class B, class TP, std::size_t argIndex>
1087 {
1089 static_assert(dim==2 or dim==3);
1091 }
1092
1093 // Overloads for sums of operators
1094
1102 template<class... Ops>
1103 requires requires(const Ops&... ops) { SumOperator(jacobian(ops)...); }
1105 {
1106 return std::apply([&](const auto&...op) {
1107 return SumOperator(jacobian(op) ...);
1108 }, op.operators());
1109 }
1110
1118 template<class... Ops>
1119 requires requires(const Ops&... ops) { SumOperator(jacobian(ops)...); }
1121 {
1122 return std::apply([&](const auto&...op) {
1123 return SumOperator(divergence(op) ...);
1124 }, op.operators());
1125 }
1126
1136 template<class... Ops>
1137 requires requires(const Ops&... ops) { SumOperator(curl(ops)...); }
1139 {
1140 return std::apply([&](const auto&...op) {
1141 return SumOperator(curl(op) ...);
1142 }, op.operators());
1143 }
1144
1145 // Other operators that are essetially shot cuts to the others
1146
1160 template<class Op>
1161 auto gradient(const Op& op)
1162 requires requires {Fufem::Forms::transpose(jacobian(op));}
1163 {
1165 }
1166
1180 template<class Op>
1181 auto grad(const Op& op)
1182 requires requires {Fufem::Forms::transpose(jacobian(op));}
1183 {
1185 }
1186
1194 template<class Op>
1195 auto div(const Op& op)
1196 requires requires {divergence(op);}
1197 {
1198 return divergence(op);
1199 }
1200
1210 template<class Op>
1211 auto rot(const Op& op)
1212 requires requires {curl(op);}
1213 {
1214 return curl(op);
1215 }
1216
1228 template<class Op>
1229 auto D(const Op& op, std::size_t k)
1230 requires requires {grad(op);}
1231 {
1232 return compose([k](auto&& g) { return g[k]; }, grad(op));
1233 }
1234
1235
1236
1237} // namespace Dune::Fufem::Forms
1238
1239
1240#endif // DUNE_FUFEM_FORMS_USERFUNCTIONS_HH
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
T apply(T... args)
T bind(T... args)
Wrapper binding a linear operator to a coefficient vector.
Definition boundunaryoperator.hh:56
Linear map representing the divergenc of the elements of an FE-space.
Definition unaryoperators.hh:467
Linear map representing the jacobians of the elements of an FE-space.
Definition unaryoperators.hh:340
Linear map representing the elements of an FE-space.
Definition unaryoperators.hh:216
auto basis() const
Definition unaryoperators.hh:173
auto treePath() const
Definition unaryoperators.hh:178
bool isAffine() const
Definition unaryoperators.hh:183
Operator representing the normal field on intersection.
Definition geometryoperators.hh:41
Operator representing the mesh size of entities.
Definition geometryoperators.hh:179
Tag type to classify non-affine finite element families.
Definition userfunctions.hh:671
Operator for switching to the outside entity.
Definition outsideoperator.hh:58
Adaptor for making a callback compatible with Dune::Fufem::Forms.
Definition userfunctions.hh:504
auto operator()(Op &&baseOperator, Args... args) const
Definition userfunctions.hh:510
RangeOperator(const OuterOp &outerOp)
Definition userfunctions.hh:506
auto operator()(Op &&baseOperator) const
Definition userfunctions.hh:518
Sum of several multilinear operators.
Definition sumoperator.hh:38
auto & operators()
Definition sumoperator.hh:172
T forward_as_tuple(T... args)
T forward(T... args)
auto operator-(const Op &op)
Negate an operator.
Definition userfunctions.hh:339
auto dot(const L &l, const R &r)
Exterior product of two multilinear operators based on pointwise dot-product.
Definition userfunctions.hh:452
auto product(const Op &op, const L &l, const R &r)
Generic exterior product of two multilinear operators.
Definition userfunctions.hh:401
auto gradient(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1161
auto divergence(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1071
auto jacobian(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the jacobian of an operator.
Definition userfunctions.hh:1058
auto div(const Op &op)
Obtain the divergence of an operator.
Definition userfunctions.hh:1195
auto curl(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the curl of an operator.
Definition userfunctions.hh:1086
auto D(const Op &op, std::size_t k)
Obtain the i-th partial derivative of an operator.
Definition userfunctions.hh:1229
auto grad(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1181
auto rot(const Op &op)
Obtain the curl of an operator.
Definition userfunctions.hh:1211
auto testFunction(const Basis &basis)
Create unary identity operator on test function space.
Definition userfunctions.hh:688
auto trialFunction(const Basis &basis)
Create unary identity operator on trial function space.
Definition userfunctions.hh:768
auto meshSize()
Construct mesh size operator.
Definition userfunctions.hh:943
auto bindToCoefficients(const Op &op, V &&vector)
Bind a linear operator to a coefficient vector.
Definition userfunctions.hh:1004
auto faceNormal()
Construct operator representing the face normals.
Definition userfunctions.hh:978
auto avg(const Op &op)
Construct intersection average of a given operator.
Definition userfunctions.hh:883
auto outside(const Op &op)
Construct outside version of a given operator.
Definition userfunctions.hh:858
auto jump(const Op &op)
Construct intersection jump of a given operator.
Definition userfunctions.hh:906
auto trace(const Op &op)
Transform an operator by pointwise computation of the matrix trace.
Definition userfunctions.hh:589
auto compose(const OuterOp &outerOp, const InnerOp &innerOp)
Generic composition of a multilinear operators with a pointwise outer operator.
Definition userfunctions.hh:477
auto transpose(const Op &op)
Transform an operator by pointwise matrix transposition.
Definition userfunctions.hh:553
auto symmetrize(const Op &op)
Transform an operator by pointwise matrix symmetrization.
Definition userfunctions.hh:571
auto inv(const Op &op)
Transform an operator by pointwise computation of the matrix inverse.
Definition userfunctions.hh:615
auto istlVectorBackend(Vector &v)
auto localCompose(const OuterOp &outerOp, const InnerOp &innerOp)
Definition localoperators.hh:617
Definition baseclass.hh:22
auto subspaceBasis(const RootBasis &rootBasis, const TypeTree::TreePath< PrefixTreeIndices... > &prefixPath)
Definition localoperators.hh:278
Definition localoperators.hh:538
Definition localoperators.hh:397
Definition localoperators.hh:66
Definition localoperators.hh:514
Definition localoperators.hh:524
Definition localoperators.hh:487