3 #ifndef DUNE_PDELAB_LOCALOPERATOR_COMBINEDOPERATOR_HH
4 #define DUNE_PDELAB_LOCALOPERATOR_COMBINEDOPERATOR_HH
9 #include <dune/common/tupleutility.hh>
10 #include <dune/common/typetraits.hh>
28 template<
typename ApplyOp,
typename... Args>
32 using ArgPtrs = std::tuple<std::shared_ptr<std::remove_reference_t<Args>>...>;
37 template<
typename... FArgs>
40 static_cast<const ApplyOp&
>(*this).applyLops(args...);
62 template<std::
size_t i>
63 void setSummand(
typename std::tuple_element_t<i,ArgRefs> summand)
64 { std::get<i>(
lops) = &summand; }
67 template<std::
size_t i>
69 {
return *std::get<i>(
lops); }
82 using OneSidedSkeleton = std::integral_constant
83 < bool, ( ( T::doAlphaSkeleton || T::doLambdaSkeleton) && ! T::doSkeletonTwoSided)>;
85 using TwoSidedSkeleton = std::integral_constant
86 < bool, ( ( T::doAlphaSkeleton || T::doLambdaSkeleton) && T::doSkeletonTwoSided)>;
93 std::disjunction_v<std::integral_constant<bool,Args::doSkipEntity>...> };
99 std::disjunction_v<std::integral_constant<bool,Args::doSkipIntersection>...> };
106 std::disjunction_v<std::integral_constant<bool,Args::doPatternVolume>...> };
112 std::disjunction_v<std::integral_constant<bool,Args::doPatternVolumePostSkeleton>...> };
117 std::disjunction_v<std::integral_constant<bool,Args::doPatternSkeleton>...> };
122 std::disjunction_v<std::integral_constant<bool,Args::doPatternBoundary>...> };
129 std::disjunction_v<std::integral_constant<bool,Args::doAlphaVolume>...> };
135 std::disjunction_v<std::integral_constant<bool,Args::doAlphaVolumePostSkeleton>...> };
139 std::disjunction_v<std::integral_constant<bool,Args::doAlphaSkeleton>...> };
143 std::disjunction_v<std::integral_constant<bool,Args::doAlphaBoundary>...> };
147 std::disjunction_v<std::integral_constant<bool,Args::doLambdaVolume>...> };
151 std::disjunction_v<std::integral_constant<bool,Args::doLambdaVolumePostSkeleton>...> };
154 std::disjunction_v<std::integral_constant<bool,Args::doLambdaSkeleton>...> };
157 std::disjunction_v<std::integral_constant<bool,Args::doLambdaBoundary>...> };
161 std::disjunction_v<TwoSidedSkeleton<Args>...> };
162 static_assert(!(std::conjunction_v<OneSidedSkeleton<Args>...> &&
163 std::conjunction_v<TwoSidedSkeleton<Args>...>),
164 "Some summands require a one-sided skelton, others a "
165 "two-sided skeleton. This is not supported.");
168 enum {
isLinear = std::conjunction_v<std::integral_constant<bool,Args::isLinear>...> };
179 template<
typename EG>
181 (
const EG& eg)
const
184 bool different_skips =
false;
185 Hybrid::forEach(std::make_index_sequence<
sizeof...(Args)>{},
187 different_skips ^= getSummand<i>().skip_entity(eg);
191 DUNE_THROW(RangeError,
"CombinedOperator is not allowed to have "
192 "different skip_entity results");
193 return getSummand<0>().skip_entity(eg);
197 template<
typename IG>
199 (
const IG&
ig)
const
202 bool different_skips =
false;
203 Hybrid::forEach(std::make_index_sequence<
sizeof...(Args)>{},
205 different_skips ^= getSummand<i>().skip_intersection(
ig);
209 DUNE_THROW(RangeError,
"CombinedOperator is not allowed to have "
210 "different skip_intersection results");
211 return getSummand<0>().skip_intersection(
ig);
228 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
230 (
const LFSU& lfsu,
const LFSV& lfsv,
231 LocalPattern& pattern)
const
233 applyLops(LocalOperatorApply::patternVolume, lfsu, lfsv, pattern);
243 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
245 (
const LFSU& lfsu,
const LFSV& lfsv,
246 LocalPattern& pattern)
const
248 applyLops(LocalOperatorApply::patternVolumePostSkeleton, lfsu, lfsv, pattern);
257 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
259 (
const LFSU& lfsu_s,
const LFSV& lfsv_s,
260 const LFSU& lfsu_n,
const LFSV& lfsv_n,
261 LocalPattern& pattern_sn,
262 LocalPattern& pattern_ns)
const
264 applyLops(LocalOperatorApply::patternSkeleton,
265 lfsu_s, lfsv_s, lfsu_n, lfsv_n,
266 pattern_sn, pattern_ns);
275 template<
typename LFSU,
typename LFSV,
typename LocalPattern>
277 (
const LFSU& lfsu_s,
const LFSV& lfsv_s,
278 LocalPattern& pattern_ss)
const
280 applyLops(LocalOperatorApply::patternBoundary, lfsu_s, lfsv_s, pattern_ss);
296 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
300 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
303 applyLops(LocalOperatorApply::alphaVolume, eg, lfsu, x, lfsv, r);
312 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
316 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
319 applyLops(LocalOperatorApply::alphaVolumePostSkeleton, eg, lfsu, x, lfsv, r);
327 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
331 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
332 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
333 R& r_s, R& r_n)
const
346 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
350 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
353 applyLops(LocalOperatorApply::alphaVolumePostSkeleton,
ig, lfsu_s, x_s, lfsv_s, r_s);
369 template<
typename EG,
typename LFSV,
typename R>
372 applyLops(LocalOperatorApply::lambdaVolume, eg, lfsv, r);
381 template<
typename EG,
typename LFSV,
typename R>
386 applyLops(LocalOperatorApply::lambdaVolumePostSkeleton, eg, lfsv, r);
394 template<
typename IG,
typename LFSV,
typename R>
396 const LFSV& lfsv_s,
const LFSV& lfsv_n,
397 R& r_s, R& r_n)
const
399 applyLops(LocalOperatorApply::lambdaSkeleton,
ig, lfsv_s, lfsv_n, r_s, r_n);
407 template<
typename IG,
typename LFSV,
typename R>
410 applyLops(LocalOperatorApply::lambdaBoundary,
ig, lfsv_s, r_s);
426 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
430 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
442 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
446 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
449 applyLops(LocalOperatorApply::jacobianApplyVolumePostSkeleton, eg, lfsu, x, lfsv, y);
457 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
461 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
462 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
463 Y& y_s, Y& y_n)
const
476 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
480 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
499 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
503 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
506 applyLops(LocalOperatorApply::jacobianVolume, eg, lfsu, x, lfsv, mat);
514 template<
typename EG,
typename LFSU,
typename X,
typename LFSV,
518 const LFSU& lfsu,
const X& x,
const LFSV& lfsv,
521 applyLops(LocalOperatorApply::jacobianVolumePostSkeleton, eg, lfsu, x, lfsv, mat);
529 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
533 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
534 const LFSU& lfsu_n,
const X& x_n,
const LFSV& lfsv_n,
538 applyLops(LocalOperatorApply::jacobianSkeleton,
ig,
541 mat_ss, mat_sn, mat_ns, mat_nn);
549 template<
typename IG,
typename LFSU,
typename X,
typename LFSV,
553 const LFSU& lfsu_s,
const X& x_s,
const LFSV& lfsv_s,
556 applyLops(LocalOperatorApply::jacobianBoundary,
ig, lfsu_s, x_s, lfsv_s, mat_ss);
568 typedef typename std::tuple_element<0, std::tuple<Args...>>::type::RealType
RealType;
575 template<
typename LOP>
581 template<
typename LOP>
585 lop.preStep(time, dt, stages);
588 template<
typename LOP>
594 template<
typename LOP>
597 lop.preStage(time, r);
600 template<
typename LOP>
606 template<
typename LOP>
609 dt = std::min(dt,lop.suggestTimestep(dt));
623 return get<0>(
lops)->getTime();
629 applyLops(Apply::preStep, time, dt, stages);
647 return get<0>(
lops)->getStage();
const IG & ig
Definition: constraints.hh:149
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:460
bool skip_intersection(const IG &ig) const
whether to assembly methods associated with a given intersection
Definition: combinedoperator.hh:199
void pattern_volume(const LFSU &lfsu, const LFSV &lfsv, LocalPattern &pattern) const
get an element's contribution to the sparsity pattern
Definition: combinedoperator.hh:230
RealType suggestTimestep(RealType dt) const
to be called after stage 1
Definition: combinedoperator.hh:662
RealType getTime() const
get current time
Definition: combinedoperator.hh:621
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:479
void lambda_volume(const EG &eg, const LFSV &lfsv, R &r) const
get an element's contribution to lambda
Definition: combinedoperator.hh:370
static void postStep(const LOP &lop)
Definition: combinedoperator.hh:589
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:259
static void preStage(const LOP &lop, RealType time, int r)
Definition: combinedoperator.hh:595
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:429
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:315
void applyLops(FArgs &... args) const
Definition: combinedoperator.hh:38
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:277
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:532
void postStep()
to be called once at the end of each time step
Definition: combinedoperator.hh:633
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:382
void preStage(RealType time, int r)
to be called once before each stage
Definition: combinedoperator.hh:639
static void setTime(const LOP &lop, RealType t)
Definition: combinedoperator.hh:576
ArgPtrs lops
Definition: combinedoperator.hh:35
std::tuple< Args &... > ArgRefs
Definition: combinedoperator.hh:33
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:552
int getStage() const
get current stage
Definition: combinedoperator.hh:645
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:502
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:330
void postStage()
to be called once at the end of each stage
Definition: combinedoperator.hh:651
void setSummand(typename std::tuple_element_t< i, ArgRefs > summand)
set the i'th component of the sum
Definition: combinedoperator.hh:63
static void postStage(const LOP &lop)
Definition: combinedoperator.hh:601
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:245
std::tuple_element< 0, std::tuple< Args... > >::type::RealType RealType
Export type used for time values.
Definition: combinedoperator.hh:568
CombinedOperator(ArgPtrs &&l)
Definition: combinedoperator.hh:58
CombinedOperator(Args &&... args)
Definition: combinedoperator.hh:54
void preStep(RealType time, RealType dt, int stages)
to be called once before each time step
Definition: combinedoperator.hh:627
static void preStep(const LOP &lop, RealType time, RealType dt, int stages)
Definition: combinedoperator.hh:582
std::tuple_element_t< i, ArgRefs > getSummand()
get the i'th component of the sum
Definition: combinedoperator.hh:68
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:395
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:408
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:517
std::tuple< std::shared_ptr< std::remove_reference_t< Args > >... > ArgPtrs
Definition: combinedoperator.hh:32
void setTime(RealType t)
set time for subsequent evaluation
Definition: combinedoperator.hh:615
bool skip_entity(const EG &eg) const
whether to assembly methods associated with a given entity
Definition: combinedoperator.hh:181
static RealType suggestTimestep(const LOP &lop, RealType &dt)
Definition: combinedoperator.hh:607
CombinedOperator(Args &... args)
Definition: combinedoperator.hh:52
CombinedOperator()
Definition: combinedoperator.hh:50
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:445
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:349
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:299
@ doLambdaVolumePostSkeleton
Definition: combinedoperator.hh:150
@ doLambdaSkeleton
Definition: combinedoperator.hh:153
@ doSkeletonTwoSided
Definition: combinedoperator.hh:160
@ isLinear
Definition: combinedoperator.hh:168
@ doPatternSkeleton
Definition: combinedoperator.hh:116
@ doAlphaSkeleton
Definition: combinedoperator.hh:138
@ doLambdaVolume
Definition: combinedoperator.hh:146
@ doAlphaBoundary
Definition: combinedoperator.hh:142
@ doPatternBoundary
Definition: combinedoperator.hh:121
@ doPatternVolumePostSkeleton
Definition: combinedoperator.hh:111
@ doPatternVolume
Definition: combinedoperator.hh:105
@ doSkipEntity
Definition: combinedoperator.hh:92
@ doLambdaBoundary
Definition: combinedoperator.hh:156
@ doSkipIntersection
Definition: combinedoperator.hh:98
@ doAlphaVolume
Definition: combinedoperator.hh:128
@ doAlphaVolumePostSkeleton
Definition: combinedoperator.hh:134
For backward compatibility – Do not use this!
Definition: adaptivity.hh:28
std::enable_if_t< LOP::isLinear > jacobianApplySkeleton(const LOP &lop, const IG &ig, const LFSU &lfsu_s, const X &z_s, const LFSV &lfsv_s, const LFSU &lfsu_n, const X &z_n, const LFSV &lfsv_n, Y &y_s, Y &y_n)
Definition: jacobianapplyhelper.hh:64
std::enable_if_t< LOP::isLinear > jacobianApplyVolume(const LOP &lop, const EG &eg, const LFSU &lfsu, const X &z, const LFSV &lfsv, Y &y)
Definition: jacobianapplyhelper.hh:23
std::enable_if_t< LOP::isLinear > jacobianApplyBoundary(const LOP &lop, const IG &ig, const LFSU &lfsu_s, const X &z_s, const LFSV &lfsv_s, Y &y_s)
Definition: jacobianapplyhelper.hh:109
A dense matrix for storing data associated with the degrees of freedom of a pair of LocalFunctionSpac...
Definition: localmatrix.hh:184
A local operator to take combine different local operators.
Definition: combinedoperator.hh:30