3 #ifndef DUNE_PDELAB_LOCALOPERATOR_SUM_HH 4 #define DUNE_PDELAB_LOCALOPERATOR_SUM_HH 8 #include <dune/common/forloop.hh> 9 #include <dune/common/tuples.hh> 10 #include <dune/common/tupleutility.hh> 11 #include <dune/common/typetraits.hh> 28 template<
typename Args>
33 typedef typename ForEachType<AddPtrTypeEvaluator, Args>::Type ArgPtrs;
34 typedef typename ForEachType<AddRefTypeEvaluator, Args>::Type ArgRefs;
48 : lops(transformTuple<AddPtrTypeEvaluator>(lops_))
52 template<std::
size_t i>
53 void setSummand(
typename tuple_element<i,Args>::type& summand)
54 { get<i>(lops) = &summand; }
57 template<std::
size_t i>
59 {
return *get<i>(lops); }
70 template<
typename T1,
typename T2>
72 :
public std::integral_constant<bool, T1::value || T2:: value>
74 template<
template<
int>
class Value>
75 struct AccFlag :
public GenericForLoop<OrOperation, Value, 0, size-1>
79 struct PatternVolumeValue :
public std::integral_constant
80 < bool, tuple_element<i, Args>::type::doPatternVolume>
83 struct PatternVolumePostSkeletonValue :
public std::integral_constant
84 < bool, tuple_element<i, Args>::type::doPatternVolumePostSkeleton>
87 struct PatternSkeletonValue :
public std::integral_constant
88 < bool, tuple_element<i, Args>::type::doPatternSkeleton>
91 struct PatternBoundaryValue :
public std::integral_constant
92 < bool, tuple_element<i, Args>::type::doPatternBoundary>
96 struct AlphaVolumeValue :
public std::integral_constant
97 < bool, tuple_element<i, Args>::type::doAlphaVolume>
100 struct AlphaVolumePostSkeletonValue :
public std::integral_constant
101 < bool, tuple_element<i, Args>::type::doAlphaVolumePostSkeleton>
104 struct AlphaSkeletonValue :
public std::integral_constant
105 < bool, tuple_element<i, Args>::type::doAlphaSkeleton>
108 struct AlphaBoundaryValue :
public std::integral_constant
109 < bool, tuple_element<i, Args>::type::doAlphaBoundary>
113 struct LambdaVolumeValue :
public std::integral_constant
114 < bool, tuple_element<i, Args>::type::doLambdaVolume>
117 struct LambdaVolumePostSkeletonValue :
public std::integral_constant
118 < bool, tuple_element<i, Args>::type::doLambdaVolumePostSkeleton>
121 struct LambdaSkeletonValue :
public std::integral_constant
122 < bool, tuple_element<i, Args>::type::doLambdaSkeleton>
125 struct LambdaBoundaryValue :
public std::integral_constant
126 < bool, tuple_element<i, Args>::type::doLambdaBoundary>
130 struct OneSidedSkeletonRequiredValue :
public std::integral_constant
131 < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
132 tuple_element<i, Args>::type::doLambdaSkeleton) &&
133 ! tuple_element<i, Args>::type::doSkeletonTwoSided)>
136 struct TwoSidedSkeletonRequiredValue :
public std::integral_constant
137 < bool, ( ( tuple_element<i, Args>::type::doAlphaSkeleton ||
138 tuple_element<i, Args>::type::doLambdaSkeleton) &&
139 tuple_element<i, Args>::type::doSkeletonTwoSided)>
201 "Some summands require a one-sided skelton, others a " 202 "two-sided skeleton. This is not supported.");
216 struct PatternVolumeOperation {
217 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
218 static void apply(
const ArgPtrs& lops,
219 const LFSU& lfsu,
const LFSV& lfsv,
220 LocalPattern& pattern)
223 tuple_element<i,Args>::type::doPatternVolume>
:: 229 struct PatternVolumePostSkeletonOperation {
230 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
231 static void apply(
const ArgPtrs& lops,
232 const LFSU& lfsu,
const LFSV& lfsv,
233 LocalPattern& pattern)
236 tuple_element<i,Args>::type::doPatternVolumePostSkeleton>
:: 242 struct PatternSkeletonOperation {
243 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
244 static void apply(
const ArgPtrs& lops,
245 const LFSU& lfsu_s,
const LFSV& lfsv_s,
246 const LFSU& lfsu_n,
const LFSV& lfsv_n,
247 LocalPattern& pattern_sn,
248 LocalPattern& pattern_ns)
251 tuple_element<i,Args>::type::doPatternSkeleton>
:: 253 lfsu_s, lfsv_s, lfsu_n, lfsv_n,
254 pattern_sn, pattern_ns);
259 struct PatternBoundaryOperation {
260 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
261 static void apply(
const ArgPtrs& lops,
262 const LFSU& lfsu_s,
const LFSV& lfsv_s,
263 LocalPattern& pattern_ss)
266 tuple_element<i,Args>::type::doPatternBoundary>
:: 278 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
280 (
const LFSU& lfsu,
const LFSV& lfsv,
281 LocalPattern& pattern)
const 283 ForLoop<PatternVolumeOperation, 0, size-1>::
284 apply(lops, lfsu, lfsv, pattern);
294 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
296 (
const LFSU& lfsu,
const LFSV& lfsv,
297 LocalPattern& pattern)
const 299 ForLoop<PatternVolumePostSkeletonOperation, 0, size-1>::
300 apply(lops, lfsu, lfsv, pattern);
309 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
311 (
const LFSU& lfsu_s,
const LFSV& lfsv_s,
312 const LFSU& lfsu_n,
const LFSV& lfsv_n,
313 LocalPattern& pattern_sn,
314 LocalPattern& pattern_ns)
const 316 ForLoop<PatternSkeletonOperation, 0, size-1>::
317 apply(lops, lfsu_s, lfsv_s, lfsu_n, lfsv_n,
318 pattern_sn, pattern_ns);
327 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
329 (
const LFSU& lfsu_s,
const LFSV& lfsv_s,
330 LocalPattern& pattern_ss)
const 332 ForLoop<PatternBoundaryOperation, 0, size-1>::
333 apply(lops, lfsu_s, lfsv_s, pattern_ss);
348 struct AlphaVolumeOperation {
349 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
351 static void apply(
const ArgPtrs& lops,
const EG& eg,
352 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
356 tuple_element<i,Args>::type::doAlphaVolume>
:: 362 struct AlphaVolumePostSkeletonOperation {
363 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
365 static void apply(
const ArgPtrs& lops,
const EG& eg,
366 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
370 tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>
:: 378 struct AlphaSkeletonOperation {
379 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
381 static void apply(
const ArgPtrs& lops,
const IG&
ig,
382 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
383 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
387 tuple_element<i,Args>::type::doAlphaSkeleton>
:: 396 struct AlphaBoundaryOperation {
397 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
399 static void apply(
const ArgPtrs& lops,
const IG&
ig,
400 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
404 tuple_element<i,Args>::type::doAlphaBoundary>
:: 415 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
419 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
422 ForLoop<AlphaVolumeOperation, 0, size-1>::
423 apply(lops, eg, lfsu, x, lfsv, r);
432 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
436 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
439 ForLoop<AlphaVolumePostSkeletonOperation, 0, size-1>::
440 apply(lops, eg, lfsu, x, lfsv, r);
448 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
452 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
453 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
454 R& r_s, R& r_n)
const 456 ForLoop<AlphaSkeletonOperation, 0, size-1>::
468 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
472 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
475 ForLoop<AlphaVolumePostSkeletonOperation, 0, size-1>::
476 apply(lops, ig, lfsu_s, x_s, lfsv_s, r_s);
491 struct LambdaVolumeOperation {
492 template<
typename EG,
typename LFSV,
typename R>
493 static void apply(
const ArgPtrs& lops,
const EG& eg,
498 tuple_element<i,Args>::type::doLambdaVolume>
:: 504 struct LambdaVolumePostSkeletonOperation {
505 template<
typename EG,
typename LFSV,
typename R>
506 static void apply(
const ArgPtrs& lops,
const EG& eg,
511 tuple_element<i,Args>::type::doLambdaVolumePostSkeleton>
:: 517 struct LambdaSkeletonOperation {
518 template<
typename IG,
typename LFSV,
typename R>
519 static void apply(
const ArgPtrs& lops,
const IG& ig,
525 tuple_element<i,Args>::type::doLambdaSkeleton>
:: 533 struct LambdaBoundaryOperation {
534 template<
typename IG,
typename LFSV,
typename R>
535 static void apply(
const ArgPtrs& lops,
const IG& ig,
540 tuple_element<i,Args>::type::doLambdaBoundary>
:: 551 template<
typename EG,
typename LFSV,
typename R>
554 ForLoop<LambdaVolumeOperation, 0, size-1>::
555 apply(lops, eg, lfsv, r);
564 template<
typename EG,
typename LFSV,
typename R>
569 ForLoop<LambdaVolumePostSkeletonOperation, 0, size-1>::
570 apply(lops, eg, lfsv, r);
578 template<
typename IG,
typename LFSV,
typename R>
580 const LFSV& lfsv_s,
const LFSV& lfsv_n,
581 R& r_s, R& r_n)
const 583 ForLoop<LambdaSkeletonOperation, 0, size-1>::
584 apply(lops, ig, lfsv_s, lfsv_n, r_s, r_n);
592 template<
typename IG,
typename LFSV,
typename R>
595 ForLoop<LambdaBoundaryOperation, 0, size-1>::
596 apply(lops, ig, lfsv_s, r_s);
611 struct JacobianApplyVolumeOperation {
612 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
614 static void apply(
const ArgPtrs& lops,
const EG& eg,
615 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
619 tuple_element<i,Args>::type::doAlphaVolume>
:: 625 struct JacobianApplyVolumePostSkeletonOperation {
626 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
628 static void apply(
const ArgPtrs& lops,
const EG& eg,
629 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
633 tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>
:: 641 struct JacobianApplySkeletonOperation {
642 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
644 static void apply(
const ArgPtrs& lops,
const IG& ig,
645 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
646 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
650 tuple_element<i,Args>::type::doAlphaSkeleton>
:: 659 struct JacobianApplyBoundaryOperation {
660 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
662 static void apply(
const ArgPtrs& lops,
const IG& ig,
663 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
667 tuple_element<i,Args>::type::doAlphaBoundary>
:: 680 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
684 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
687 ForLoop<JacobianApplyVolumeOperation, 0, size-1>::
688 apply(lops, eg, lfsu, x, lfsv, y);
697 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
701 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
704 ForLoop<JacobianApplyVolumePostSkeletonOperation, 0, size-1>::
705 apply(lops, eg, lfsu, x, lfsv, y);
713 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
717 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
718 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
719 Y& y_s, Y& y_n)
const 721 ForLoop<JacobianApplySkeletonOperation, 0, size-1>::
733 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
737 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
740 ForLoop<JacobianApplyBoundaryOperation, 0, size-1>::
741 apply(lops, ig, lfsu_s, x_s, lfsv_s, y_s);
756 struct JacobianVolumeOperation {
757 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
759 static void apply(
const ArgPtrs& lops,
const EG& eg,
760 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
764 tuple_element<i,Args>::type::doAlphaVolume>
:: 770 struct JacobianVolumePostSkeletonOperation {
771 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
773 static void apply(
const ArgPtrs& lops,
const EG& eg,
774 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
778 tuple_element<i,Args>::type::doAlphaVolumePostSkeleton>
:: 786 struct JacobianSkeletonOperation {
787 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
789 static void apply(
const ArgPtrs& lops,
const IG& ig,
790 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
791 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
796 tuple_element<i,Args>::type::doAlphaSkeleton>
:: 800 mat_ss, mat_sn, mat_ns, mat_nn);
805 struct JacobianBoundaryOperation {
806 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
808 static void apply(
const ArgPtrs& lops,
const IG& ig,
809 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
813 tuple_element<i,Args>::type::doAlphaBoundary>
:: 815 lfsu_s, x_s, lfsv_s, mat_ss);
825 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
829 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
832 ForLoop<JacobianVolumeOperation, 0, size-1>::
833 apply(lops, eg, lfsu, x, lfsv, mat);
841 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
845 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
848 ForLoop<JacobianVolumePostSkeletonOperation, 0, size-1>::
849 apply(lops, eg, lfsu, x, lfsv, mat);
857 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
861 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
862 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
866 ForLoop<JacobianSkeletonOperation, 0, size-1>::
870 mat_ss, mat_sn, mat_ns, mat_nn);
878 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
882 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
885 ForLoop<JacobianBoundaryOperation, 0, size-1>::
886 apply(lops, ig, lfsu_s, x_s, lfsv_s, mat_ss);
898 typedef typename tuple_element<0, Args>::type::RealType
RealType;
904 template<
int i>
struct SetTimeOperation {
905 static void apply(ArgPtrs& lops, RealType t)
909 template<
int i>
struct PreStepOperation {
910 static void apply(ArgPtrs& lops,
911 RealType time, RealType dt,
int stages)
912 { get<i>(lops)->
preStep(time, dt, stages); }
915 template<
int i>
struct PostStepOperation {
916 static void apply(ArgPtrs& lops)
920 template<
int i>
struct PreStageOperation {
921 static void apply(ArgPtrs& lops, RealType time,
int r)
922 { get<i>(lops)->
preStage(time, r); }
925 template<
int i>
struct PostStageOperation {
926 static void apply(ArgPtrs& lops)
930 template<
int i>
struct SuggestTimestepOperation {
931 static void apply(ArgPtrs& lops, RealType& dt)
939 ForLoop<SetTimeOperation, 0, size-1>::apply(lops, t);
945 return get<0>(lops)->
getTime();
949 void preStep (RealType time, RealType dt,
int stages)
951 ForLoop<PreStepOperation, 0, size-1>::apply(lops, time, dt, stages);
957 ForLoop<PostStepOperation, 0, size-1>::apply(lops);
963 ForLoop<PreStageOperation, 0, size-1>::apply(lops, time, r);
975 ForLoop<PostStageOperation, 0, size-1>::apply(lops);
986 ForLoop<SuggestTimestepOperation, 0, size-1>::apply(lops, dt);
997 #endif // DUNE_PDELAB_LOCALOPERATOR_SUM_HH const IG & ig
Definition: constraints.hh:148
A local operator to take the sum of other local operators.
Definition: sum.hh:29
void preStage(RealType time, int r)
to be called once before each stage
Definition: sum.hh:961
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:881
void postStep()
to be called once at the end of each time step
Definition: sum.hh:955
RealType suggestTimestep(RealType dt) const
to be called after stage 1
Definition: sum.hh:984
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:844
void preStep(RealType time, RealType dt, int stages)
to be called once before each time step
Definition: sum.hh:949
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:471
void postStage()
to be called once at the end of each stage
Definition: sum.hh:973
For backward compatibility – Do not use this!
Definition: adaptivity.hh:27
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:329
RealType getTime() const
get current time
Definition: sum.hh:943
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:565
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:451
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:418
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:716
tuple_element< 0, Args >::type::RealType RealType
Export type used for time values.
Definition: sum.hh:898
InstationarySumLocalOperator(const ArgRefs &lops_)
construct a InstationarySumLocalOperator from a tuple of local operators
Definition: sum.hh:47
void pattern_volume(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element's contribution to the sparsity pattern
Definition: sum.hh:280
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:435
Definition: callswitch.hh:64
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:683
tuple_element< i, Args >::type & getSummand()
get the i'th component of the sum
Definition: sum.hh:58
void setTime(RealType t)
set time for subsequent evaluation
Definition: sum.hh:937
A dense matrix for storing data associated with the degrees of freedom of a pair of LocalFunctionSpac...
Definition: localmatrix.hh:184
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:296
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:311
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:700
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:828
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:860
void lambda_volume(const EG &eg, const LFSV &lfsv, R &r) const
get an element's contribution to lambda
Definition: sum.hh:552
static const unsigned int value
Definition: gridfunctionspace/tags.hh:139
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:579
int getStage() const
get current stage
Definition: sum.hh:967
void setSummand(typename tuple_element< i, Args >::type &summand)
set the i'th component of the sum
Definition: sum.hh:53
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:593
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:736