DUNE PDELab (2.7)

combinedoperator.hh
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=8 sw=2 sts=2:
3#ifndef DUNE_PDELAB_LOCALOPERATOR_COMBINEDOPERATOR_HH
4#define DUNE_PDELAB_LOCALOPERATOR_COMBINEDOPERATOR_HH
5
6#include <cstddef>
7
8#include <tuple>
11
12#include <dune/pdelab/localoperator/callswitch.hh>
13
14namespace Dune {
15 namespace PDELab {
16
20
22
28 template<typename ApplyOp, typename... Args>
30 {
31 protected:
32 using ArgPtrs = std::tuple<std::shared_ptr<std::remove_reference_t<Args>>...>;
33 using ArgRefs = std::tuple<Args&...>;
34
35 ArgPtrs lops;
36
37 template<typename... FArgs>
38 void applyLops(FArgs &... args) const
39 {
40 static_cast<const ApplyOp&>(*this).applyLops(args...);
41 }
42
43 public:
45 //
48 //
49
51
52 CombinedOperator(Args&... args) : lops(stackobject_to_shared_ptr(args)...) {}
53
54 CombinedOperator(Args&&... args) : lops(std::make_shared<Args>(std::move(args))...) {}
55
56 protected:
57 // CombinedOperator(const ArgPtrs & l) : lops(l) {}
58 CombinedOperator(ArgPtrs && l) : lops(std::move(l)) {}
59 public:
60
62 template<std::size_t i>
63 void setSummand(typename std::tuple_element_t<i,ArgRefs> summand)
64 { std::get<i>(lops) = &summand; }
65
67 template<std::size_t i>
68 typename std::tuple_element_t<i,ArgRefs> getSummand()
69 { return *std::get<i>(lops); }
70
72
74 //
77 //
78
79 private:
80 // we only evaluate the one-/two-sided flags, if a skeleton term is to be evaluated
81 template<typename T>
82 using OneSidedSkeleton = std::integral_constant
83 < bool, ( ( T::doAlphaSkeleton || T::doLambdaSkeleton) && ! T::doSkeletonTwoSided)>;
84 template<typename T>
85 using TwoSidedSkeleton = std::integral_constant
86 < bool, ( ( T::doAlphaSkeleton || T::doLambdaSkeleton) && T::doSkeletonTwoSided)>;
87
88 public:
91 enum { doPatternVolume =
92 std::disjunction_v<std::integral_constant<bool,Args::doPatternVolume>...> };
93
97 enum { doPatternVolumePostSkeleton =
98 std::disjunction_v<std::integral_constant<bool,Args::doPatternVolumePostSkeleton>...> };
102 enum { doPatternSkeleton =
103 std::disjunction_v<std::integral_constant<bool,Args::doPatternSkeleton>...> };
107 enum { doPatternBoundary =
108 std::disjunction_v<std::integral_constant<bool,Args::doPatternBoundary>...> };
109
111
114 enum { doAlphaVolume =
115 std::disjunction_v<std::integral_constant<bool,Args::doAlphaVolume>...> };
120 enum { doAlphaVolumePostSkeleton =
121 std::disjunction_v<std::integral_constant<bool,Args::doAlphaVolumePostSkeleton>...> };
124 enum { doAlphaSkeleton =
125 std::disjunction_v<std::integral_constant<bool,Args::doAlphaSkeleton>...> };
128 enum { doAlphaBoundary =
129 std::disjunction_v<std::integral_constant<bool,Args::doAlphaBoundary>...> };
130
132 enum { doLambdaVolume =
133 std::disjunction_v<std::integral_constant<bool,Args::doLambdaVolume>...> };
136 enum { doLambdaVolumePostSkeleton =
137 std::disjunction_v<std::integral_constant<bool,Args::doLambdaVolumePostSkeleton>...> };
139 enum { doLambdaSkeleton =
140 std::disjunction_v<std::integral_constant<bool,Args::doLambdaSkeleton>...> };
142 enum { doLambdaBoundary =
143 std::disjunction_v<std::integral_constant<bool,Args::doLambdaBoundary>...> };
144
146 enum { doSkeletonTwoSided =
147 std::disjunction_v<TwoSidedSkeleton<Args>...> };
148 static_assert(!(std::conjunction_v<OneSidedSkeleton<Args>...> &&
149 std::conjunction_v<TwoSidedSkeleton<Args>...>),
150 "Some summands require a one-sided skelton, others a "
151 "two-sided skeleton. This is not supported.");
152
154 enum { isLinear = std::conjunction_v<std::integral_constant<bool,Args::isLinear>...> };
155
157
159 //
162 //
163
165
170 template<typename LFSU, typename LFSV, typename LocalPattern>
172 ( const LFSU& lfsu, const LFSV& lfsv,
173 LocalPattern& pattern) const
174 {
175 applyLops(LocalOperatorApply::patternVolume, lfsu, lfsv, pattern);
176 }
177
180
185 template<typename LFSU, typename LFSV, typename LocalPattern>
187 ( const LFSU& lfsu, const LFSV& lfsv,
188 LocalPattern& pattern) const
189 {
190 applyLops(LocalOperatorApply::patternVolumePostSkeleton, lfsu, lfsv, pattern);
191 }
192
194
199 template<typename LFSU, typename LFSV, typename LocalPattern>
201 ( const LFSU& lfsu_s, const LFSV& lfsv_s,
202 const LFSU& lfsu_n, const LFSV& lfsv_n,
203 LocalPattern& pattern_sn,
204 LocalPattern& pattern_ns) const
205 {
206 applyLops(LocalOperatorApply::patternSkeleton,
207 lfsu_s, lfsv_s, lfsu_n, lfsv_n,
208 pattern_sn, pattern_ns);
209 }
210
212
217 template<typename LFSU, typename LFSV, typename LocalPattern>
219 ( const LFSU& lfsu_s, const LFSV& lfsv_s,
220 LocalPattern& pattern_ss) const
221 {
222 applyLops(LocalOperatorApply::patternBoundary, lfsu_s, lfsv_s, pattern_ss);
223 }
224
226
228 //
231 //
232
234
238 template<typename EG, typename LFSU, typename X, typename LFSV,
239 typename R>
241 ( const EG& eg,
242 const LFSU& lfsu, const X& x, const LFSV& lfsv,
243 R& r) const
244 {
245 applyLops(LocalOperatorApply::alphaVolume, eg, lfsu, x, lfsv, r);
246 }
247
250
254 template<typename EG, typename LFSU, typename X, typename LFSV,
255 typename R>
257 ( const EG& eg,
258 const LFSU& lfsu, const X& x, const LFSV& lfsv,
259 R& r) const
260 {
261 applyLops(LocalOperatorApply::alphaVolumePostSkeleton, eg, lfsu, x, lfsv, r);
262 }
263
265
269 template<typename IG, typename LFSU, typename X, typename LFSV,
270 typename R>
272 ( const IG& ig,
273 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
274 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
275 R& r_s, R& r_n) const
276 {
277 applyLops(LocalOperatorApply::alphaSkeleton, ig,
278 lfsu_s, x_s, lfsv_s,
279 lfsu_n, x_n, lfsv_n,
280 r_s, r_n);
281 }
282
284
288 template<typename IG, typename LFSU, typename X, typename LFSV,
289 typename R>
291 ( const IG& ig,
292 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
293 R& r_s) const
294 {
295 applyLops(LocalOperatorApply::alphaVolumePostSkeleton, ig, lfsu_s, x_s, lfsv_s, r_s);
296 }
297
299
301 //
304 //
305
307
311 template<typename EG, typename LFSV, typename R>
312 void lambda_volume(const EG& eg, const LFSV& lfsv, R& r) const
313 {
314 applyLops(LocalOperatorApply::lambdaVolume, eg, lfsv, r);
315 }
316
319
323 template<typename EG, typename LFSV, typename R>
325 const LFSV& lfsv,
326 R& r) const
327 {
328 applyLops(LocalOperatorApply::lambdaVolumePostSkeleton, eg, lfsv, r);
329 }
330
332
336 template<typename IG, typename LFSV, typename R>
337 void lambda_skeleton(const IG& ig,
338 const LFSV& lfsv_s, const LFSV& lfsv_n,
339 R& r_s, R& r_n) const
340 {
341 applyLops(LocalOperatorApply::lambdaSkeleton, ig, lfsv_s, lfsv_n, r_s, r_n);
342 }
343
345
349 template<typename IG, typename LFSV, typename R>
350 void lambda_boundary(const IG& ig, const LFSV& lfsv_s, R& r_s) const
351 {
352 applyLops(LocalOperatorApply::lambdaBoundary, ig, lfsv_s, r_s);
353 }
354
356
358 //
361 //
362
364
368 template<typename EG, typename LFSU, typename X, typename LFSV,
369 typename Y>
371 ( const EG& eg,
372 const LFSU& lfsu, const X& x, const LFSV& lfsv,
373 Y& y) const
374 {
375 applyLops(LocalOperatorApply::jacobianApplyVolume, eg, lfsu, x, lfsv, y);
376 }
377
380
384 template<typename EG, typename LFSU, typename X, typename LFSV,
385 typename Y>
387 ( const EG& eg,
388 const LFSU& lfsu, const X& x, const LFSV& lfsv,
389 Y& y) const
390 {
391 applyLops(LocalOperatorApply::jacobianApplyVolumePostSkeleton, eg, lfsu, x, lfsv, y);
392 }
393
395
399 template<typename IG, typename LFSU, typename X, typename LFSV,
400 typename Y>
402 ( const IG& ig,
403 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
404 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
405 Y& y_s, Y& y_n) const
406 {
407 applyLops(LocalOperatorApply::jacobianApplySkeleton, ig,
408 lfsu_s, x_s, lfsv_s,
409 lfsu_n, x_n, lfsv_n,
410 y_s, y_n);
411 }
412
414
418 template<typename IG, typename LFSU, typename X, typename LFSV,
419 typename Y>
421 ( const IG& ig,
422 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
423 Y& y_s) const
424 {
425 applyLops(LocalOperatorApply::jacobianApplyBoundary, ig, lfsu_s, x_s, lfsv_s, y_s);
426 }
427
429
431 //
434 //
435
437
441 template<typename EG, typename LFSU, typename X, typename LFSV,
442 typename LocalMatrix>
444 ( const EG& eg,
445 const LFSU& lfsu, const X& x, const LFSV& lfsv,
446 LocalMatrix& mat) const
447 {
448 applyLops(LocalOperatorApply::jacobianVolume, eg, lfsu, x, lfsv, mat);
449 }
450
452
456 template<typename EG, typename LFSU, typename X, typename LFSV,
457 typename LocalMatrix>
459 ( const EG& eg,
460 const LFSU& lfsu, const X& x, const LFSV& lfsv,
461 LocalMatrix& mat) const
462 {
463 applyLops(LocalOperatorApply::jacobianVolumePostSkeleton, eg, lfsu, x, lfsv, mat);
464 }
465
467
471 template<typename IG, typename LFSU, typename X, typename LFSV,
472 typename LocalMatrix>
474 ( const IG& ig,
475 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
476 const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
477 LocalMatrix& mat_ss, LocalMatrix& mat_sn,
478 LocalMatrix& mat_ns, LocalMatrix& mat_nn) const
479 {
480 applyLops(LocalOperatorApply::jacobianSkeleton, ig,
481 lfsu_s, x_s, lfsv_s,
482 lfsu_n, x_n, lfsv_n,
483 mat_ss, mat_sn, mat_ns, mat_nn);
484 }
485
487
491 template<typename IG, typename LFSU, typename X, typename LFSV,
492 typename LocalMatrix>
494 ( const IG& ig,
495 const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
496 LocalMatrix& mat_ss) const
497 {
498 applyLops(LocalOperatorApply::jacobianBoundary, ig, lfsu_s, x_s, lfsv_s, mat_ss);
499 }
500
502
504 //
507 //
508
510 typedef typename std::tuple_element<0, std::tuple<Args...>>::type::RealType RealType;
511
512 private:
513 // template meta program helpers for the methods related to instationary
514 // stuff
515
516 struct Apply {
517 template<typename LOP>
518 static void setTime(const LOP& lop, RealType t)
519 {
520 lop.setTime(t);
521 }
522
523 template<typename LOP>
524 static void preStep(const LOP& lop,
525 RealType time, RealType dt, int stages)
526 {
527 lop.preStep(time, dt, stages);
528 }
529
530 template<typename LOP>
531 static void postStep(const LOP& lop)
532 {
533 lop.postStep();
534 }
535
536 template<typename LOP>
537 static void preStage(const LOP& lop, RealType time, int r)
538 {
539 lop.preStage(time, r);
540 }
541
542 template<typename LOP>
543 static void postStage(const LOP& lop)
544 {
545 lop.postStage();
546 }
547
548 template<typename LOP>
549 static RealType suggestTimestep(const LOP& lop, RealType & dt)
550 {
551 dt = std::min(dt,lop.suggestTimestep(dt));
552 }
553 };
554
555 public:
558 {
559 applyLops(Apply::setTime, t);
560 }
561
564 {
565 return get<0>(lops)->getTime();
566 }
567
569 void preStep (RealType time, RealType dt, int stages)
570 {
571 applyLops(Apply::preStep, time, dt, stages);
572 }
573
575 void postStep ()
576 {
577 applyLops(Apply::postStep, lops);
578 }
579
581 void preStage (RealType time, int r)
582 {
583 applyLops(Apply::preStage, time, r);
584 }
585
587 int getStage () const
588 {
589 return get<0>(lops)->getStage();
590 }
591
593 void postStage ()
594 {
595 applyLops(Apply::postStage, lops);
596 }
597
599
605 {
606 applyLops(Apply::suggestTimestep, dt);
607 return dt;
608 }
609
611 };
612
613 }
614}
615
616#endif // DUNE_PDELAB_LOCALOPERATOR_COMBINEDOPERATOR_HH
A local operator to take combine different local operators.
Definition: combinedoperator.hh:30
A dense matrix for storing data associated with the degrees of freedom of a pair of LocalFunctionSpac...
Definition: localmatrix.hh:184
Traits for type conversions and type information.
void jacobian_apply_skeleton(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const X &x_n, const LFSV &lfsv_n, Y &y_s, Y &y_n) const
apply an internal intersections's jacobians
Definition: combinedoperator.hh:402
void pattern_volume(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element's contribution to the sparsity pattern
Definition: combinedoperator.hh:172
RealType suggestTimestep(RealType dt) const
to be called after stage 1
Definition: combinedoperator.hh:604
RealType getTime() const
get current time
Definition: combinedoperator.hh:563
void jacobian_apply_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, Y &y_s) const
apply a boundary intersections's jacobian
Definition: combinedoperator.hh:421
void lambda_volume(const EG &eg, const LFSV &lfsv, R &r) const
get an element's contribution to lambda
Definition: combinedoperator.hh:312
void pattern_skeleton(const LFSU &lfsu_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const LFSV &lfsv_n, LocalPattern &pattern_sn, LocalPattern &pattern_ns) const
get an internal intersection's contribution to the sparsity pattern
Definition: combinedoperator.hh:201
void jacobian_apply_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, Y &y) const
apply an element's jacobian
Definition: combinedoperator.hh:371
void alpha_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, R &r) const
get an element's contribution to alpha after the intersections have been handled
Definition: combinedoperator.hh:257
void pattern_boundary(const LFSU &lfsu_s, const LFSV &lfsv_s, LocalPattern &pattern_ss) const
get a boundary intersection's contribution to the sparsity pattern
Definition: combinedoperator.hh:219
void jacobian_skeleton(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const X &x_n, const LFSV &lfsv_n, LocalMatrix &mat_ss, LocalMatrix &mat_sn, LocalMatrix &mat_ns, LocalMatrix &mat_nn) const
apply an internal intersections's jacobians
Definition: combinedoperator.hh:474
void postStep()
to be called once at the end of each time step
Definition: combinedoperator.hh:575
void lambda_volume_post_skeleton(const EG &eg, const LFSV &lfsv, R &r) const
get an element's contribution to lambda after the intersections have been handled
Definition: combinedoperator.hh:324
void preStage(RealType time, int r)
to be called once before each stage
Definition: combinedoperator.hh:581
void jacobian_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, LocalMatrix &mat_ss) const
get a boundary intersections's jacobian
Definition: combinedoperator.hh:494
std::tuple_element_t< i, ArgRefs > getSummand()
get the i'th component of the sum
Definition: combinedoperator.hh:68
int getStage() const
get current stage
Definition: combinedoperator.hh:587
void jacobian_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, LocalMatrix &mat) const
get an element's jacobian
Definition: combinedoperator.hh:444
void alpha_skeleton(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const X &x_n, const LFSV &lfsv_n, R &r_s, R &r_n) const
get an internal intersections's contribution to alpha
Definition: combinedoperator.hh:272
void postStage()
to be called once at the end of each stage
Definition: combinedoperator.hh:593
void setSummand(typename std::tuple_element_t< i, ArgRefs > summand)
set the i'th component of the sum
Definition: combinedoperator.hh:63
void pattern_volume_post_skeleton(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element's contribution to the sparsity pattern after the intersections have been handled
Definition: combinedoperator.hh:187
std::tuple_element< 0, std::tuple< Args... > >::type::RealType RealType
Export type used for time values.
Definition: combinedoperator.hh:510
void preStep(RealType time, RealType dt, int stages)
to be called once before each time step
Definition: combinedoperator.hh:569
void lambda_skeleton(const IG &ig, const LFSV &lfsv_s, const LFSV &lfsv_n, R &r_s, R &r_n) const
get an internal intersections's contribution to lambda
Definition: combinedoperator.hh:337
void lambda_boundary(const IG &ig, const LFSV &lfsv_s, R &r_s) const
get a boundary intersections's contribution to lambda
Definition: combinedoperator.hh:350
void jacobian_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, LocalMatrix &mat) const
get an element's jacobian after the intersections have been handled
Definition: combinedoperator.hh:459
void setTime(RealType t)
set time for subsequent evaluation
Definition: combinedoperator.hh:557
void jacobian_apply_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, Y &y) const
apply an element's jacobian after the intersections have been handled
Definition: combinedoperator.hh:387
void alpha_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, R &r_s) const
get a boundary intersections's contribution to alpha
Definition: combinedoperator.hh:291
void alpha_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, R &r) const
get an element's contribution to alpha
Definition: combinedoperator.hh:241
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:87
Dune namespace.
Definition: alignedallocator.hh:14
shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:75
Contains utility classes which can be used with std::tuple.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)