DUNE PDELab (git)

weightedsum.hh
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=8 sw=2 sts=2:
3#ifndef DUNE_PDELAB_LOCALOPERATOR_WEIGHTEDSUM_HH
4#define DUNE_PDELAB_LOCALOPERATOR_WEIGHTEDSUM_HH
5
7#include <dune/pdelab/localoperator/sum.hh>
8
9namespace Dune {
10 namespace PDELab {
14
16
25 template<typename K, typename... Args>
27 public CombinedOperator<WeightedSumLocalOperator<K, Args...>, Args...>
28 {
29 protected:
30 using Base = CombinedOperator<WeightedSumLocalOperator<K, Args...>, Args...>;
31 using ArgPtrs = typename Base::ArgPtrs;
32 using ArgRefs = typename Base::ArgRefs;
33 friend Base;
34
35 using Weights = FieldVector<K, sizeof...(Args)>;
36 Weights weights;
37
38 // concept check for a weighted container, like e.g. LocalVector or LocalMatrix
39 struct WeightedContainer {
40 template<class C>
41 auto require(C& c) -> decltype(
42 Concept::requireType<typename C::weight_type>(),
43 const_cast<C&>(c).weight()
44 // c.setWeight(std::declval<typename C::weight_type>())
45 );
46 };
47
48 template<typename... FArgs>
49 void getWeights(FieldVector<K, sizeof...(FArgs)> & aweights,
50 std::tuple<FArgs...> fargs) const
51 {
52 Hybrid::forEach(std::make_index_sequence<sizeof...(FArgs)>{},
53 [&](auto j){
54 const auto & a = get<j>(fargs);
55 Hybrid::ifElse(models<WeightedContainer,decltype(a)>(),
56 [&](auto id){
57 aweights[j] = id(a).weight();});
58 });
59 }
60
61 template<typename... FArgs>
62 void setWeights(const FieldVector<K, sizeof...(FArgs)> & aweights,
63 std::tuple<FArgs...> fargs) const
64 {
65 Hybrid::forEach(std::make_index_sequence<sizeof...(FArgs)>{},
66 [&](auto j){
67 auto & a = get<j>(fargs);
68 Hybrid::ifElse(models<WeightedContainer,decltype(a)>(),
69 [&](auto id){
70 id(a).setWeight(aweights[j]);});
71 });
72 }
73
74 template<typename F, typename... FArgs>
75 void applyLops(F && f, FArgs &... fargs) const
76 {
77 // remember weights
78 FieldVector<K, sizeof...(FArgs)> aweights(K(0));
79 FieldVector<K, sizeof...(FArgs)> current_weights;
80 getWeights(aweights, std::forward_as_tuple(fargs...));
81 Hybrid::forEach(std::make_index_sequence<sizeof...(Args)>{},
82 [&](auto i){
83 if(weights[i] != K(0)) {
84 // set weights
85 current_weights = aweights;
86 current_weights *= weights[i];
87 setWeights(current_weights, std::forward_as_tuple(fargs...));
88 f(*Hybrid::elementAt(this->lops, i), fargs...);}}
89 );
90 // reset weights
91 setWeights(aweights, std::forward_as_tuple(fargs...));
92 }
93
94 public:
96 //
99 //
100
102
107 : weights(weights_)
108 { }
109
113 const Weights& weights_ = Weights(1))
114 : Base(lops_...), weights(weights_)
115 { }
116
119 WeightedSumLocalOperator (Args&&... lops_,
120 const Weights& weights_ = Weights(1))
121 : Base(std::forward<Args>(lops_)...), weights(weights_)
122 { }
123
124 protected:
125 WeightedSumLocalOperator(ArgPtrs&& lops, const Weights& weights_)
126 : Base(std::forward<ArgPtrs>(lops)), weights(weights_)
127 { }
128
129 public:
131 void setWeight(K w, std::size_t i)
132 { weights[i] = w; }
133
135 K getWeight(std::size_t i)
136 { return weights[i]; }
137
139 };
140
142
152 template<typename K, typename... Args>
153 class WeightedSumLocalOperator<K, std::tuple<Args...>> :
154 public WeightedSumLocalOperator<K, Args...>
155 {
156 using Base = WeightedSumLocalOperator<K, Args...>;
157 using ArgRefs = typename Base::ArgRefs;
158 using Weights = typename Base::Weights;
159
160 public:
162
166 [[deprecated("The specialization WeightedSumLocalOperator<K,Tuple<...>> is"
167 "deprecated and will be removed after PDELab 2.7.")]]
168 WeightedSumLocalOperator (const Weights& weights_ = Weights(1))
169 : Base(weights_)
170 { }
171
173 [[deprecated("The specialization WeightedSumLocalOperator<K,Tuple<...>> is"
174 "deprecated and will be removed after PDELab 2.7.")]]
175 WeightedSumLocalOperator (const ArgRefs& lops_, const Weights& weights_ = Weights(1))
177 [](auto & l){return stackobject_to_shared_ptr(l);}), weights_)
178 { }
179 };
180
181 }
182}
183
184#endif // DUNE_PDELAB_LOCALOPERATOR_WEIGHTEDSUM_HH
A local operator to take combine different local operators.
Definition: combinedoperator.hh:30
A local operator to take the weighted sum of other local operators.
Definition: weightedsum.hh:28
Infrastructure for concepts.
constexpr auto models()
Check if concept is modeled by given types.
Definition: concept.hh:184
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:344
constexpr decltype(auto) elementAt(Container &&c, Index &&i)
Get element at given position from container.
Definition: hybridutilities.hh:126
WeightedSumLocalOperator(Args &... lops_, const Weights &weights_=Weights(1))
Definition: weightedsum.hh:112
WeightedSumLocalOperator(Args &&... lops_, const Weights &weights_=Weights(1))
Definition: weightedsum.hh:119
WeightedSumLocalOperator(const Weights &weights_=Weights(1))
construct a WeightedSumLocalOperator
Definition: weightedsum.hh:106
void setWeight(K w, std::size_t i)
set the weight for the i'th component of the sum
Definition: weightedsum.hh:131
WeightedSumLocalOperator(const ArgRefs &lops_, const Weights &weights_=Weights(1))
construct a WeightedSumLocalOperator from a tuple of local operators
Definition: weightedsum.hh:175
K getWeight(std::size_t i)
get the weight for the i'th component of the sum
Definition: weightedsum.hh:135
WeightedSumLocalOperator(const Weights &weights_=Weights(1))
construct a WeightedSumLocalOperator
Definition: weightedsum.hh:168
auto genericTransformTuple(Tuple &&t, Functor &&f) -> decltype(genericTransformTupleBackend(t, f))
Definition: tupleutility.hh:186
Dune namespace.
Definition: alignedallocator.hh:13
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:72
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)