Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
transformedoperator.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_TRANSFORMEDOPERATOR_HH
8#define DUNE_FUFEM_FORMS_TRANSFORMEDOPERATOR_HH
9
10#include <cstddef>
11#include <type_traits>
12#include <tuple>
13#include <utility>
14#include <functional>
15
19
20
21
22namespace Dune::Fufem::Forms::Impl {
23
24 template<class Operator, int arity = Operator::arity>
25 struct TransformedOperatorBaseTraits
26 {
27 using type = MultilinearOperator<arity>;
28 };
29
30 template<class Operator>
31 struct TransformedOperatorBaseTraits<Operator, 1>
32 {
33 using type = UnaryOperator<Operator::argIndex>;
34 };
35
36} // namespace Dune::Fufem::Forms::Impl
37
38
39
40namespace Dune::Fufem::Forms {
41
42
43
52 template<class Op, class BaseOperator>
54 : public Impl::TransformedOperatorBaseTraits<BaseOperator>::type
55 {
56 using Transformation = Op;
57 using BaseLocalOperator = decltype(localOperator(std::declval<BaseOperator>()));
58
59 public:
60
61 using Element = typename BaseOperator::Element;
63
64 TransformedOperator(const BaseOperator& baseOperator) :
65 baseOperator_(baseOperator),
66 transformation_()
67 {}
68
69 TransformedOperator(const Transformation& transformation, const BaseOperator& baseOperator) :
70 baseOperator_(baseOperator),
71 transformation_(transformation)
72 {}
73
74 class LocalOperator : public BaseLocalOperator
75 {
76 public:
77
80
81 LocalOperator(const Transformation& transformation, BaseLocalOperator&& baseLocalOperator) :
82 BaseLocalOperator(std::move(baseLocalOperator)),
83 transformation_(transformation)
84 {}
85
87 {
88 return compose(std::cref(transformation_), BaseLocalOperator::operator()(index));
89 }
90
91 private:
92 Transformation transformation_;
93 };
94
95 friend LocalOperator localOperator(const TransformedOperator& transformedOperator)
96 {
97 return LocalOperator(transformedOperator.transformation(), localOperator(transformedOperator.baseOperator()));
98 }
99
100 template<bool dummy=true, std::enable_if_t<dummy and (TransformedOperator::arity==0), int> = 0>
102 {
103 return LocalFunctionAdaptor<LocalOperator>(localOperator(transformedOperator));
104 }
105
106 auto basis() const
107 {
108 return baseOperator_.basis();
109 }
110
111 auto treePath() const
112 {
113 return baseOperator_.treePath();
114 }
115
116 const BaseOperator& baseOperator() const
117 {
118 return baseOperator_;
119 }
120
121 const Transformation& transformation() const
122 {
123 return transformation_;
124 }
125
126 friend auto gradient(const TransformedOperator& f)
127 {
128 static constexpr auto dimension = Element::Geometry::Coordinate::dimension;
129 static_assert(dimension<4);
130
131 auto gradientTransformation = [transformation = f.transformation()](const auto& g) {
132 static_assert(dimension<=3, "The gradient of a transformed operator is not implemented for range dimensions > 3.");
133 if constexpr (dimension==1)
134 return std::array{transformation(g[0])};
135 else if constexpr (dimension==2)
136 return std::array{transformation(g[0]), transformation(g[1])};
137 else if constexpr (dimension==3)
138 return std::array{transformation(g[0]), transformation(g[1]), transformation(g[2])};
139 };
140 return compose(gradientTransformation, gradient(f.baseOperator()));
141 }
142
143 friend auto grad(const TransformedOperator& f)
144 {
145 return gradient(f);
146 }
147
148 private:
149 BaseOperator baseOperator_;
150 Transformation transformation_;
151 };
152
153
154
155} // namespace Dune::Fufem::Forms
156
157
158#endif // DUNE_FUFEM_FORMS_TRANSFORMEDOPERATOR_HH
std::ptrdiff_t index() const
auto compose(const OuterOp &outerOp, const InnerOp &innerOp)
Generic composition of a multilinear operators with a pointwise outer operator.
Definition userfunctions.hh:483
STL namespace.
Definition baseclass.hh:22
Adaptor for turning a Fufem::Forms LocalOperator into a LocalFunction.
Definition localfunctionadaptor.hh:42
Pointwise transformation of a multilinear operator.
Definition transformedoperator.hh:55
auto basis() const
Definition transformedoperator.hh:106
typename BaseOperator::Element Element
Definition transformedoperator.hh:61
auto treePath() const
Definition transformedoperator.hh:111
friend auto grad(const TransformedOperator &f)
Definition transformedoperator.hh:143
TransformedOperator(const BaseOperator &baseOperator)
Definition transformedoperator.hh:64
decltype(std::declval< Op >()(std::declval< typename BaseOperator::Range >())) Range
Definition transformedoperator.hh:62
const Transformation & transformation() const
Definition transformedoperator.hh:121
friend LocalOperator localOperator(const TransformedOperator &transformedOperator)
Definition transformedoperator.hh:95
TransformedOperator(const Transformation &transformation, const BaseOperator &baseOperator)
Definition transformedoperator.hh:69
friend auto gradient(const TransformedOperator &f)
Definition transformedoperator.hh:126
friend LocalFunctionAdaptor< LocalOperator > localFunction(const TransformedOperator &transformedOperator)
Definition transformedoperator.hh:101
const BaseOperator & baseOperator() const
Definition transformedoperator.hh:116
Definition transformedoperator.hh:75
typename TransformedOperator::Element Element
Definition transformedoperator.hh:78
auto operator()(std::size_t index) const
Definition transformedoperator.hh:86
LocalOperator(const Transformation &transformation, BaseLocalOperator &&baseLocalOperator)
Definition transformedoperator.hh:81
typename TransformedOperator::Range Range
Definition transformedoperator.hh:79
T forward(T... args)
T cref(T... args)