DUNE-ACFEM (unstable)

functionalexpression.hh
1#ifndef __DUNE_ACFEM_OPERATORS_FUNCTIONALS_FUNCTIONALEXPRESSION_HH__
2#define __DUNE_ACFEM_OPERATORS_FUNCTIONALS_FUNCTIONALEXPRESSION_HH__
3
4#include "../../common/types.hh"
5#include "../../common/literals.hh"
6#include "../../expressions/operationtraits.hh"
7#include "../../tensors/tensor.hh"
8
9#include "linearfunctional.hh"
10#include "functionaltraits.hh"
11#include "closuretraits.hh"
12#include "operations/inner.hh"
13
14namespace Dune {
15
16 namespace ACFem {
17
18 namespace LinearFunctional {
19
20 using namespace Literals;
21
22 template<class Operation, class T>
23 class UnaryLinearFunctionalExpression;
24
25 template<class Operation, class T0, class T1>
26 class BinaryLinearFunctionalExpression;
27
29 template<class T>
30 class UnaryLinearFunctionalExpression<MinusOperation, T>
31 : public LinearFunctional<typename std::decay_t<T>::DiscreteFunctionSpaceType>
32 , public Expressions::Storage<OperationTraits<MinusOperation>, T>
33 {
35 using StorageType = Expressions::Storage<OperationTraits<MinusOperation>, T>;
36 public:
37 using typename BaseType::DiscreteFunctionSpaceType;
38 using typename BaseType::RangeFieldType;
39 using StorageType::operand;
40 using StorageType::operation;
41
42 template<class TArg, std::enable_if_t<std::is_constructible<T, TArg>::value, int> = 0>
43 UnaryLinearFunctionalExpression(TArg&& t)
44 : StorageType(std::forward<TArg>(t))
45 {}
46
47 template<class FieldArg, class DiscreteFunction,
48 std::enable_if_t<std::is_constructible<RangeFieldType, FieldArg>::value, int> = 0>
49 void coefficients(FieldArg&& s, DiscreteFunction& values) const
50 {
51 static_assert(std::is_same<DiscreteFunctionSpaceType, typename DiscreteFunction::DiscreteFunctionSpaceType>::value,
52 "DiscreteFunctionSpaceType of functional and discrete storage has to coincide");
53
54 operand(0_c).coefficients(-s, values);
55 }
56
57 template<class DiscreteFunction>
58 void coefficients(DiscreteFunction& values) const
59 {
60 values.clear();
61 coefficients(1_f, values);
62 }
63
64 template<class DiscreteFunction>
65 auto operator()(const DiscreteFunction& df) const
66 {
67 return inner(*this, df);
68 }
69
70 const DiscreteFunctionSpaceType& space() const
71 {
72 return arg().space();
73 }
74
75 std::string name() const
76 {
77 return operationName(operation(), arg().name());
78 }
79
80 protected:
81 using StorageType::t0_;
82 constexpr auto&& arg() && { return t0_; }
83 constexpr auto& arg() & { return t0_; }
84 constexpr const auto& arg() const& { return t0_; }
85 };
86
88 template<class Operation, class T0, class T1>
90 : public LinearFunctional<typename std::decay_t<T1>::DiscreteFunctionSpaceType>
91 , public Expressions::Storage<OperationTraits<Operation>, T0, T1>
92 {
94 using StorageType = Expressions::Storage<OperationTraits<Operation>, T0, T1>;
95 public:
96 using typename BaseType::DiscreteFunctionSpaceType;
97 using typename BaseType::RangeFieldType;
98 using StorageType::operand;
99 using StorageType::operation;
100
101 template<class T0Arg, class T1Arg,
102 std::enable_if_t<(std::is_constructible<T0, T0Arg>::value
103 && std::is_constructible<T1, T1Arg>::value
104 ), int> = 0>
105 BinaryLinearFunctionalExpression(T0Arg&& t0, T1Arg&& t1)
106 : StorageType(std::forward<T0Arg>(t0), std::forward<T1>(t1))
107 {}
108
109 template<class FieldArg, class DiscreteFunction,
110 std::enable_if_t<std::is_constructible<RangeFieldType, FieldArg>::value, int> = 0>
111 void coefficients(FieldArg&& s, DiscreteFunction& values) const
112 {
113 static_assert(std::is_same<DiscreteFunctionSpaceType, typename DiscreteFunction::DiscreteFunctionSpaceType>::value,
114 "DiscreteFunctionSpaceType of functional and discrete storage has to coincide");
115
116 // gurk it together
117 if constexpr (std::is_same<Operation, PlusOperation>::value) {
118 left().coefficients(s, values);
119 right().coefficients(s, values);
120 } else if constexpr (std::is_same<Operation, MinusOperation>::value) {
121 left().coefficients(s, values);
122 right().coefficients(-s, values);
123 } else if constexpr (std::is_same<Operation, SMultiplyOperation>::value) {
124 // The factor is always the left operand
125 right().coefficients(left()*s, values);
126 }
127 }
128
129 template<class DiscreteFunction>
130 void coefficients(DiscreteFunction& df) const
131 {
132 coefficients(1_f, df);
133 }
134
135 template<class DiscreteFunction>
136 auto operator()(const DiscreteFunction& df) const
137 {
138 return inner(*this, df);
139 }
140
141 const DiscreteFunctionSpaceType& space() const
142 {
143 return right().space();
144 }
145
146 std::string name() const
147 {
148 return operationName(operation(), left().name(), right().name());
149 }
150
151 protected:
152 using StorageType::t0_;
153 using StorageType::t1_;
154 constexpr auto&& left() && { return t0_; }
155 constexpr auto& left() & { return t0_; }
156 constexpr const auto& left() const& { return t0_; }
157 constexpr auto&& right() && { return t1_; }
158 constexpr auto& right() & { return t1_; }
159 constexpr const auto& right() const& { return t1_; }
160 };
161
162 template<class Op, class T, std::enable_if_t<IsLinearFunctional<T>::value, int> = 0>
163 constexpr auto operate(Expressions::DontOptimize, OperationTraits<Op>, T&& t)
164 {
165 DUNE_ACFEM_RECORD_OPTIMIZATION;
166
167 return UnaryLinearFunctionalExpression<Op, T>(std::forward<T>(t));
168 }
169
170 template<class Op, class T0, class T1,
171 std::enable_if_t<((IsLinearFunctional<T0>::value || TensorTraits<T0>::rank == 0)
172 && IsLinearFunctional<T1>::value
173 ), int> = 0>
174 constexpr auto operate(Expressions::DontOptimize, OperationTraits<Op>, T0&& t0, T1&& t1)
175 {
176 DUNE_ACFEM_RECORD_OPTIMIZATION;
177
178 return BinaryLinearFunctionalExpression<Op, T0, T1>(std::forward<T0>(t0), std::forward<T1>(t1));
179 }
180
181 }
182
183 } // ACFem::
184
185} // Dune::
186
187#endif // __DUNE_ACFEM_OPERATORS_FUNCTIONALS_FUNCTIONALEXPRESSION_HH__
The one and only one binary expression.
Definition: functionalexpression.hh:92
Light-weight base class for all linear functionals.
Definition: linearfunctional.hh:13
OptimizeTag< 0 > DontOptimize
Bottom level is overloaded to do nothing.
Definition: optimizationbase.hh:74
std::string operationName(F &&f, const std::string &arg)
Verbose print of an operation, helper function to produce noise.
Definition: operationtraits.hh:601
auto inner(T1 &&t1, T2 &&t2)
"scalar product"
Definition: expressions.hh:154
Subtraction of two objects and unary minus.
Definition: expressionoperations.hh:43
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 3, 22:42, 2025)