FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
power_mirror.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <kernel/lafem/power_vector.hpp>
9#include <kernel/lafem/vector_mirror.hpp>
10
11namespace FEAT
12{
13 namespace LAFEM
14 {
16 namespace Intern
17 {
18 // PowerMirror helper class: this implements the actual recursion for the gather/scatter methods
19 template<int i_>
20 struct PowerMirrorHelper
21 {
22 template<typename SM_, typename BV_, typename PV_>
23 static void gather(const SM_& sm, BV_& bv, const PV_& pv, const Index bo)
24 {
25 sm.gather(bv, pv.first(), bo);
26 PowerMirrorHelper<i_-1>::gather(sm, bv, pv.rest(), bo + sm.buffer_size(pv.first()));
27 }
28 template<typename SM_, typename PV_, typename BV_, typename AT_>
29 static void scatter_axpy(const SM_& sm, PV_& pv, const BV_& bv, const AT_ a, const Index bo)
30 {
31 sm.scatter_axpy(pv.first(), bv, a, bo);
32 PowerMirrorHelper<i_-1>::scatter_axpy(sm, pv.rest(), bv, a, bo + sm.buffer_size(pv.first()));
33 }
34 template<typename SM_, typename PV_>
35 static Index buffer_size(const SM_& sm, PV_& pv)
36 {
37 return sm.buffer_size(pv.first()) + PowerMirrorHelper<i_-1>::buffer_size(sm, pv.rest());
38 }
39 template<Perspective perspective_, typename SM_, typename Pv_>
40 static Index mask_scatter(const SM_& sm, const Pv_& pv, std::vector<int>& mask, const int value, const Index offset)
41 {
42 Index nf = sm.template mask_scatter<perspective_>(pv.first(), mask, value, offset);
43 Index nr = PowerMirrorHelper<i_-1>::template mask_scatter<perspective_>(sm, pv.rest(), mask, value, offset + nf);
44 return nf + nr;
45 }
46 };
47
48 template<>
49 struct PowerMirrorHelper<1>
50 {
51 template<typename SM_, typename BV_, typename PV_>
52 static void gather(const SM_& sm, BV_& bv, const PV_& pv, const Index bo)
53 {
54 sm.gather(bv, pv.first(), bo);
55 }
56 template<typename SM_, typename PV_, typename BV_, typename AT_>
57 static void scatter_axpy(const SM_& sm, PV_& pv, const BV_& bv, const AT_ a, const Index bo)
58 {
59 sm.scatter_axpy(pv.first(), bv, a, bo);
60 }
61 template<typename SM_, typename PV_>
62 static Index buffer_size(const SM_& sm, PV_& pv)
63 {
64 return sm.buffer_size(pv.first());
65 }
66 template<Perspective perspective_, typename SM_, typename Pv_>
67 static Index mask_scatter(const SM_& sm, const Pv_& pv, std::vector<int>& mask, const int value, const Index offset)
68 {
69 return sm.template mask_scatter<perspective_>(pv.first(), mask, value, offset);
70 }
71 };
72 } // namespace Intern
74
92 template<typename SubMirror_, int count_>
94 {
95 public:
96 static_assert(count_ > 0, "invalid block size");
97
99 typedef SubMirror_ SubMirrorType;
101 typedef typename SubMirrorType::DataType DataType;
103 typedef typename SubMirrorType::IndexType IndexType;
104
106 static constexpr int num_blocks = count_;
107
109 template <typename DT2_ = DataType, typename IT2_ = IndexType>
111
113 template <typename DataType2_, typename IndexType2_>
115
118
121 {
122 }
123
125 explicit PowerMirror(SubMirrorType&& sub_mirror) :
126 _sub_mirror(std::move(sub_mirror))
127 {
128 }
129
132 _sub_mirror(std::move(other._sub_mirror))
133 {
134 }
135
138 {
139 if(this != &other)
140 {
141 _sub_mirror = std::move(other._sub_mirror);
142 }
143 return *this;
144 }
145
152 {
153 return PowerMirror(_sub_mirror.clone(clone_mode));
154 }
155
162 template<typename SubMirror2_>
164 {
165 this->_sub_mirror.convert(other._sub_mirror);
166 }
167
176 template<typename SubVector_>
178 {
179 return PowerMirror(SubMirrorType::make_empty(tmpl_vec.first()));
180 }
181
183 std::size_t bytes() const
184 {
185 return _sub_mirror.bytes();
186 }
187
193 bool empty() const
194 {
195 return this->_sub_mirror.empty();
196 }
197
204 template<typename SubVector_>
206 {
207 return Intern::PowerMirrorHelper<count_>::buffer_size(_sub_mirror, vector);
208 }
209
216 template<typename SubVector_>
218 {
220 }
221
231 template<int i_>
233 {
234 static_assert((0 <= i_) && (i_ < count_), "invalid sub-mirror index");
235 return _sub_mirror;
236 }
237
239 template<int i_>
240 const SubMirrorType& at() const
241 {
242 static_assert((0 <= i_) && (i_ < count_), "invalid sub-mirror index");
243 return _sub_mirror;
244 }
245
256 {
257 XASSERTM((0 <= i) && (i < count_), "invalid sub-mirror index");
258 return _sub_mirror;
259 }
260
262 const SubMirrorType& get(int i) const
263 {
264 XASSERTM((0 <= i) && (i < count_), "invalid sub-mirror index");
265 return _sub_mirror;
266 }
267
269 template<typename Tv_>
270 void gather(
273 const Index buffer_offset = Index(0)) const
274 {
275 Intern::PowerMirrorHelper<count_>::gather(_sub_mirror, buffer, vector, buffer_offset);
276 }
277
279 template<typename Tv_>
283 const DataType alpha = DataType(1),
284 const Index buffer_offset = Index(0)) const
285 {
286 Intern::PowerMirrorHelper<count_>::scatter_axpy(_sub_mirror, vector, buffer, alpha, buffer_offset);
287 }
288
290 template<Perspective perspective_, typename Tv_>
291 Index mask_scatter(const LAFEM::PowerVector<Tv_, count_>& vector, std::vector<int>& mask,
292 const int value, const Index offset = Index(0)) const
293 {
294 return Intern::PowerMirrorHelper<count_>::template mask_scatter<perspective_>(_sub_mirror, vector, mask, value, offset);
295 }
296
297 }; // class PowerMirror<...>
298 } // namespace LAFEM
299} // namespace FEAT
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Definition: assertion.hpp:263
Dense data vector class template.
PowerVector meta-mirror class template.
const SubMirrorType & at() const
Returns a sub-mirror block.
Index mask_scatter(const LAFEM::PowerVector< Tv_, count_ > &vector, std::vector< int > &mask, const int value, const Index offset=Index(0)) const
Updates a scatter mask vector for this mirror.
PowerMirror & operator=(PowerMirror &&other)
move-assign operator
PowerMirror(SubMirrorType &&sub_mirror)
sub-mirror move-ctor
void gather(LAFEM::DenseVector< DataType, IndexType > &buffer, const LAFEM::PowerVector< Tv_, count_ > &vector, const Index buffer_offset=Index(0)) const
Gathers the buffer entries from a DenseVector.
PowerMirror(PowerMirror &&other)
move-ctor
DenseVector< DataType, IndexType > create_buffer(const PowerVector< SubVector_, count_ > &vector) const
Creates a new buffer vector for a PowerVector.
Index buffer_size(const PowerVector< SubVector_, count_ > &vector) const
Computes the required buffer size for a PowerVector.
SubMirrorType::IndexType IndexType
sub-mirror index-type
SubMirrorType & at()
Returns a sub-mirror block.
SubMirrorType::DataType DataType
sub-mirror data-type
PowerMirror clone(CloneMode clone_mode=CloneMode::Weak) const
Clone operation.
std::size_t bytes() const
Returns the total amount of bytes allocated.
static PowerMirror make_empty(const PowerVector< SubVector_, count_ > &tmpl_vec)
Creates and returns an empty mirror.
SubMirrorType & get(int i)
Returns a sub-mirror block.
bool empty() const
Checks whether the mirror is empty.
SubMirrorType _sub_mirror
the one and only sub-mirror object
const SubMirrorType & get(int i) const
Returns a sub-mirror block.
void convert(const PowerMirror< SubMirror2_, count_ > &other)
Conversion method.
SubMirror_ SubMirrorType
sub-mirror type
void scatter_axpy(LAFEM::PowerVector< Tv_, count_ > &vector, const LAFEM::DenseVector< DataType, IndexType > &buffer, const DataType alpha=DataType(1), const Index buffer_offset=Index(0)) const
Scatters the buffer entries onto a DenseVector.
static constexpr int num_blocks
total number of sub-mirror blocks
Power-Vector meta class template.
FEAT namespace.
Definition: adjactor.hpp:12
@ value
specifies whether the space should supply basis function values
std::uint64_t Index
Index data type.