DUNE-ACFEM (unstable)

dofstorage.hh
1#ifndef __DUNE_ACFEM_OPERATORS_FUNCTIONALS_MODULES_DOFSTORAGE_HH__
2#define __DUNE_ACFEM_OPERATORS_FUNCTIONALS_MODULES_DOFSTORAGE_HH__
3
4#include "../../../expressions/terminal.hh"
5#include "../../../common/literals.hh"
6
7#include "../linearfunctional.hh"
8#include "../functionaltraits.hh"
9#include "../operations/inner.hh"
10
11namespace Dune {
12
13 namespace ACFem {
14
15 namespace LinearFunctional {
16
17 using namespace Literals;
18
20 template<class DiscreteFunction>
22 : public DiscreteFunction
23 , public LinearFunctional<typename DiscreteFunction::DiscreteFunctionSpaceType>
24 , public Expressions::SelfExpression<DofStorageFunctional<DiscreteFunction> >
25 , public ConstantExpression
26 {
28 using BaseType = DiscreteFunction;
30 public:
31 using typename FunctionalBase::DiscreteFunctionSpaceType;
32 using typename FunctionalBase::RangeFieldType;
33 using BaseType::DiscreteFunction;
34 using BaseType::space;
35 using BaseType::dbegin;
36 using BaseType::dend;
37
38 template<class Other,
39 std::enable_if_t<(IsLinearFunctional<Other>::value
41 && std::is_same<DiscreteFunctionSpaceType, typename std::decay_t<Other>::DiscreteFunctionSpaceType>::value
42 ), int> = 0>
43 DofStorageFunctional(Other&& other)
44 : BaseType("functional dof storage", other.space())
45 {
46 BaseType::clear();
47 other.coefficients(static_cast<BaseType&>(*this));
48 }
49
50 template<class Other,
51 std::enable_if_t<(IsLinearFunctional<Other>::value
53 && std::is_same<DiscreteFunctionSpaceType, typename std::decay_t<Other>::DiscreteFunctionSpaceType>::value
54 ), int> = 0>
55 ThisType& operator=(Other&& other)
56 {
57 BaseType::clear();
58 other.coefficients(1_f, static_cast<BaseType&>(*this));
59 }
60
61 template<class Other,
62 std::enable_if_t<(IsLinearFunctional<Other>::value
64 && std::is_same<DiscreteFunctionSpaceType, typename std::decay_t<Other>::DiscreteFunctionSpaceType>::value
65 ), int> = 0>
66 ThisType& operator+=(Other&& other)
67 {
68 if constexpr (!ExpressionTraits<Other>::isZero) {
69 other.coefficients(static_cast<BaseType&>(*this));
70 }
71 return *this;
72 }
73
74 template<class Other,
75 std::enable_if_t<(IsLinearFunctional<Other>::value
77 && std::is_same<DiscreteFunctionSpaceType, typename std::decay_t<Other>::DiscreteFunctionSpaceType>::value
78 ), int> = 0>
79 ThisType& operator-=(Other&& other)
80 {
81 if constexpr (!ExpressionTraits<Other>::isZero) {
82 other.coefficients(-1_f, static_cast<BaseType&>(*this));
83 }
84 return *this;
85 }
86
87 template<class FieldArg, class DF,
88 std::enable_if_t<std::is_constructible<RangeFieldType, FieldArg>::value, int> = 0>
89 ThisType& operator*=(FieldArg&& s)
90 {
92 BaseType::clear();
93 } else if constexpr (!ExpressionTraits<FieldArg>::isOne) {
94 for (auto&& dof : dofs(*this)) {
95 dof *= s;
96 }
97 }
98 return *this;
99 }
100
101 template<class FieldArg, class DF,
102 std::enable_if_t<std::is_constructible<RangeFieldType, FieldArg>::value, int> = 0>
103 void coefficients(FieldArg&& s, DF& values) const
104 {
106 values.clear();
107 } else {
108 auto dofsEnd = dend();
109 for (auto&& dof = dbegin(), dest = values.dbegin(); dof != dofsEnd; ++dof, ++dest) {
110 *dest += s * *dof;
111 }
112 }
113 }
114
115 template<class DF>
116 void coefficients(DF& df) const
117 {
118 coefficients(1_f, df);
119 }
120
121 template<class DF>
122 auto operator()(const DF& df) const
123 {
124 return inner(*this, df);
125 }
126 };
127
128 template<class DiscreteFunction>
129 class DofStorageFunctional<DiscreteFunction&>
132 {
134 using ThisType = DofStorageFunctional;
136 public:
137 using typename FunctionalBase::DiscreteFunctionSpaceType;
138 using typename FunctionalBase::RangeFieldType;
139
140 DofStorageFunctional(DiscreteFunction& dofs)
141 : dofs_(dofs)
142 {}
143
144 template<class Other,
145 std::enable_if_t<(!std::is_const<DiscreteFunction>::value
146 && IsLinearFunctional<Other>::value
148 && std::is_same<DiscreteFunctionSpaceType, typename std::decay_t<Other>::DiscreteFunctionSpaceType>::value
149 ), int> = 0>
150 ThisType& operator=(Other&& other)
151 {
152 other.coefficients(1_f, dofs_);
153 }
154
155 template<class FieldArg, class DF,
156 std::enable_if_t<std::is_constructible<RangeFieldType, FieldArg>::value, int> = 0>
157 void coefficients(FieldArg&& s, DF& values) const
158 {
159 auto&& dof = dofs_.dbegin();
160 auto&& dest = values.dbegin();
161 auto&& dofsEnd = dofs_.dend();
162 while (dof != dofsEnd) {
163 *dest += s * *dof;
164 ++dof;
165 ++dest;
166 }
167 }
168
169 template<class DF>
170 void coefficients(DF& df) const
171 {
172 coefficients(1_f, df);
173 }
174
175 template<class DF>
176 auto operator()(const DF& df) const
177 {
178 return inner(*this, df);
179 }
180
181 auto dbegin() const
182 {
183 return dofs_.dbegin();
184 }
185
186 auto dend() const
187 {
188 return dofs_.dend();
189 }
190
191 const DiscreteFunctionSpaceType& space() const
192 {
193 return dofs_.space();
194 }
195
196 std::string name() const
197 {
198 return "<Uh,.>";
199 }
200
201 operator DiscreteFunction& () &
202 {
203 return dofs_;
204 }
205
206 operator std::add_const_t<DiscreteFunction>& () const&
207 {
208 return dofs_;
209 }
210
211 operator DiscreteFunction () &&
212 {
213 return dofs_;
214 }
215
216 protected:
217 DiscreteFunction& dofs_;
218 };
219
220 template<class DiscreteFunction>
221 auto dofStorageFunctional(DiscreteFunction&& df)
222 {
223 return DofStorageFunctional<DiscreteFunction>(std::forward<DiscreteFunction>(df));
224 }
225
226 template<class DiscreteFunction, class DiscreteFunctionSpace,
227 std::enable_if_t<std::is_same<typename std::decay_t<DiscreteFunction>::DiscreteFunctionSpaceType,
228 DiscreteFunctionSpace>::value, int> = 0>
229 auto dofStorageFunctional(const DiscreteFunctionSpace& space, const std::string& name = "")
230 {
231 using DiscreteFunctionType = std::decay_t<DiscreteFunction>;
232 return expressionClosure( DofStorageFunctional<DiscreteFunctionType>(DiscreteFunctionType(name, space)));
233 }
234
235 }
236
237 using LinearFunctional::dofStorageFunctional;
238
239 } // ACFem::
240
241} // Dune::
242
243#endif // __DUNE_ACFEM_OPERATORS_FUNCTIONALS_MODULES_DOFSTORAGE_HH__
A functional which inherits from a proper discrete function.
Definition: dofstorage.hh:26
Light-weight base class for all linear functionals.
Definition: linearfunctional.hh:13
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
auto inner(T1 &&t1, T2 &&t2)
"scalar product"
Definition: expressions.hh:154
A constant.
Definition: tags.hh:93
Default expression traits definition is a recursion in order to ease disambiguation.
Definition: expressiontraits.hh:54
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
TrueType if T1 and T2 have the same decay types, otherwise FalseType.
Definition: types.hh:440
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Sep 4, 22:38, 2025)