DUNE-ACFEM (2.5.1)

operatorpartsoperations.hh
1#ifndef __DUNE_ACFEM_OPERATORPARTSOPERATIONS_HH__
2#define __DUNE_ACFEM_OPERATORPARTSOPERATIONS_HH__
3
4#include "../../expressions/expressionoperations.hh"
5
6namespace Dune
7{
8
9 namespace ACFem
10 {
11
12 template<class Operation>
13 struct OperatorPartsExpressionOperation
14 {};
15
16 template<class Operation>
17 struct UnaryOperatorPartsExpressionOperation
18 : public OperatorPartsExpressionOperation<Operation>
19 {};
20
21 template<class Operation>
22 struct BinaryOperatorPartsExpressionOperation
23 : public OperatorPartsExpressionOperation<Operation>
24 {};
25
27 //
28 // Addition
29
30 template<>
31 struct BinaryOperatorPartsExpressionOperation<PlusOperation>
32 : public OperatorPartsExpressionOperation<PlusOperation>
33 {
34 //flux
35 template<class LeftOperand, class RightOperand,
36 class PointType, class RangeType, class JacobianRangeType,
37 class Entity>
38 static void flux(const LeftOperand& f, const RightOperand& g,
39 const Entity &entity, const PointType& x,
40 const RangeType &value, const JacobianRangeType& jacobian,
41 JacobianRangeType& ret)
42 {
43 JacobianRangeType tmp;
44
45 f.flux(entity, x, value, jacobian, ret);
46 if (RightOperand::hasFlux) {
47 g.flux(entity, x, value, jacobian, tmp);
48 ret += tmp;
49 }
50 }
51
52 //linearizedFlux
53 template<class LeftOperand, class RightOperand,
54 class PointType, class RangeType, class JacobianRangeType,
55 class Entity>
56 static void linearizedFlux (const LeftOperand& f, const RightOperand& g,
57 const RangeType& uBar, const JacobianRangeType& DuBar,
58 const Entity &entity,const PointType& x,
59 const RangeType &value, const JacobianRangeType& jacobian,
60 JacobianRangeType& ret)
61 {
62 JacobianRangeType tmp;
63
64 f.linearizedFlux(uBar, DuBar, entity, x, value, jacobian, ret);
65 if (RightOperand::hasFlux) {
66 g.linearizedFlux(uBar, DuBar, entity, x, value, jacobian, tmp);
67 ret += tmp;
68 }
69 }
70
71 //source
72 template<class LeftOperand, class RightOperand,
73 class PointType, class RangeType, class JacobianRangeType, class Entity>
74 static void source(const LeftOperand& f, const RightOperand& g,
75 const Entity &entity, const PointType& x,
76 const RangeType& value, const JacobianRangeType& jacobian,
77 RangeType& ret)
78 {
79 RangeType tmp;
80
81 f.source(entity, x, value, jacobian, ret);
82 if (RightOperand::hasSources) {
83 g.source(entity, x, value, jacobian, tmp);
84 ret += tmp;
85 }
86 }
87
88 //linearizedSource
89 template<class LeftOperand, class RightOperand,
90 class PointType, class RangeType, class JacobianRangeType,
91 class Entity>
92 static void linearizedSource(const LeftOperand& f, const RightOperand& g,
93 const RangeType& uBar, const JacobianRangeType& DuBar,
94 const Entity &entity,const PointType& x,
95 const RangeType& value, const JacobianRangeType& jacobian,
96 RangeType& ret)
97 {
98 RangeType tmp;
99
100 f.linearizedSource(uBar, DuBar, entity, x, value, jacobian, ret);
101 if (RightOperand::hasSources) {
102 g.linearizedSource(uBar, DuBar, entity, x, value, jacobian, tmp);
103 ret += tmp;
104 }
105 }
106
107 // fluxDivergence
108 template<class LeftOperand, class RightOperand,
109 class PointType, class RangeType, class JacobianRangeType, class HessianRangeType,
110 class Entity>
111 static void fluxDivergence(const LeftOperand& f, const RightOperand& g,
112 const Entity &entity, const PointType& x,
113 const RangeType& value, const JacobianRangeType& jacobian,
114 const HessianRangeType& hessian,
115 RangeType& ret)
116 {
117 RangeType tmp;
118
119 f.fluxDivergence(entity, x, value, jacobian, hessian, ret);
120 if (RightOperand::hasFlux) {
121 g.fluxDivergence(entity, x, value, jacobian, hessian, tmp);
122 ret += tmp;
123 }
124 }
125
126 // Robin b.c., non-linear
127 template<class LeftOperand, class RightOperand,
128 class Intersection, class Point,
129 class DomainType, class RangeType>
130 static void robinFlux(const LeftOperand& left, const RightOperand& right,
131 const Intersection& intersection,
132 const Point& x,
133 const DomainType& unitOuterNormal,
134 const RangeType& value,
135 RangeType& result)
136 {
137 RangeType tmp;
138
139 left.robinFlux(intersection, x, unitOuterNormal, value, result);
140 if (RightOperand::hasRobinFlux) {
141 right.robinFlux(intersection, x, unitOuterNormal, value, tmp);
142 result += tmp;
143 }
144 }
145
146 // Robin b.c., linearization
147 template<class LeftOperand, class RightOperand,
148 class Intersection, class Point,
149 class DomainType, class RangeType>
150 static void linearizedRobinFlux(const LeftOperand& left,
151 const RightOperand& right,
152 const RangeType& uBar,
153 const Intersection& intersection,
154 const Point& x,
155 const DomainType& unitOuterNormal,
156 const RangeType& value,
157 RangeType& result)
158 {
159 RangeType tmp;
160
161 left.linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
162 if (RightOperand::hasRobinFlux) {
163 right.linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, tmp);
164 result += tmp;
165 }
166 }
167 };
168
169
171 //
172 // Subtraction
173
174 template<>
175 struct BinaryOperatorPartsExpressionOperation<MinusOperation>
176 : public OperatorPartsExpressionOperation<MinusOperation>
177 {
178 //flux
179 template<class LeftOperand, class RightOperand,
180 class PointType, class RangeType, class JacobianRangeType,
181 class Entity>
182 static void flux(const LeftOperand& f, const RightOperand& g,
183 const Entity &entity, const PointType& x,
184 const RangeType& value, const JacobianRangeType& jacobian,
185 JacobianRangeType& ret)
186 {
187 JacobianRangeType tmp;
188
189 f.flux(entity, x, value, jacobian, ret);
190 if (RightOperand::hasFlux) {
191 g.flux(entity, x, value, jacobian, tmp);
192 ret -= tmp;
193 }
194 }
195
196 //linearizedFlux
197 template<class LeftOperand, class RightOperand,
198 class PointType, class RangeType, class JacobianRangeType,
199 class Entity>
200 static void linearizedFlux(const LeftOperand& f, const RightOperand& g,
201 const RangeType& uBar, const JacobianRangeType& DuBar,
202 const Entity &entity, const PointType& x,
203 const RangeType &value, const JacobianRangeType& jacobian,
204 JacobianRangeType& ret)
205 {
206 JacobianRangeType tmp;
207
208 f.linearizedFlux(uBar, DuBar, entity, x, value, jacobian, ret);
209 if (RightOperand::hasFlux) {
210 g.linearizedFlux(uBar, DuBar, entity, x, value, jacobian, tmp);
211 ret -= tmp;
212 }
213 }
214
215 //source
216 template<class LeftOperand, class RightOperand,
217 class PointType, class RangeType, class JacobianRangeType,
218 class Entity>
219 static void source(const LeftOperand& f, const RightOperand& g,
220 const Entity &entity, const PointType& x,
221 const RangeType& value, const JacobianRangeType& jacobian,
222 RangeType& ret)
223 {
224 RangeType tmp;
225
226 f.source(entity, x, value, jacobian, ret);
227 if (RightOperand::hasSources) {
228 g.source(entity, x, value, jacobian, tmp);
229 ret -= tmp;
230 }
231 }
232
233 //linearizedSource
234 template<class LeftOperand, class RightOperand,
235 class PointType, class RangeType, class JacobianRangeType,
236 class Entity>
237 static void linearizedSource(const LeftOperand& f, const RightOperand& g,
238 const RangeType uBar, const JacobianRangeType DuBar,
239 const Entity &entity, const PointType& x,
240 const RangeType &value, const JacobianRangeType& jacobian,
241 RangeType& ret)
242 {
243 RangeType tmp;
244
245 f.linearizedSource(uBar, DuBar, entity, x, value, jacobian, ret);
246 if (RightOperand::hasSources) {
247 g.linearizedSource(uBar, DuBar, entity, x, value, jacobian, tmp);
248 ret -= tmp;
249 }
250 }
251
252 //fluxDivergence
253 template<class LeftOperand, class RightOperand,
254 class PointType, class RangeType, class JacobianRangeType, class HessianRangeType,
255 class Entity>
256 static void fluxDivergence(const LeftOperand& f, const RightOperand& g,
257 const Entity &entity, const PointType& x,
258 const RangeType &value, const JacobianRangeType& jacobian,
259 const HessianRangeType& hessian,
260 RangeType& ret)
261 {
262 RangeType tmp;
263
264 f.fluxDivergence(entity, x, value, jacobian, hessian, ret);
265 if (RightOperand::hasFlux) {
266 g.fluxDivergence(entity, x, value, jacobian, hessian, tmp);
267 ret -= tmp;
268 }
269 }
270
271 // Robin b.c., non-linear
272 template<class LeftOperand, class RightOperand,
273 class Intersection, class Point,
274 class DomainType, class RangeType>
275 static void robinFlux(const LeftOperand& left, const RightOperand& right,
276 const Intersection& intersection,
277 const Point& x,
278 const DomainType& unitOuterNormal,
279 const RangeType& value,
280 RangeType& result)
281 {
282 RangeType tmp;
283
284 left.robinFlux(intersection, x, unitOuterNormal, value, result);
285 if (RightOperand::hasRobinFlux) {
286 // If left is also Zero then the result is already correct.
287 right.robinFlux(intersection, x, unitOuterNormal, value, tmp);
288 result -= tmp;
289 }
290 }
291
292 // Robin b.c., linearization
293 template<class LeftOperand, class RightOperand,
294 class Intersection, class Point,
295 class DomainType, class RangeType>
296 static void linearizedRobinFlux(const LeftOperand& left,
297 const RightOperand& right,
298 const RangeType& uBar,
299 const Intersection& intersection,
300 const Point& x,
301 const DomainType& unitOuterNormal,
302 const RangeType& value,
303 RangeType& result)
304 {
305 RangeType tmp;
306
307 left.linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, result);
308 if (RightOperand::hasRobinFlux) {
309 right.linearizedRobinFlux(uBar, intersection, x, unitOuterNormal, value, tmp);
310 result -= tmp;
311 }
312 }
313 };
314
315 } // namespace ACFem
316
317} // namespace Dune
318
319#endif // __DUNE_ACFEM_OPERATORPARTSOPERATIONS_HH__
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden & Uni Heidelberg  |  generated with Hugo v0.111.3 (Mar 12, 23:28, 2025)