dune-pdelab  2.5-dev
weightedsum.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_WEIGHTEDSUM_HH
4 #define DUNE_PDELAB_LOCALOPERATOR_WEIGHTEDSUM_HH
5 
6 #include <cstddef>
7 
8 #include <dune/common/forloop.hh>
9 #include <dune/common/fvector.hh>
10 #include <dune/common/tuples.hh>
11 #include <dune/common/tupleutility.hh>
12 #include <dune/common/typetraits.hh>
13 
16 
18 
19 namespace Dune {
20  namespace PDELab {
24 
26 
36  template<typename K, typename Args>
38  {
39  static const std::size_t size = tuple_size<Args>::value;
40 
41  typedef typename ForEachType<AddPtrTypeEvaluator, Args>::Type ArgPtrs;
42  typedef typename ForEachType<AddRefTypeEvaluator, Args>::Type ArgRefs;
43 
44  ArgPtrs lops;
45  typedef FieldVector<K, size> Weights;
46  Weights weights;
47 
48  public:
50  //
53  //
54 
56 
61  ( const Weights& weights_ = Weights(1))
62  : weights(weights_)
63  { }
64 
67  ( const ArgRefs& lops_,
68  const Weights& weights_ = Weights(1))
69  : lops(transformTuple<AddPtrTypeEvaluator>(lops_)), weights(weights_)
70  { }
71 
73  template<std::size_t i>
74  void setSummand(typename tuple_element<i,Args>::type& summand)
75  { get<i>(lops) = &summand; }
76 
78  template<std::size_t i>
79  typename tuple_element<i,Args>::type& getSummand()
80  { return *get<i>(lops); }
81 
83  void setWeight(K w, std::size_t i)
84  { weights[i] = w; }
85 
87  K getWeight(std::size_t i)
88  { return weights[i]; }
89 
91 
93  //
96  //
97 
98  private:
99  template<typename T1, typename T2>
100  struct OrOperation
101  : public std::integral_constant<bool, T1::value || T2:: value>
102  { };
103  template<template<int> class Value>
104  struct AccFlag : public GenericForLoop<OrOperation, Value, 0, size-1>
105  { };
106 
107  template<int i>
108  struct PatternVolumeValue : public std::integral_constant
109  < bool, tuple_element<i, Args>::type::doPatternVolume>
110  { };
111  template<int i>
112  struct PatternVolumePostSkeletonValue : public std::integral_constant
113  < bool, tuple_element<i, Args>::type::doPatternVolumePostSkeleton>
114  { };
115  template<int i>
116  struct PatternSkeletonValue : public std::integral_constant
117  < bool, tuple_element<i, Args>::type::doPatternSkeleton>
118  { };
119  template<int i>
120  struct PatternBoundaryValue : public std::integral_constant
121  < bool, tuple_element<i, Args>::type::doPatternBoundary>
122  { };
123 
124  template<int i>
125  struct AlphaVolumeValue : public std::integral_constant
126  < bool, tuple_element<i, Args>::type::doAlphaVolume>
127  { };
128  template<int i>
129  struct AlphaVolumePostSkeletonValue : public std::integral_constant
130  < bool, tuple_element<i, Args>::type::doAlphaVolumePostSkeleton>
131  { };
132  template<int i>
133  struct AlphaSkeletonValue : public std::integral_constant
134  < bool, tuple_element<i, Args>::type::doAlphaSkeleton>
135  { };
136  template<int i>
137  struct AlphaBoundaryValue : public std::integral_constant
138  < bool, tuple_element<i, Args>::type::doAlphaBoundary>
139  { };
140 
141  template<int i>
142  struct LambdaVolumeValue : public std::integral_constant
143  < bool, tuple_element<i, Args>::type::doLambdaVolume>
144  { };
145  template<int i>
146  struct LambdaVolumePostSkeletonValue : public std::integral_constant
147  < bool, tuple_element<i, Args>::type::doLambdaVolumePostSkeleton>
148  { };
149  template<int i>
150  struct LambdaSkeletonValue : public std::integral_constant
151  < bool, tuple_element<i, Args>::type::doLambdaSkeleton>
152  { };
153  template<int i>
154  struct LambdaBoundaryValue : public std::integral_constant
155  < bool, tuple_element<i, Args>::type::doLambdaBoundary>
156  { };
157 
158  template<int i>
159  struct OneSidedSkeletonRequiredValue : public std::integral_constant
160  < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
161  tuple_element<i, Args>::type::doLambdaSkeleton) &&
162  ! tuple_element<i, Args>::type::doSkeletonTwoSided)>
163  { };
164  template<int i>
165  struct TwoSidedSkeletonRequiredValue : public std::integral_constant
166  < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
167  tuple_element<i, Args>::type::doLambdaSkeleton) &&
168  tuple_element<i, Args>::type::doSkeletonTwoSided)>
169  { };
170 
171  public:
191 
194  enum { doAlphaVolume =
210 
212  enum { doLambdaVolume =
224 
230  "Some summands require a one-sided skelton, others a "
231  "two-sided skeleton. This is not supported.");
232 
234 
236  //
239  //
240 
241  private:
242  // template meta program helpers for the pattern_* methods
243 
244  template<int i>
245  struct PatternVolumeOperation {
246  template<typename LFSU, typename LFSV, typename LocalPattern>
247  static void apply(const ArgPtrs& lops, const Weights& weights,
248  const LFSU& lfsu, const LFSV& lfsv,
249  LocalPattern& pattern)
250  {
251  if(weights[i] != K(0))
253  tuple_element<i,Args>::type::doPatternVolume>::
254  pattern_volume(*get<i>(lops), lfsu, lfsv, pattern);
255  }
256  };
257 
258  template<int i>
259  struct PatternVolumePostSkeletonOperation {
260  template<typename LFSU, typename LFSV, typename LocalPattern>
261  static void apply(const ArgPtrs& lops, const Weights& weights,
262  const LFSU& lfsu, const LFSV& lfsv,
263  LocalPattern& pattern)
264  {
265  if(weights[i] != K(0))
267  tuple_element<i,Args>::type::doPatternVolumePostSkeleton>::
268  pattern_volume_post_skeleton(*get<i>(lops), lfsu, lfsv, pattern);
269  }
270  };
271 
272  template<int i>
273  struct PatternSkeletonOperation {
274  template<typename LFSU, typename LFSV, typename LocalPattern>
275  static void apply(const ArgPtrs& lops, const Weights& weights,
276  const LFSU& lfsu_s, const LFSV& lfsv_s,
277  const LFSU& lfsu_n, const LFSV& lfsv_n,
278  LocalPattern& pattern_sn,
279  LocalPattern& pattern_ns)
280  {
281  if(weights[i] != K(0))
283  tuple_element<i,Args>::type::doPatternSkeleton>::
284  pattern_skeleton(*get<i>(lops),
285  lfsu_s, lfsv_s, lfsu_n, lfsv_n,
286  pattern_sn, pattern_ns);
287  }
288  };
289 
290  template<int i>
291  struct PatternBoundaryOperation {
292  template<typename LFSU, typename LFSV, typename LocalPattern>
293  static void apply(const ArgPtrs& lops, const Weights& weights,
294  const LFSU& lfsu_s, const LFSV& lfsv_s,
295  LocalPattern& pattern_ss)
296  {
297  if(weights[i] != K(0))
299  tuple_element<i,Args>::type::doPatternBoundary>::
300  pattern_boundary(*get<i>(lops), lfsu_s, lfsv_s, pattern_ss);
301  }
302  };
303 
304  public:
306 
311  template<typename LFSU, typename LFSV, typename LocalPattern>
312  void pattern_volume
313  ( const LFSU& lfsu, const LFSV& lfsv,
314  LocalPattern& pattern) const
315  {
316  ForLoop<PatternVolumeOperation, 0, size-1>::
317  apply(lops, weights, lfsu, lfsv, pattern);
318  }
319 
322 
327  template<typename LFSU, typename LFSV, typename LocalPattern>
329  ( const LFSU& lfsu, const LFSV& lfsv,
330  LocalPattern& pattern) const
331  {
332  ForLoop<PatternVolumePostSkeletonOperation, 0, size-1>::
333  apply(lops, weights, lfsu, lfsv, pattern);
334  }
335 
337 
342  template<typename LFSU, typename LFSV, typename LocalPattern>
343  void pattern_skeleton
344  ( const LFSU& lfsu_s, const LFSV& lfsv_s,
345  const LFSU& lfsu_n, const LFSV& lfsv_n,
346  LocalPattern& pattern_sn,
347  LocalPattern& pattern_ns) const
348  {
349  ForLoop<PatternSkeletonOperation, 0, size-1>::
350  apply(lops, weights, lfsu_s, lfsv_s, lfsu_n, lfsv_n,
351  pattern_sn, pattern_ns);
352  }
353 
355 
360  template<typename LFSU, typename LFSV, typename LocalPattern>
361  void pattern_boundary
362  ( const LFSU& lfsu_s, const LFSV& lfsv_s,
363  LocalPattern& pattern_ss) const
364  {
365  ForLoop<PatternBoundaryOperation, 0, size-1>::
366  apply(lops, weights, lfsu_s, lfsv_s, pattern_ss);
367  }
368 
370 
372  //
375  //
376 
377  private:
378  // template meta program helpers for the alpha_* methods
379 
380  template<int i>
381  struct AlphaVolumeOperation {
382  typedef typename tuple_element<i,Args>::type Arg;
383  template<typename EG, typename LFSU, typename X, typename LFSV,
384  typename C>
385  static void apply(const ArgPtrs& lops, const Weights& weights,
386  const EG& eg,
387  const LFSU& lfsu, const X& x, const LFSV& lfsv,
389  {
390  apply(lops, weights[i]*r.weight(), eg, lfsu, x, lfsv, r.container());
391  }
392  template<typename EG, typename LFSU, typename X, typename LFSV,
393  typename C>
394  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
395  const EG& eg,
396  const LFSU& lfsu, const X& x, const LFSV& lfsv,
397  C& r)
398  {
399  if(weight != K(0)) {
400  WeightedVectorAccumulationView<C> view(r, weight);
402  alpha_volume(*get<i>(lops), eg, lfsu, x, lfsv, view);
403  }
404  }
405  };
406 
407  template<int i>
408  struct AlphaVolumePostSkeletonOperation {
409  typedef typename tuple_element<i,Args>::type Arg;
410  template<typename EG, typename LFSU, typename X, typename LFSV,
411  typename C>
412  static void apply(const ArgPtrs& lops, const Weights& weights,
413  const EG& eg,
414  const LFSU& lfsu, const X& x, const LFSV& lfsv,
416  {
417  apply(lops, weights[i]*r.weight(), eg, lfsu, x, lfsv, r.container());
418  }
419  template<typename EG, typename LFSU, typename X, typename LFSV,
420  typename C>
421  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
422  const EG& eg,
423  const LFSU& lfsu, const X& x, const LFSV& lfsv,
424  C& r)
425  {
426  if(weight != K(0)) {
427  WeightedVectorAccumulationView<C> view(r, weight);
429  alpha_volume_post_skeleton(*get<i>(lops), eg,
430  lfsu, x, lfsv,
431  view);
432  }
433  }
434  };
435 
436  template<int i>
437  struct AlphaSkeletonOperation {
438  typedef typename tuple_element<i,Args>::type Arg;
439  template<typename IG, typename LFSU, typename X, typename LFSV,
440  typename C>
441  static void apply(const ArgPtrs& lops, const Weights& weights,
442  const IG& ig,
443  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
444  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
447  {
448  apply(lops, weights[i]*r_s.weight(), weights[i]*r_n.weight(),
449  ig,
450  lfsu_s, x_s, lfsv_s,
451  lfsu_n, x_n, lfsv_n,
452  r_s.container(), r_n.container());
453  }
454  template<typename IG, typename LFSU, typename X, typename LFSV,
455  typename C>
456  static void apply(const ArgPtrs& lops,
457  typename C::weight_type weight_s,
458  typename C::weight_type weight_n,
459  const IG& ig,
460  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
461  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
462  C& r_s, C& r_n)
463  {
464  if(weight_s != K(0) || weight_n != K(0)) {
465  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
466  WeightedVectorAccumulationView<C> view_n(r_n, weight_n);
468  alpha_skeleton(*get<i>(lops), ig,
469  lfsu_s, x_s, lfsv_s,
470  lfsu_n, x_n, lfsv_n,
471  view_s, view_n);
472  }
473  }
474  };
475 
476  template<int i>
477  struct AlphaBoundaryOperation {
478  typedef typename tuple_element<i,Args>::type Arg;
479  template<typename IG, typename LFSU, typename X, typename LFSV,
480  typename C>
481  static void apply(const ArgPtrs& lops, const Weights& weights,
482  const IG& ig,
483  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
485  {
486  apply(lops, weights[i]*r_s.weight(), ig,
487  lfsu_s, x_s, lfsv_s,
488  r_s.container());
489  }
490  template<typename IG, typename LFSU, typename X, typename LFSV,
491  typename C>
492  static void apply(const ArgPtrs& lops,
493  typename C::weight_type weight_s,
494  const IG& ig,
495  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
496  C& r_s)
497  {
498  if(weight_s != K(0)) {
499  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
501  alpha_boundary(*get<i>(lops), ig, lfsu_s, x_s, lfsv_s, view_s);
502  }
503  }
504  };
505 
506  public:
508 
512  template<typename EG, typename LFSU, typename X, typename LFSV,
513  typename C>
514  void alpha_volume
515  ( const EG& eg,
516  const LFSU& lfsu, const X& x, const LFSV& lfsv,
517  C& r) const
518  {
519  ForLoop<AlphaVolumeOperation, 0, size-1>::
520  apply(lops, weights, eg, lfsu, x, lfsv, r);
521  }
522 
525 
529  template<typename EG, typename LFSU, typename X, typename LFSV,
530  typename C>
532  ( const EG& eg,
533  const LFSU& lfsu, const X& x, const LFSV& lfsv,
534  C& r) const
535  {
536  ForLoop<AlphaVolumePostSkeletonOperation, 0, size-1>::
537  apply(lops, weights, eg, lfsu, x, lfsv, r);
538  }
539 
541 
545  template<typename IG, typename LFSU, typename X, typename LFSV,
546  typename C>
547  void alpha_skeleton
548  ( const IG& ig,
549  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
550  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
551  C& r_s, C& r_n) const
552  {
553  ForLoop<AlphaSkeletonOperation, 0, size-1>::
554  apply(lops, weights, ig,
555  lfsu_s, x_s, lfsv_s,
556  lfsu_n, x_n, lfsv_n,
557  r_s, r_n);
558  }
559 
561 
565  template<typename IG, typename LFSU, typename X, typename LFSV,
566  typename C>
567  void alpha_boundary
568  ( const IG& ig,
569  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
570  C& r_s) const
571  {
572  ForLoop<AlphaBoundaryOperation, 0, size-1>::
573  apply(lops, weights, ig, lfsu_s, x_s, lfsv_s, r_s);
574  }
575 
577 
579  //
582  //
583 
584  private:
585  // template meta program helpers for the lambda_* methods
586 
587  template<int i>
588  struct LambdaVolumeOperation {
589  typedef typename tuple_element<i,Args>::type Arg;
590  template<typename EG, typename LFSV, typename C>
591  static void apply(const ArgPtrs& lops, const Weights& weights,
592  const EG& eg,
593  const LFSV& lfsv,
595  {
596  apply(lops, weights[i]*r.weight(), eg, lfsv, r.container());
597  }
598  template<typename EG, typename LFSV, typename C>
599  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
600  const EG& eg,
601  const LFSV& lfsv,
602  C& r)
603  {
604  if(weight != K(0)) {
605  WeightedVectorAccumulationView<C> view(r, weight);
607  lambda_volume(*get<i>(lops), eg, lfsv, view);
608  }
609  }
610  };
611 
612  template<int i>
613  struct LambdaVolumePostSkeletonOperation {
614  typedef typename tuple_element<i,Args>::type Arg;
615  template<typename EG, typename LFSV, typename C>
616  static void apply(const ArgPtrs& lops, const Weights& weights,
617  const EG& eg,
618  const LFSV& lfsv,
620  {
621  apply(lops, weights[i]*r.weight(), eg, lfsv, r.container());
622  }
623  template<typename EG, typename LFSV, typename C>
624  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
625  const EG& eg,
626  const LFSV& lfsv,
627  C& r)
628  {
629  if(weight != K(0)) {
630  WeightedVectorAccumulationView<C> view(r, weight);
632  lambda_volume_post_skeleton(*get<i>(lops), eg, lfsv, view);
633  }
634  }
635  };
636 
637  template<int i>
638  struct LambdaSkeletonOperation {
639  typedef typename tuple_element<i,Args>::type Arg;
640  template<typename IG, typename LFSV, typename C>
641  static void apply(const ArgPtrs& lops, const Weights& weights,
642  const IG& ig,
643  const LFSV& lfsv_s, const LFSV& lfsv_n,
646  {
647  apply(lops, weights[i]*r_s.weight(), weights[i]*r_n.weight(),
648  ig,
649  lfsv_s, lfsv_n,
650  r_s.container(), r_n.container());
651  }
652  template<typename IG, typename LFSV, typename C>
653  static void apply(const ArgPtrs& lops,
654  typename C::weight_type weight_s,
655  typename C::weight_type weight_n,
656  const IG& ig,
657  const LFSV& lfsv_s, const LFSV& lfsv_n,
658  C& r_s, C& r_n)
659  {
660  if(weight_s != K(0) || weight_n != K(0)) {
661  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
662  WeightedVectorAccumulationView<C> view_n(r_n, weight_n);
664  lambda_skeleton(*get<i>(lops), ig,
665  lfsv_s, lfsv_n,
666  view_s, view_n);
667  }
668  }
669  };
670 
671  template<int i>
672  struct LambdaBoundaryOperation {
673  typedef typename tuple_element<i,Args>::type Arg;
674  template<typename IG, typename LFSV, typename C>
675  static void apply(const ArgPtrs& lops, const Weights& weights,
676  const IG& ig,
677  const LFSV& lfsv_s,
679  {
680  apply(lops, weights[i]*r_s.weight(), ig, lfsv_s, r_s.container());
681  }
682  template<typename IG, typename LFSV, typename C>
683  static void apply(const ArgPtrs& lops,
684  typename C::weight_type weight_s,
685  const IG& ig,
686  const LFSV& lfsv_s,
687  C& r_s)
688  {
689  if(weight_s != K(0)) {
690  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
692  lambda_boundary(*get<i>(lops), ig, lfsv_s, view_s);
693  }
694  }
695  };
696 
697  public:
699 
703  template<typename EG, typename LFSV, typename C>
704  void lambda_volume(const EG& eg, const LFSV& lfsv, C& r) const
705  {
706  ForLoop<LambdaVolumeOperation, 0, size-1>::
707  apply(lops, weights, eg, lfsv, r);
708  }
709 
712 
716  template<typename EG, typename LFSV, typename C>
717  void lambda_volume_post_skeleton(const EG& eg,
718  const LFSV& lfsv,
719  C& r) const
720  {
721  ForLoop<LambdaVolumePostSkeletonOperation, 0, size-1>::
722  apply(lops, weights, eg, lfsv, r);
723  }
724 
726 
730  template<typename IG, typename LFSV, typename C>
731  void lambda_skeleton(const IG& ig,
732  const LFSV& lfsv_s, const LFSV& lfsv_n,
733  C& r_s, C& r_n) const
734  {
735  ForLoop<LambdaSkeletonOperation, 0, size-1>::
736  apply(lops, weights, ig, lfsv_s, lfsv_n, r_s, r_n);
737  }
738 
740 
744  template<typename IG, typename LFSV, typename C>
745  void lambda_boundary(const IG& ig, const LFSV& lfsv_s, C& r_s) const
746  {
747  ForLoop<LambdaBoundaryOperation, 0, size-1>::
748  apply(lops, weights, ig, lfsv_s, r_s);
749  }
750 
752 
754  //
757  //
758 
759  private:
760  // template meta program helpers for the jacobian_apply_* methods
761 
762  template<int i>
763  struct JacobianApplyVolumeOperation {
764  typedef typename tuple_element<i,Args>::type Arg;
765  template<typename EG, typename LFSU, typename X, typename LFSV,
766  typename C>
767  static void apply(const ArgPtrs& lops, const Weights& weights,
768  const EG& eg,
769  const LFSU& lfsu, const X& x, const LFSV& lfsv,
771  {
772  apply(lops, weights[i]*r.weight(), eg, lfsu, x, lfsv, r.container());
773  }
774  template<typename EG, typename LFSU, typename X, typename LFSV,
775  typename C>
776  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
777  const EG& eg,
778  const LFSU& lfsu, const X& x, const LFSV& lfsv,
779  C& r)
780  {
781  if(weight != K(0)) {
782  WeightedVectorAccumulationView<C> view(r, weight);
784  jacobian_apply_volume(*get<i>(lops), eg, lfsu, x, lfsv, view);
785  }
786  }
787  };
788 
789  template<int i>
790  struct JacobianApplyVolumePostSkeletonOperation {
791  typedef typename tuple_element<i,Args>::type Arg;
792  template<typename EG, typename LFSU, typename X, typename LFSV,
793  typename C>
794  static void apply(const ArgPtrs& lops, const Weights& weights,
795  const EG& eg,
796  const LFSU& lfsu, const X& x, const LFSV& lfsv,
798  {
799  apply(lops, weights[i]*r.weight(), eg, lfsu, x, lfsv, r.container());
800  }
801  template<typename EG, typename LFSU, typename X, typename LFSV,
802  typename C>
803  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
804  const EG& eg,
805  const LFSU& lfsu, const X& x, const LFSV& lfsv,
806  C& r)
807  {
808  if(weight != K(0)) {
809  WeightedVectorAccumulationView<C> view(r, weight);
811  jacobian_apply_volume_post_skeleton(*get<i>(lops), eg,
812  lfsu, x, lfsv,
813  view);
814  }
815  }
816  };
817 
818  template<int i>
819  struct JacobianApplySkeletonOperation {
820  typedef typename tuple_element<i,Args>::type Arg;
821  template<typename IG, typename LFSU, typename X, typename LFSV,
822  typename C>
823  static void apply(const ArgPtrs& lops, const Weights& weights,
824  const IG& ig,
825  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
826  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
829  {
830  apply(lops, weights[i]*r_s.weight(), weights[i]*r_n.weight(),
831  ig,
832  lfsu_s, x_s, lfsv_s,
833  lfsu_n, x_n, lfsv_n,
834  r_s.container(), r_n.container());
835  }
836  template<typename IG, typename LFSU, typename X, typename LFSV,
837  typename C>
838  static void apply(const ArgPtrs& lops,
839  typename C::weight_type weight_s,
840  typename C::weight_type weight_n,
841  const IG& ig,
842  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
843  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
844  C& r_s, C& r_n)
845  {
846  if(weight_s != K(0) || weight_n != K(0)) {
847  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
848  WeightedVectorAccumulationView<C> view_n(r_n, weight_n);
850  jacobian_apply_skeleton(*get<i>(lops), ig,
851  lfsu_s, x_s, lfsv_s,
852  lfsu_n, x_n, lfsv_n,
853  view_s, view_n);
854  }
855  }
856  };
857 
858  template<int i>
859  struct JacobianApplyBoundaryOperation {
860  typedef typename tuple_element<i,Args>::type Arg;
861  template<typename IG, typename LFSU, typename X, typename LFSV,
862  typename C>
863  static void apply(const ArgPtrs& lops, const Weights& weights,
864  const IG& ig,
865  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
867  {
868  apply(lops, weights[i]*r_s.weight(), ig,
869  lfsu_s, x_s, lfsv_s,
870  r_s.container());
871  }
872  template<typename IG, typename LFSU, typename X, typename LFSV,
873  typename C>
874  static void apply(const ArgPtrs& lops,
875  typename C::weight_type weight_s,
876  const IG& ig,
877  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
878  C& r_s)
879  {
880  if(weight_s != K(0)) {
881  WeightedVectorAccumulationView<C> view_s(r_s, weight_s);
883  jacobian_apply_boundary(*get<i>(lops), ig,
884  lfsu_s, x_s, lfsv_s,
885  view_s);
886  }
887  }
888  };
889 
890  public:
892 
896  template<typename EG, typename LFSU, typename X, typename LFSV,
897  typename C>
899  ( const EG& eg,
900  const LFSU& lfsu, const X& x, const LFSV& lfsv,
901  C& r) const
902  {
903  ForLoop<JacobianApplyVolumeOperation, 0, size-1>::
904  apply(lops, weights, eg, lfsu, x, lfsv, r);
905  }
906 
909 
913  template<typename EG, typename LFSU, typename X, typename LFSV,
914  typename C>
916  ( const EG& eg,
917  const LFSU& lfsu, const X& x, const LFSV& lfsv,
918  C& r) const
919  {
920  ForLoop<JacobianApplyVolumePostSkeletonOperation, 0, size-1>::
921  apply(lops, weights, eg, lfsu, x, lfsv, r);
922  }
923 
925 
929  template<typename IG, typename LFSU, typename X, typename LFSV,
930  typename C>
932  ( const IG& ig,
933  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
934  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
935  C& r_s, C& r_n) const
936  {
937  ForLoop<JacobianApplySkeletonOperation, 0, size-1>::
938  apply(lops, weights, ig,
939  lfsu_s, x_s, lfsv_s,
940  lfsu_n, x_n, lfsv_n,
941  r_s, r_n);
942  }
943 
945 
949  template<typename IG, typename LFSU, typename X, typename LFSV,
950  typename C>
952  ( const IG& ig,
953  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
954  C& r_s) const
955  {
956  ForLoop<JacobianApplyBoundaryOperation, 0, size-1>::
957  apply(lops, weights, ig, lfsu_s, x_s, lfsv_s, r_s);
958  }
959 
961 
963  //
966  //
967 
968  private:
969  // template meta program helpers for the jacobian_apply_* methods
970 
971  template<int i>
972  struct JacobianVolumeOperation {
973  typedef typename tuple_element<i,Args>::type Arg;
974  template<typename EG, typename LFSU, typename X, typename LFSV,
975  typename C>
976  static void apply(const ArgPtrs& lops, const Weights& weights,
977  const EG& eg,
978  const LFSU& lfsu, const X& x, const LFSV& lfsv,
980  {
981  apply(lops, weights[i]*m.weight(), eg, lfsu, x, lfsv, m.container());
982  }
983  template<typename EG, typename LFSU, typename X, typename LFSV,
984  typename C>
985  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
986  const EG& eg,
987  const LFSU& lfsu, const X& x, const LFSV& lfsv,
988  C& m)
989  {
990  if(weight != K(0)) {
991  WeightedMatrixAccumulationView<C> view(m, weight);
993  jacobian_volume(*get<i>(lops), eg, lfsu, x, lfsv, view);
994  }
995  }
996  };
997 
998  template<int i>
999  struct JacobianVolumePostSkeletonOperation {
1000  typedef typename tuple_element<i,Args>::type Arg;
1001  template<typename EG, typename LFSU, typename X, typename LFSV,
1002  typename C>
1003  static void apply(const ArgPtrs& lops, const Weights& weights,
1004  const EG& eg,
1005  const LFSU& lfsu, const X& x, const LFSV& lfsv,
1007  {
1008  apply(lops, weights[i]*m.weight(), eg, lfsu, x, lfsv, m.container());
1009  }
1010  template<typename EG, typename LFSU, typename X, typename LFSV,
1011  typename C>
1012  static void apply(const ArgPtrs& lops, typename C::weight_type weight,
1013  const EG& eg,
1014  const LFSU& lfsu, const X& x, const LFSV& lfsv,
1015  C& m)
1016  {
1017  if(weight != K(0)) {
1018  WeightedMatrixAccumulationView<C> view(m, weight);
1020  jacobian_volume_post_skeleton(*get<i>(lops), eg,
1021  lfsu, x, lfsv,
1022  view);
1023  }
1024  }
1025  };
1026 
1027  template<int i>
1028  struct JacobianSkeletonOperation {
1029  typedef typename tuple_element<i,Args>::type Arg;
1030  template<typename IG, typename LFSU, typename X, typename LFSV,
1031  typename C>
1032  static void apply(const ArgPtrs& lops, const Weights& weights,
1033  const IG& ig,
1034  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1035  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
1040  {
1041  apply(lops,
1042  weights[i]*m_ss.weight(), weights[i]*m_sn.weight(),
1043  weights[i]*m_ns.weight(), weights[i]*m_nn.weight(),
1044  ig,
1045  lfsu_s, x_s, lfsv_s,
1046  lfsu_n, x_n, lfsv_n,
1047  m_ss.container(), m_sn.container(),
1048  m_ns.container(), m_nn.container());
1049  }
1050  template<typename IG, typename LFSU, typename X, typename LFSV,
1051  typename C>
1052  static void apply(const ArgPtrs& lops,
1053  typename C::weight_type weight_ss,
1054  typename C::weight_type weight_sn,
1055  typename C::weight_type weight_ns,
1056  typename C::weight_type weight_nn,
1057  const IG& ig,
1058  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1059  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
1060  C& m_ss, C& m_sn, C& m_ns, C& m_nn)
1061  {
1062  if(weight_ss != K(0) || weight_sn != K(0) ||
1063  weight_ns != K(0) || weight_nn != K(0))
1064  {
1065  WeightedMatrixAccumulationView<C> view_ss(m_ss, weight_ss);
1066  WeightedMatrixAccumulationView<C> view_sn(m_sn, weight_sn);
1067  WeightedMatrixAccumulationView<C> view_ns(m_ns, weight_ns);
1068  WeightedMatrixAccumulationView<C> view_nn(m_nn, weight_nn);
1070  jacobian_skeleton(*get<i>(lops), ig,
1071  lfsu_s, x_s, lfsv_s,
1072  lfsu_n, x_n, lfsv_n,
1073  view_ss, view_sn, view_ns, view_nn);
1074  }
1075  }
1076  };
1077 
1078  template<int i>
1079  struct JacobianBoundaryOperation {
1080  typedef typename tuple_element<i,Args>::type Arg;
1081  template<typename IG, typename LFSU, typename X, typename LFSV,
1082  typename C>
1083  static void apply(const ArgPtrs& lops, const Weights& weights,
1084  const IG& ig,
1085  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1087  {
1088  apply(lops, weights[i]*m_ss.weight(), ig,
1089  lfsu_s, x_s, lfsv_s,
1090  m_ss.container());
1091  }
1092  template<typename IG, typename LFSU, typename X, typename LFSV,
1093  typename C>
1094  static void apply(const ArgPtrs& lops,
1095  typename C::weight_type weight_ss,
1096  const IG& ig,
1097  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1098  C& m_ss)
1099  {
1100  if(weight_ss != K(0))
1101  {
1102  WeightedMatrixAccumulationView<C> view_ss(m_ss, weight_ss);
1104  jacobian_boundary(*get<i>(lops), ig,
1105  lfsu_s, x_s, lfsv_s, view_ss);
1106  }
1107  }
1108  };
1109 
1110  public:
1112 
1116  template<typename EG, typename LFSU, typename X, typename LFSV,
1117  typename C>
1118  void jacobian_volume
1119  ( const EG& eg,
1120  const LFSU& lfsu, const X& x, const LFSV& lfsv,
1121  C& m) const
1122  {
1123  ForLoop<JacobianVolumeOperation, 0, size-1>::
1124  apply(lops, weights, eg, lfsu, x, lfsv, m);
1125  }
1126 
1128 
1132  template<typename EG, typename LFSU, typename X, typename LFSV,
1133  typename C>
1135  ( const EG& eg,
1136  const LFSU& lfsu, const X& x, const LFSV& lfsv,
1137  C& m) const
1138  {
1139  ForLoop<JacobianVolumePostSkeletonOperation, 0, size-1>::
1140  apply(lops, weights, eg, lfsu, x, lfsv, m);
1141  }
1142 
1144 
1148  template<typename IG, typename LFSU, typename X, typename LFSV,
1149  typename C>
1150  void jacobian_skeleton
1151  ( const IG& ig,
1152  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1153  const LFSU& lfsu_n, const X& x_n, const LFSV& lfsv_n,
1154  C& m_ss, C& m_sn, C& m_ns, C& m_nn) const
1155  {
1156  ForLoop<JacobianSkeletonOperation, 0, size-1>::
1157  apply(lops, weights, ig,
1158  lfsu_s, x_s, lfsv_s,
1159  lfsu_n, x_n, lfsv_n,
1160  m_ss, m_sn, m_ns, m_nn);
1161  }
1162 
1164 
1168  template<typename IG, typename LFSU, typename X, typename LFSV,
1169  typename C>
1170  void jacobian_boundary
1171  ( const IG& ig,
1172  const LFSU& lfsu_s, const X& x_s, const LFSV& lfsv_s,
1173  C& m_ss) const
1174  {
1175  ForLoop<JacobianBoundaryOperation, 0, size-1>::
1176  apply(lops, weights, ig, lfsu_s, x_s, lfsv_s, m_ss);
1177  }
1178 
1180 
1182  //
1185  //
1186 
1188  typedef typename tuple_element<0, Args>::type::RealType RealType;
1189 
1190  private:
1191  // template meta program helpers for the methods related to instationary
1192  // stuff
1193 
1194  template<int i> struct SetTimeOperation {
1195  static void apply(ArgPtrs& lops, RealType t)
1196  { get<i>(lops)->setTime(t); }
1197  };
1198 
1199  template<int i> struct PreStepOperation {
1200  static void apply(ArgPtrs& lops,
1201  RealType time, RealType dt, int stages)
1202  { get<i>(lops)->preStep(time, dt, stages); }
1203  };
1204 
1205  template<int i> struct PostStepOperation {
1206  static void apply(ArgPtrs& lops)
1207  { get<i>(lops)->postStep(); }
1208  };
1209 
1210  template<int i> struct PreStageOperation {
1211  static void apply(ArgPtrs& lops, RealType time, int r)
1212  { get<i>(lops)->preStage(time, r); }
1213  };
1214 
1215  template<int i> struct PostStageOperation {
1216  static void apply(ArgPtrs& lops)
1217  { get<i>(lops)->postStage(); }
1218  };
1219 
1220  template<int i> struct SuggestTimestepOperation {
1221  static void apply(ArgPtrs& lops, RealType& dt)
1222  { dt = get<i>(lops)->suggestTimestep(dt); }
1223  };
1224 
1225  public:
1227  void setTime (RealType t)
1228  {
1229  ForLoop<SetTimeOperation, 0, size-1>::apply(lops, t);
1230  }
1231 
1233  RealType getTime () const
1234  {
1235  return get<0>(lops)->getTime();
1236  }
1237 
1239  void preStep (RealType time, RealType dt, int stages)
1240  {
1241  ForLoop<PreStepOperation, 0, size-1>::apply(lops, time, dt, stages);
1242  }
1243 
1245  void postStep ()
1246  {
1247  ForLoop<PostStepOperation, 0, size-1>::apply(lops);
1248  }
1249 
1251  void preStage (RealType time, int r)
1252  {
1253  ForLoop<PreStageOperation, 0, size-1>::apply(lops, time, r);
1254  }
1255 
1257  int getStage () const
1258  {
1259  return get<0>(lops)->getStage();
1260  }
1261 
1263  void postStage ()
1264  {
1265  ForLoop<PostStageOperation, 0, size-1>::apply(lops);
1266  }
1267 
1269 
1274  RealType suggestTimestep (RealType dt) const
1275  {
1276  ForLoop<SuggestTimestepOperation, 0, size-1>::apply(lops, dt);
1277  return dt;
1278  }
1279 
1281  };
1282 
1284  }
1285 }
1286 
1287 #endif // DUNE_PDELAB_LOCALOPERATOR_WEIGHTEDSUM_HH
VTKWriter & w
Definition: function.hh:829
void jacobian_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, C &m_ss) const
get a boundary intersections&#39;s jacobian
Definition: weightedsum.hh:1171
void setWeight(K w, std::size_t i)
set the weight for the i&#39;th component of the sum
Definition: weightedsum.hh:83
An accumulate-only view on a local matrix that automatically takes into account an accumulation weigh...
Definition: localmatrix.hh:21
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&#39;s contribution to the sparsity pattern
Definition: weightedsum.hh:344
void lambda_skeleton(const IG &ig, const LFSV &lfsv_s, const LFSV &lfsv_n, C &r_s, C &r_n) const
get an internal intersections&#39;s contribution to lambda
Definition: weightedsum.hh:731
static void lambda_volume_post_skeleton(const LA &la, const EG &eg, const LFSV &lfsv, R &r)
Definition: callswitch.hh:117
void alpha_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &r) const
get an element&#39;s contribution to alpha
Definition: weightedsum.hh:515
static void jacobian_apply_skeleton(const LA &la, 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)
Definition: callswitch.hh:140
void pattern_boundary(const LFSU &lfsu_s, const LFSV &lfsv_s, LocalPattern &pattern_ss) const
get a boundary intersection&#39;s contribution to the sparsity pattern
Definition: weightedsum.hh:362
void lambda_volume_post_skeleton(const EG &eg, const LFSV &lfsv, C &r) const
get an element&#39;s contribution to lambda after the intersections have been handled ...
Definition: weightedsum.hh:717
void setSummand(typename tuple_element< i, Args >::type &summand)
set the i&#39;th component of the sum
Definition: weightedsum.hh:74
RealType getTime() const
get current time
Definition: weightedsum.hh:1233
static void lambda_volume(const LA &la, const EG &eg, const LFSV &lfsv, R &r)
Definition: callswitch.hh:113
weight_type weight()
Returns the weight associated with this view.
Definition: localmatrix.hh:60
void setTime(RealType t)
set time for subsequent evaluation
Definition: weightedsum.hh:1227
static void alpha_boundary(const LA &la, const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, R &r_s)
Definition: callswitch.hh:106
static void jacobian_apply_volume_post_skeleton(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, Y &y)
Definition: callswitch.hh:136
K getWeight(std::size_t i)
get the weight for the i&#39;th component of the sum
Definition: weightedsum.hh:87
static void jacobian_apply_volume(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, Y &y)
Definition: callswitch.hh:132
RealType suggestTimestep(RealType dt) const
to be called after stage 1
Definition: weightedsum.hh:1274
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139
void jacobian_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &m) const
get an element&#39;s jacobian
Definition: weightedsum.hh:1119
WeightedSumLocalOperator(const Weights &weights_=Weights(1))
construct a WeightedSumLocalOperator
Definition: weightedsum.hh:61
void jacobian_apply_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, C &r_s) const
apply a boundary intersections&#39;s jacobian
Definition: weightedsum.hh:952
void preStep(RealType time, RealType dt, int stages)
to be called once before each time step
Definition: weightedsum.hh:1239
static void alpha_volume(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, R &r)
Definition: callswitch.hh:91
A local operator to take the weighted sum of other local operators.
Definition: weightedsum.hh:37
void jacobian_apply_volume(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &r) const
apply an element&#39;s jacobian
Definition: weightedsum.hh:899
void alpha_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &r) const
get an element&#39;s contribution to alpha after the intersections have been handled
Definition: weightedsum.hh:532
static void jacobian_boundary(const LA &la, const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, M &mat_ss)
Definition: callswitch.hh:194
Container & container()
Returns the container (of type LocalVector) that this view is based on.
Definition: localvector.hh:127
void jacobian_apply_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &r) const
apply an element&#39;s jacobian after the intersections have been handled
Definition: weightedsum.hh:916
void postStep()
to be called once at the end of each time step
Definition: weightedsum.hh:1245
tuple_element< i, Args >::type & getSummand()
get the i&#39;th component of the sum
Definition: weightedsum.hh:79
void lambda_volume(const EG &eg, const LFSV &lfsv, C &r) const
get an element&#39;s contribution to lambda
Definition: weightedsum.hh:704
void jacobian_volume_post_skeleton(const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, C &m) const
get an element&#39;s jacobian after the intersections have been handled
Definition: weightedsum.hh:1135
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
static void jacobian_apply_boundary(const LA &la, const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, Y &y_s)
Definition: callswitch.hh:147
void alpha_boundary(const IG &ig, const LFSU &lfsu_s, const X &x_s, const LFSV &lfsv_s, C &r_s) const
get a boundary intersections&#39;s contribution to alpha
Definition: weightedsum.hh:568
static void jacobian_skeleton(const LA &la, 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, M &mat_ss, M &mat_sn, M &mat_ns, M &mat_nn)
Definition: callswitch.hh:186
static void lambda_boundary(const LA &la, const IG &ig, const LFSV &lfsv, R &r)
Definition: callswitch.hh:127
void pattern_volume_post_skeleton(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element&#39;s contribution to the sparsity pattern after the intersections have been handled ...
Definition: weightedsum.hh:329
weight_type weight()
Returns the weight associated with this view.
Definition: localvector.hh:61
static void alpha_skeleton(const LA &la, 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)
Definition: callswitch.hh:99
const IG & ig
Definition: constraints.hh:148
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, C &r_s, C &r_n) const
apply an internal intersections&#39;s jacobians
Definition: weightedsum.hh:932
Container & container()
Returns the container (of type LocalMatrix) that this view is based on.
Definition: localmatrix.hh:129
static void alpha_volume_post_skeleton(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, R &r)
Definition: callswitch.hh:95
static void jacobian_volume_post_skeleton(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, M &mat)
Definition: callswitch.hh:182
static void jacobian_volume(const LA &la, const EG &eg, const LFSU &lfsu, const X &x, const LFSV &lfsv, M &mat)
Definition: callswitch.hh:178
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, C &m_ss, C &m_sn, C &m_ns, C &m_nn) const
apply an internal intersections&#39;s jacobians
Definition: weightedsum.hh:1151
tuple_element< 0, Args >::type::RealType RealType
Export type used for time values.
Definition: weightedsum.hh:1188
void postStage()
to be called once at the end of each stage
Definition: weightedsum.hh:1263
int getStage() const
get current stage
Definition: weightedsum.hh:1257
void preStage(RealType time, int r)
to be called once before each stage
Definition: weightedsum.hh:1251
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, C &r_s, C &r_n) const
get an internal intersections&#39;s contribution to alpha
Definition: weightedsum.hh:548
Definition: callswitch.hh:64
static void lambda_skeleton(const LA &la, const IG &ig, const LFSV &lfsv_s, const LFSV &lfsv_n, R &r_s, R &r_n)
Definition: callswitch.hh:121
void lambda_boundary(const IG &ig, const LFSV &lfsv_s, C &r_s) const
get a boundary intersections&#39;s contribution to lambda
Definition: weightedsum.hh:745
An accumulate-only view on a local vector that automatically takes into account an accumulation weigh...
Definition: localvector.hh:26
void pattern_volume(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element&#39;s contribution to the sparsity pattern
Definition: weightedsum.hh:313