dune-pdelab  2.0.0
sum.hh
Go to the documentation of this file.
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_SUM_HH
4 #define DUNE_PDELAB_LOCALOPERATOR_SUM_HH
5 
6 #include <cstddef>
7 
8 #include <dune/common/forloop.hh>
9 #include <dune/common/static_assert.hh>
10 #include <dune/common/tuples.hh>
11 #include <dune/common/tupleutility.hh>
12 #include <dune/common/typetraits.hh>
13 
15 
16 namespace Dune {
17  namespace PDELab {
21 
23 
29  template<typename Args>
31  {
32  static const std::size_t size = tuple_size<Args>::value;
33 
34  typedef typename ForEachType<AddPtrTypeEvaluator, Args>::Type ArgPtrs;
35  typedef typename ForEachType<AddRefTypeEvaluator, Args>::Type ArgRefs;
36 
37  ArgPtrs lops;
38 
39  public:
41  //
44  //
45 
48  InstationarySumLocalOperator(const ArgRefs& lops_)
49  : lops(transformTuple<AddPtrTypeEvaluator>(lops_))
50  { }
51 
53  template<std::size_t i>
54  void setSummand(typename tuple_element<i,Args>::type& summand)
55  { get<i>(lops) = &summand; }
56 
58  template<std::size_t i>
59  typename tuple_element<i,Args>::type& getSummand()
60  { return *get<i>(lops); }
61 
63 
65  //
68  //
69 
70  private:
71  template<typename T1, typename T2>
72  struct OrOperation
73  : public integral_constant<bool, T1::value || T2:: value>
74  { };
75  template<template<int> class Value>
76  struct AccFlag : public GenericForLoop<OrOperation, Value, 0, size-1>
77  { };
78 
79  template<int i>
80  struct PatternVolumeValue : public integral_constant
81  < bool, tuple_element<i, Args>::type::doPatternVolume>
82  { };
83  template<int i>
84  struct PatternVolumePostSkeletonValue : public integral_constant
85  < bool, tuple_element<i, Args>::type::doPatternVolumePostSkeleton>
86  { };
87  template<int i>
88  struct PatternSkeletonValue : public integral_constant
89  < bool, tuple_element<i, Args>::type::doPatternSkeleton>
90  { };
91  template<int i>
92  struct PatternBoundaryValue : public integral_constant
93  < bool, tuple_element<i, Args>::type::doPatternBoundary>
94  { };
95 
96  template<int i>
97  struct AlphaVolumeValue : public integral_constant
98  < bool, tuple_element<i, Args>::type::doAlphaVolume>
99  { };
100  template<int i>
101  struct AlphaVolumePostSkeletonValue : public integral_constant
102  < bool, tuple_element<i, Args>::type::doAlphaVolumePostSkeleton>
103  { };
104  template<int i>
105  struct AlphaSkeletonValue : public integral_constant
106  < bool, tuple_element<i, Args>::type::doAlphaSkeleton>
107  { };
108  template<int i>
109  struct AlphaBoundaryValue : public integral_constant
110  < bool, tuple_element<i, Args>::type::doAlphaBoundary>
111  { };
112 
113  template<int i>
114  struct LambdaVolumeValue : public integral_constant
115  < bool, tuple_element<i, Args>::type::doLambdaVolume>
116  { };
117  template<int i>
118  struct LambdaVolumePostSkeletonValue : public integral_constant
119  < bool, tuple_element<i, Args>::type::doLambdaVolumePostSkeleton>
120  { };
121  template<int i>
122  struct LambdaSkeletonValue : public integral_constant
123  < bool, tuple_element<i, Args>::type::doLambdaSkeleton>
124  { };
125  template<int i>
126  struct LambdaBoundaryValue : public integral_constant
127  < bool, tuple_element<i, Args>::type::doLambdaBoundary>
128  { };
129 
130  template<int i>
131  struct OneSidedSkeletonRequiredValue : public integral_constant
132  < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
133  tuple_element<i, Args>::type::doLambdaSkeleton) &&
134  ! tuple_element<i, Args>::type::doSkeletonTwoSided)>
135  { };
136  template<int i>
137  struct TwoSidedSkeletonRequiredValue : public integral_constant
138  < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
139  tuple_element<i, Args>::type::doLambdaSkeleton) &&
140  tuple_element<i, Args>::type::doSkeletonTwoSided)>
141  { };
142 
143  public:
163 
166  enum { doAlphaVolume =
182 
184  enum { doLambdaVolume =
196 
202  "Some summands require a one-sided skelton, others a "
203  "two-sided skeleton. This is not supported.");
204 
206 
208  //
211  //
212 
213  private:
214  // template meta program helpers for the pattern_* methods
215 
216  template<int i>
217  struct PatternVolumeOperation {
218  template<typename LFSU, typename LFSV, typename LocalPattern>
219  static void apply(const ArgPtrs& lops,
220  const LFSU& lfsu, const LFSV& lfsv,
221  LocalPattern& pattern)
222  {
224  tuple_element<i,Args>::type::doPatternVolume>::
225  pattern_volume(*get<i>(lops), lfsu, lfsv, pattern);
226  }
227  };
228 
229  template<int i>
230  struct PatternVolumePostSkeletonOperation {
231  template<typename LFSU, typename LFSV, typename LocalPattern>
232  static void apply(const ArgPtrs& lops,
233  const LFSU& lfsu, const LFSV& lfsv,
234  LocalPattern& pattern)
235  {
236  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
237  tuple_element<i,Args>::type::doPatternVolumePostSkeleton>::
238  pattern_volume_post_skeleton(*get<i>(lops), lfsu, lfsv, pattern);
239  }
240  };
241 
242  template<int i>
243  struct PatternSkeletonOperation {
244  template<typename LFSU, typename LFSV, typename LocalPattern>
245  static void apply(const ArgPtrs& lops,
246  const LFSU& lfsu_s, const LFSV& lfsv_s,
247  const LFSU& lfsu_n, const LFSV& lfsv_n,
248  LocalPattern& pattern_sn,
249  LocalPattern& pattern_ns)
250  {
251  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
252  tuple_element<i,Args>::type::doPatternSkeleton>::
253  pattern_skeleton(*get<i>(lops),
254  lfsu_s, lfsv_s, lfsu_n, lfsv_n,
255  pattern_sn, pattern_ns);
256  }
257  };
258 
259  template<int i>
260  struct PatternBoundaryOperation {
261  template<typename LFSU, typename LFSV, typename LocalPattern>
262  static void apply(const ArgPtrs& lops,
263  const LFSU& lfsu_s, const LFSV& lfsv_s,
264  LocalPattern& pattern_ss)
265  {
266  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
267  tuple_element<i,Args>::type::doPatternBoundary>::
268  pattern_boundary(*get<i>(lops), lfsu_s, lfsv_s, pattern_ss);
269  }
270  };
271 
272  public:
274 
279  template<typename LFSU, typename LFSV, typename LocalPattern>
280  void pattern_volume
281  ( const LFSU& lfsu, const LFSV& lfsv,
282  LocalPattern& pattern) const
283  {
284  ForLoop<PatternVolumeOperation, 0, size-1>::
285  apply(lops, lfsu, lfsv, pattern);
286  }
287 
290 
295  template<typename LFSU, typename LFSV, typename LocalPattern>
297  ( const LFSU& lfsu, const LFSV& lfsv,
298  LocalPattern& pattern) const
299  {
300  ForLoop<PatternVolumePostSkeletonOperation, 0, size-1>::
301  apply(lops, lfsu, lfsv, pattern);
302  }
303 
305 
310  template<typename LFSU, typename LFSV, typename LocalPattern>
311  void pattern_skeleton
312  ( const LFSU& lfsu_s, const LFSV& lfsv_s,
313  const LFSU& lfsu_n, const LFSV& lfsv_n,
314  LocalPattern& pattern_sn,
315  LocalPattern& pattern_ns) const
316  {
317  ForLoop<PatternSkeletonOperation, 0, size-1>::
318  apply(lops, lfsu_s, lfsv_s, lfsu_n, lfsv_n,
319  pattern_sn, pattern_ns);
320  }
321 
323 
328  template<typename LFSU, typename LFSV, typename LocalPattern>
329  void pattern_boundary
330  ( const LFSU& lfsu_s, const LFSV& lfsv_s,
331  LocalPattern& pattern_ss) const
332  {
333  ForLoop<PatternBoundaryOperation, 0, size-1>::
334  apply(lops, lfsu_s, lfsv_s, pattern_ss);
335  }
336 
338 
340  //
343  //
344 
345  private:
346  // template meta program helpers for the alpha_* methods
347 
348  template<int i>
349  struct AlphaVolumeOperation {
350  template<typename EG, typename LFSU, typename X, typename LFSV,
351  typename R>
352  static void apply(const ArgPtrs& lops, const EG& eg,
353  const LFSU& lfsu, const X& x, const LFSV& lfsv,
354  R& r)
355  {
357  tuple_element<i,Args>::type::doAlphaVolume>::
358  alpha_volume(*get<i>(lops), eg, lfsu, x, lfsv, r);
359  }
360  };
361 
362  template<int i>
363  struct AlphaVolumePostSkeletonOperation {
364  template<typename EG, typename LFSU, typename X, typename LFSV,
365  typename R>
366  static void apply(const ArgPtrs& lops, const EG& eg,
367  const LFSU& lfsu, const X& x, const LFSV& lfsv,
368  R& r)
369  {
370  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
371  tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>::
372  alpha_volume_post_skeleton(*get<i>(lops), eg,
373  lfsu, x, lfsv,
374  r);
375  }
376  };
377 
378  template<int i>
379  struct AlphaSkeletonOperation {
380  template<typename IG, typename LFSU, typename X, typename LFSV,
381  typename R>
382  static void apply(const ArgPtrs& lops, const IG& ig,
383  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
384  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
385  R& r_s, R& r_n)
386  {
387  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
388  tuple_element<i,Args>::type::doAlphaSkeleton>::
389  alpha_skeleton(*get<i>(lops), ig,
390  lfsu_s, x_s, lfsv_s,
391  lfsu_n, x_n, lfsv_n,
392  r_s, r_n);
393  }
394  };
395 
396  template<int i>
397  struct AlphaBoundaryOperation {
398  template<typename IG, typename LFSU, typename X, typename LFSV,
399  typename R>
400  static void apply(const ArgPtrs& lops, const IG& ig,
401  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
402  R& r_s)
403  {
404  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
405  tuple_element<i,Args>::type::doAlphaBoundary>::
406  alpha_boundary(*get<i>(lops), ig, lfsu_s, x_s, lfsv_s, r_s);
407  }
408  };
409 
410  public:
412 
416  template<typename EG, typename LFSU, typename X, typename LFSV,
417  typename R>
418  void alpha_volume
419  ( const EG& eg,
420  const LFSU& lfsu, const X& x, const LFSV& lfsv,
421  R& r) const
422  {
423  ForLoop<AlphaVolumeOperation, 0, size-1>::
424  apply(lops, eg, lfsu, x, lfsv, r);
425  }
426 
429 
433  template<typename EG, typename LFSU, typename X, typename LFSV,
434  typename R>
436  ( const EG& eg,
437  const LFSU& lfsu, const X& x, const LFSV& lfsv,
438  R& r) const
439  {
440  ForLoop<AlphaVolumePostSkeletonOperation, 0, size-1>::
441  apply(lops, eg, lfsu, x, lfsv, r);
442  }
443 
445 
449  template<typename IG, typename LFSU, typename X, typename LFSV,
450  typename R>
451  void alpha_skeleton
452  ( const IG& ig,
453  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
454  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
455  R& r_s, R& r_n) const
456  {
457  ForLoop<AlphaSkeletonOperation, 0, size-1>::
458  apply(lops, ig,
459  lfsu_s, x_s, lfsv_s,
460  lfsu_n, x_n, lfsv_n,
461  r_s, r_n);
462  }
463 
465 
469  template<typename IG, typename LFSU, typename X, typename LFSV,
470  typename R>
471  void alpha_boundary
472  ( const IG& ig,
473  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
474  R& r_s) const
475  {
476  ForLoop<AlphaVolumePostSkeletonOperation, 0, size-1>::
477  apply(lops, ig, lfsu_s, x_s, lfsv_s, r_s);
478  }
479 
481 
483  //
486  //
487 
488  private:
489  // template meta program helpers for the lambda_* methods
490 
491  template<int i>
492  struct LambdaVolumeOperation {
493  template<typename EG, typename LFSV, typename R>
494  static void apply(const ArgPtrs& lops, const EG& eg,
495  const LFSV& lfsv,
496  R& r)
497  {
499  tuple_element<i,Args>::type::doLambdaVolume>::
500  lambda_volume(*get<i>(lops), eg, lfsv, r);
501  }
502  };
503 
504  template<int i>
505  struct LambdaVolumePostSkeletonOperation {
506  template<typename EG, typename LFSV, typename R>
507  static void apply(const ArgPtrs& lops, const EG& eg,
508  const LFSV& lfsv,
509  R& r)
510  {
511  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
512  tuple_element<i,Args>::type::doLambdaVolumePostSkeleton>::
513  lambda_volume_post_skeleton(*get<i>(lops), eg, lfsv, r);
514  }
515  };
516 
517  template<int i>
518  struct LambdaSkeletonOperation {
519  template<typename IG, typename LFSV, typename R>
520  static void apply(const ArgPtrs& lops, const IG& ig,
521  const LFSV& lfsv_s,
522  const LFSV& lfsv_n,
523  R& r_s, R& r_n)
524  {
525  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
526  tuple_element<i,Args>::type::doLambdaSkeleton>::
527  lambda_skeleton(*get<i>(lops), ig,
528  lfsv_s, lfsv_n,
529  r_s, r_n);
530  }
531  };
532 
533  template<int i>
534  struct LambdaBoundaryOperation {
535  template<typename IG, typename LFSV, typename R>
536  static void apply(const ArgPtrs& lops, const IG& ig,
537  const LFSV& lfsv_s,
538  R& r_s)
539  {
540  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
541  tuple_element<i,Args>::type::doLambdaBoundary>::
542  lambda_boundary(*get<i>(lops), ig, lfsv_s, r_s);
543  }
544  };
545 
546  public:
548 
552  template<typename EG, typename LFSV, typename R>
553  void lambda_volume(const EG& eg, const LFSV& lfsv, R& r) const
554  {
555  ForLoop<LambdaVolumeOperation, 0, size-1>::
556  apply(lops, eg, lfsv, r);
557  }
558 
561 
565  template<typename EG, typename LFSV, typename R>
566  void lambda_volume_post_skeleton(const EG& eg,
567  const LFSV& lfsv,
568  R& r) const
569  {
570  ForLoop<LambdaVolumePostSkeletonOperation, 0, size-1>::
571  apply(lops, eg, lfsv, r);
572  }
573 
575 
579  template<typename IG, typename LFSV, typename R>
580  void lambda_skeleton(const IG& ig,
581  const LFSV& lfsv_s, const LFSV& lfsv_n,
582  R& r_s, R& r_n) const
583  {
584  ForLoop<LambdaSkeletonOperation, 0, size-1>::
585  apply(lops, ig, lfsv_s, lfsv_n, r_s, r_n);
586  }
587 
589 
593  template<typename IG, typename LFSV, typename R>
594  void lambda_boundary(const IG& ig, const LFSV& lfsv_s, R& r_s) const
595  {
596  ForLoop<LambdaBoundaryOperation, 0, size-1>::
597  apply(lops, ig, lfsv_s, r_s);
598  }
599 
601 
603  //
606  //
607 
608  private:
609  // template meta program helpers for the jacobian_apply_* methods
610 
611  template<int i>
612  struct JacobianApplyVolumeOperation {
613  template<typename EG, typename LFSU, typename X, typename LFSV,
614  typename Y>
615  static void apply(const ArgPtrs& lops, const EG& eg,
616  const LFSU& lfsu, const X& x, const LFSV& lfsv,
617  Y& y)
618  {
620  tuple_element<i,Args>::type::doAlphaVolume>::
621  jacobian_apply_volume(*get<i>(lops), eg, lfsu, x, lfsv, y);
622  }
623  };
624 
625  template<int i>
626  struct JacobianApplyVolumePostSkeletonOperation {
627  template<typename EG, typename LFSU, typename X, typename LFSV,
628  typename Y>
629  static void apply(const ArgPtrs& lops, const EG& eg,
630  const LFSU& lfsu, const X& x, const LFSV& lfsv,
631  Y& y)
632  {
633  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
634  tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>::
635  jacobian_apply_volume_post_skeleton(*get<i>(lops), eg,
636  lfsu, x, lfsv,
637  y);
638  }
639  };
640 
641  template<int i>
642  struct JacobianApplySkeletonOperation {
643  template<typename IG, typename LFSU, typename X, typename LFSV,
644  typename Y>
645  static void apply(const ArgPtrs& lops, const IG& ig,
646  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
647  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
648  Y& y_s, Y& y_n)
649  {
650  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
651  tuple_element<i,Args>::type::doAlphaSkeleton>::
652  jacobian_apply_skeleton(*get<i>(lops), ig,
653  lfsu_s, x_s, lfsv_s,
654  lfsu_n, x_n, lfsv_n,
655  y_s, y_n);
656  }
657  };
658 
659  template<int i>
660  struct JacobianApplyBoundaryOperation {
661  template<typename IG, typename LFSU, typename X, typename LFSV,
662  typename Y>
663  static void apply(const ArgPtrs& lops, const IG& ig,
664  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
665  Y& y_s)
666  {
667  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
668  tuple_element<i,Args>::type::doAlphaBoundary>::
669  jacobian_apply_boundary(*get<i>(lops), ig,
670  lfsu_s, x_s, lfsv_s,
671  y_s);
672  }
673  };
674 
675  public:
677 
681  template<typename EG, typename LFSU, typename X, typename LFSV,
682  typename Y>
684  ( const EG& eg,
685  const LFSU& lfsu, const X& x, const LFSV& lfsv,
686  Y& y) const
687  {
688  ForLoop<JacobianApplyVolumeOperation, 0, size-1>::
689  apply(lops, eg, lfsu, x, lfsv, y);
690  }
691 
694 
698  template<typename EG, typename LFSU, typename X, typename LFSV,
699  typename Y>
701  ( const EG& eg,
702  const LFSU& lfsu, const X& x, const LFSV& lfsv,
703  Y& y) const
704  {
705  ForLoop<JacobianApplyVolumePostSkeletonOperation, 0, size-1>::
706  apply(lops, eg, lfsu, x, lfsv, y);
707  }
708 
710 
714  template<typename IG, typename LFSU, typename X, typename LFSV,
715  typename Y>
717  ( const IG& ig,
718  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
719  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
720  Y& y_s, Y& y_n) const
721  {
722  ForLoop<JacobianApplySkeletonOperation, 0, size-1>::
723  apply(lops, ig,
724  lfsu_s, x_s, lfsv_s,
725  lfsu_n, x_n, lfsv_n,
726  y_s, y_n);
727  }
728 
730 
734  template<typename IG, typename LFSU, typename X, typename LFSV,
735  typename Y>
737  ( const IG& ig,
738  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
739  Y& y_s) const
740  {
741  ForLoop<JacobianApplyBoundaryOperation, 0, size-1>::
742  apply(lops, ig, lfsu_s, x_s, lfsv_s, y_s);
743  }
744 
746 
748  //
751  //
752 
753  private:
754  // template meta program helpers for the jacobian_apply_* methods
755 
756  template<int i>
757  struct JacobianVolumeOperation {
758  template<typename EG, typename LFSU, typename X, typename LFSV,
759  typename LocalMatrix>
760  static void apply(const ArgPtrs& lops, const EG& eg,
761  const LFSU& lfsu, const X& x, const LFSV& lfsv,
762  LocalMatrix& mat)
763  {
765  tuple_element<i,Args>::type::doAlphaVolume>::
766  jacobian_volume(*get<i>(lops), eg, lfsu, x, lfsv, mat);
767  }
768  };
769 
770  template<int i>
771  struct JacobianVolumePostSkeletonOperation {
772  template<typename EG, typename LFSU, typename X, typename LFSV,
773  typename LocalMatrix>
774  static void apply(const ArgPtrs& lops, const EG& eg,
775  const LFSU& lfsu, const X& x, const LFSV& lfsv,
776  LocalMatrix& mat)
777  {
778  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
779  tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>::
780  jacobian_volume_post_skeleton(*get<i>(lops), eg,
781  lfsu, x, lfsv,
782  mat);
783  }
784  };
785 
786  template<int i>
787  struct JacobianSkeletonOperation {
788  template<typename IG, typename LFSU, typename X, typename LFSV,
789  typename LocalMatrix>
790  static void apply(const ArgPtrs& lops, const IG& ig,
791  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
792  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
793  LocalMatrix& mat_ss, LocalMatrix& mat_sn,
794  LocalMatrix& mat_ns, LocalMatrix& mat_nn)
795  {
796  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
797  tuple_element<i,Args>::type::doAlphaSkeleton>::
798  jacobian_skeleton(*get<i>(lops), ig,
799  lfsu_s, x_s, lfsv_s,
800  lfsu_n, x_n, lfsv_n,
801  mat_ss, mat_sn, mat_ns, mat_nn);
802  }
803  };
804 
805  template<int i>
806  struct JacobianBoundaryOperation {
807  template<typename IG, typename LFSU, typename X, typename LFSV,
808  typename LocalMatrix>
809  static void apply(const ArgPtrs& lops, const IG& ig,
810  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
811  LocalMatrix& mat_ss)
812  {
813  LocalAssemblerCallSwitch<typename tuple_element<i,Args>::type,
814  tuple_element<i,Args>::type::doAlphaBoundary>::
815  jacobian_boundary(*get<i>(lops), ig,
816  lfsu_s, x_s, lfsv_s, mat_ss);
817  }
818  };
819 
820  public:
822 
826  template<typename EG, typename LFSU, typename X, typename LFSV,
827  typename LocalMatrix>
828  void jacobian_volume
829  ( const EG& eg,
830  const LFSU& lfsu, const X& x, const LFSV& lfsv,
831  LocalMatrix& mat) const
832  {
833  ForLoop<JacobianVolumeOperation, 0, size-1>::
834  apply(lops, eg, lfsu, x, lfsv, mat);
835  }
836 
838 
842  template<typename EG, typename LFSU, typename X, typename LFSV,
843  typename LocalMatrix>
845  ( const EG& eg,
846  const LFSU& lfsu, const X& x, const LFSV& lfsv,
847  LocalMatrix& mat) const
848  {
849  ForLoop<JacobianVolumePostSkeletonOperation, 0, size-1>::
850  apply(lops, eg, lfsu, x, lfsv, mat);
851  }
852 
854 
858  template<typename IG, typename LFSU, typename X, typename LFSV,
859  typename LocalMatrix>
860  void jacobian_skeleton
861  ( const IG& ig,
862  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
863  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
864  LocalMatrix& mat_ss, LocalMatrix& mat_sn,
865  LocalMatrix& mat_ns, LocalMatrix& mat_nn) const
866  {
867  ForLoop<JacobianSkeletonOperation, 0, size-1>::
868  apply(lops, ig,
869  lfsu_s, x_s, lfsv_s,
870  lfsu_n, x_n, lfsv_n,
871  mat_ss, mat_sn, mat_ns, mat_nn);
872  }
873 
875 
879  template<typename IG, typename LFSU, typename X, typename LFSV,
880  typename LocalMatrix>
881  void jacobian_boundary
882  ( const IG& ig,
883  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
884  LocalMatrix& mat_ss) const
885  {
886  ForLoop<JacobianBoundaryOperation, 0, size-1>::
887  apply(lops, ig, lfsu_s, x_s, lfsv_s, mat_ss);
888  }
889 
891 
893  //
896  //
897 
899  typedef typename tuple_element<0, Args>::type::RealType RealType;
900 
901  private:
902  // template meta program helpers for the methods related to instationary
903  // stuff
904 
905  template<int i> struct SetTimeOperation {
906  static void apply(ArgPtrs& lops, RealType t)
907  { get<i>(lops)->setTime(t); }
908  };
909 
910  template<int i> struct PreStepOperation {
911  static void apply(ArgPtrs& lops,
912  RealType time, RealType dt, int stages)
913  { get<i>(lops)->preStep(time, dt, stages); }
914  };
915 
916  template<int i> struct PostStepOperation {
917  static void apply(ArgPtrs& lops)
918  { get<i>(lops)->postStep(); }
919  };
920 
921  template<int i> struct PreStageOperation {
922  static void apply(ArgPtrs& lops, RealType time, int r)
923  { get<i>(lops)->preStage(time, r); }
924  };
925 
926  template<int i> struct PostStageOperation {
927  static void apply(ArgPtrs& lops)
928  { get<i>(lops)->postStage(); }
929  };
930 
931  template<int i> struct SuggestTimestepOperation {
932  static void apply(ArgPtrs& lops, RealType& dt)
933  { dt = get<i>(lops)->suggestTimestep(dt); }
934  };
935 
936  public:
938  void setTime (RealType t)
939  {
940  ForLoop<SetTimeOperation, 0, size-1>::apply(lops, t);
941  }
942 
944  RealType getTime () const
945  {
946  return get<0>(lops)->getTime();
947  }
948 
950  void preStep (RealType time, RealType dt, int stages)
951  {
952  ForLoop<PreStepOperation, 0, size-1>::apply(lops, time, dt, stages);
953  }
954 
956  void postStep ()
957  {
958  ForLoop<PostStepOperation, 0, size-1>::apply(lops);
959  }
960 
962  void preStage (RealType time, int r)
963  {
964  ForLoop<PreStageOperation, 0, size-1>::apply(lops, time, r);
965  }
966 
968  int getStage () const
969  {
970  return get<0>(lops)->getStage();
971  }
972 
974  void postStage ()
975  {
976  ForLoop<PostStageOperation, 0, size-1>::apply(lops);
977  }
978 
980 
986  {
987  ForLoop<SuggestTimestepOperation, 0, size-1>::apply(lops, dt);
988  return dt;
989  }
990 
992  };
993 
995  }
996 }
997 
998 #endif // DUNE_PDELAB_LOCALOPERATOR_SUM_HH
void lambda_volume(const EG &eg, const LFSV &lfsv, R &r) const
get an element's contribution to lambda
Definition: sum.hh:553
int getStage() const
get current stage
Definition: sum.hh:968
void postStep()
to be called once at the end of each time step
Definition: sum.hh:956
A local operator to take the sum of other local operators.
Definition: sum.hh:30
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: sum.hh:845
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: sum.hh:566
void lambda_boundary(const IG &ig, const LFSV &lfsv_s, R &r_s) const
get a boundary intersections's contribution to lambda
Definition: sum.hh:594
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: sum.hh:737
void pattern_volume(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element's contribution to the sparsity pattern
Definition: sum.hh:281
Definition: callswitch.hh:12
void preStage(RealType time, int r)
to be called once before each stage
Definition: sum.hh:962
dune_static_assert(!(AccFlag< OneSidedSkeletonRequiredValue >::value &&AccFlag< TwoSidedSkeletonRequiredValue >::value),"Some summands require a one-sided skelton, others a ""two-sided skeleton. This is not supported.")
tuple_element< i, Args >::type & getSummand()
get the i'th component of the sum
Definition: sum.hh:59
RealType suggestTimestep(RealType dt) const
to be called after stage 1
Definition: sum.hh:985
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: sum.hh:580
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: sum.hh:861
A dense matrix for storing data associated with the degrees of freedom of a pair of LocalFunctionSpac...
Definition: common/localmatrix.hh:184
const IG & ig
Definition: common/constraints.hh:146
RealType getTime() const
get current time
Definition: sum.hh:944
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: sum.hh:472
void setTime(RealType t)
set time for subsequent evaluation
Definition: sum.hh:938
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: sum.hh:701
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: sum.hh:882
static const unsigned int value
Definition: gridfunctionspace/tags.hh:175
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: sum.hh:684
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: sum.hh:436
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: sum.hh:452
InstationarySumLocalOperator(const ArgRefs &lops_)
construct a InstationarySumLocalOperator from a tuple of local operators
Definition: sum.hh:48
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: sum.hh:312
void setSummand(typename tuple_element< i, Args >::type &summand)
set the i'th component of the sum
Definition: sum.hh:54
const EG & eg
Definition: common/constraints.hh:277
void jacobian_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, LocalMatrix &mat) const
get an element's jacobian
Definition: sum.hh:829
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: sum.hh:717
tuple_element< 0, Args >::type::RealType RealType
Export type used for time values.
Definition: sum.hh:899
void preStep(RealType time, RealType dt, int stages)
to be called once before each time step
Definition: sum.hh:950
void postStage()
to be called once at the end of each stage
Definition: sum.hh:974
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: sum.hh:330
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: sum.hh:297
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: sum.hh:419