Flow123d  DF_patch_fe_mechanics-b866f5c
arena_vec.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file arena_vec.hh
15  */
16 
17 #ifndef ARENA_VEC_HH_
18 #define ARENA_VEC_HH_
19 
20 #include "fem/arena_resource.hh"
21 #include "system/asserts.hh"
22 
23 #include <Eigen/Core>
24 #include <Eigen/Dense>
25 
26 
27 
28 template<class T> class ArenaOVec;
29 
30 
31 /**
32  * Define vector allocated in ArenaResource and aligned to SIMD size.
33  */
34 template<class T>
35 class ArenaVec {
36 public:
37  /// Type definition
38  typedef Eigen::Matrix<T, Eigen::Dynamic, 1> VecData;
39  typedef Eigen::Array<T, Eigen::Dynamic, 1> ArrayData;
40 
41  /// Default constructor, set invalid data pointer
43  : data_ptr_(nullptr), data_size_(0), arena_(nullptr), scalar_val_( (T)0 ) {}
44 
45  /**
46  * Constructor. Set scalar value
47  */
49  : data_ptr_(nullptr), data_size_(0), arena_(nullptr), scalar_val_(scalar_val) {}
50 
51  /**
52  * Constructor. Set sizes and allocate data pointer
53  */
55  : data_ptr_(nullptr), data_size_(data_size), arena_(&arena), scalar_val_( (T)0 ) {
57  }
58 
59  /// Copy constructor
60  ArenaVec(const ArenaVec<T> &other)
61  : data_ptr_(other.data_ptr_), data_size_(other.data_size_),
62  arena_(other.arena_), scalar_val_(other.scalar_val_)
63  {}
64 
65  /**
66  * Maps data pointer to Eigen Map of dimensions given data_size_ and returns it.
67  */
68  inline Eigen::Map<VecData> eigen_map() {
70  return Eigen::Map<VecData>(data_ptr_, data_size_, 1);
71  }
72 
73  /// Smae as previous but with const modifier
74  inline const Eigen::Map<VecData> eigen_map() const {
76  return Eigen::Map<VecData>(data_ptr_, data_size_, 1);
77  }
78 
79  /**
80  * Maps data pointer to Eigen Map of dimensions given data_size_ and returns it.
81  */
82  inline Eigen::Map<ArrayData> array_map() {
84  return Eigen::Map<ArrayData>(data_ptr_, data_size_, 1);
85  }
86 
87  /// Smae as previous but with const modifier
88  inline const Eigen::Map<ArrayData> array_map() const {
90  return Eigen::Map<ArrayData>(data_ptr_, data_size_, 1);
91  }
92 
93  /// Return data pointer (development method)
94  T* data_ptr() {
95  return data_ptr_;
96  }
97 
98  /// Smae as previous but return const pointer
99  const T* data_ptr() const {
100  return data_ptr_;
101  }
102 
103  /// Getter for data_size_
104  inline size_t data_size() const {
105  return data_size_;
106  }
107 
108  /// Getter for arena_
110  return *arena_;
111  }
112 
113  /// Getter for scalar_val_
114  T scalar_val() const {
115  return scalar_val_;
116  }
117 
118  /// Set pointer to PatchArena
121  this->arena_ = &arena;
122  }
123 
124  /// Returns copied vector of square root values
125  inline ArenaVec<T> sqrt() const {
128  Eigen::Map<ArrayData> result_map = res.array_map();
129  result_map = this->array_map().sqrt();
130  return res;
131  }
132 
133  /// Returns copied vector of inverse values
134  inline ArenaVec<T> inverse() const {
137  Eigen::Map<ArrayData> result_map = res.array_map();
138  result_map = this->array_map().inverse();
139  return res;
140  }
141 
142  /// Returns copied vector of absolute values
143  inline ArenaVec<T> abs() const {
146  Eigen::Map<ArrayData> result_map = res.array_map();
147  result_map = this->array_map().abs();
148  return res;
149  }
150 
151  /// For development only. TODO remove
152  inline T & operator()(std::size_t item) {
154  ASSERT_LT(item, data_size_);
155  return data_ptr_[item];
156  }
157 
158  /// For development only. TODO remove
159  inline const T & operator()(std::size_t item) const {
160  ASSERT_LT(item, data_size_);
161  return data_ptr_[item];
162  }
163 
164  /// Assignment operator
165  inline ArenaVec<T> &operator=(const ArenaVec<T> &other) {
166  data_ptr_ = other.data_ptr_;
167  data_size_ = other.data_size_;
168  arena_ = other.arena_;
169  scalar_val_ = other.scalar_val_;
170  return *this;
171  }
172 
173  /**
174  * Addition operator
175  *
176  * Sums two ArenaVec objects
177  * TODO If ASSERT_PTR is thrown needs to implement tests of scalar values (see multiplication operator).
178  */
179  inline ArenaVec<T> operator+(const ArenaVec<T> &other) const {
181  ASSERT_PTR(other.data_ptr());
182  ASSERT_EQ(data_size_, other.data_size());
184  Eigen::Map<VecData> result_map = res.eigen_map();
185  result_map = this->eigen_map() + other.eigen_map();
186  return res;
187  }
188 
189  /**
190  * Subtraction operator
191  *
192  * Subtracts two ArenaVec objects
193  * TODO If ASSERT_PTR is thrown needs to implement tests of scalar values (see multiplication operator).
194  */
195  inline ArenaVec<T> operator-(const ArenaVec<T> &other) const {
197  ASSERT_PTR(other.data_ptr());
198  ASSERT_EQ(data_size_, other.data_size());
200  Eigen::Map<ArrayData> result_map = res.array_map();
201  result_map = this->array_map() - other.array_map();
202  return res;
203  }
204 
205  /**
206  * Multiplication operator
207  *
208  * Product Scalar x ArenaVec
209  */
210  inline ArenaVec<T> operator*(T multi) const {
213  Eigen::Map<ArrayData> result_map = res.array_map();
214  result_map = this->array_map() * multi;
215  return res;
216  }
217 
218  /**
219  * Multiplication operator
220  *
221  * Product of two ArenaVec objects, checks if one ofe them is define as scalar
222  */
223  inline ArenaVec<T> operator*(const ArenaVec<T> &other) const {
224  if (data_ptr_ == nullptr)
225  return other * scalar_val_;
226  if (other.data_ptr() == nullptr)
227  return this->operator *(other.scalar_val());
228  ASSERT_EQ(data_size_, other.data_size());
230  Eigen::Map<ArrayData> result_map = res.array_map();
231  result_map = this->array_map() * other.array_map();
232  return res;
233  }
234 
235  /**
236  * Division operator
237  *
238  * Divides ArenaVec / Scalar
239  */
240  inline ArenaVec<T> operator/(T div_by) const {
243  Eigen::Map<ArrayData> result_map = res.array_map();
244  result_map = this->array_map() / div_by;
245  return res;
246  }
247 
248  /**
249  * Division operator
250  *
251  * Divides two ArenaVec objects
252  * TODO If ASSERT_PTR is thrown needs to implement tests of scalar values (see multiplication operator).
253  */
254  inline ArenaVec<T> operator/(const ArenaVec<T> &other) const {
256  ASSERT_PTR(other.data_ptr());
257  ASSERT_EQ(data_size_, other.data_size());
259  Eigen::Map<ArrayData> result_map = res.array_map();
260  result_map = this->array_map() / other.array_map();
261  return res;
262  }
263 
264 protected:
265  /// Constructor. Allows create ArenaVec from ArenaOVec
268 
269  T* data_ptr_; ///< Pointer to data array
270  size_t data_size_; ///< Length of data array
271  PatchArena *arena_; ///< Pointer to Arena where intermediate calculations and results are stored, should be changed by set_patch_arena
272  T scalar_val_; ///< Scalar value of T type
273 
274  friend class ArenaOVec<T>;
275 };
276 
277 
278 
279 /**
280  * Define vector allocated in ArenaResource based on ArenaVec with overwrite
281  * multiplication operator that executes outer product.
282  *
283  * Example of usage with conversions between ArenaVec and ArenaOVec:
284  @code
285  ArenaVec<double> outer_product(ArenaVec<double> a, ArenaVec<double> b) {
286  // Convert ArenaVec inputs to ArenaOVec variables
287  ArenaOVec<double> a_ovec(a);
288  ArenaOVec<double> b_ovec(b);
289 
290  // performs outer product
291  ArenaOVec<double> result_ovec = a * b;
292 
293  // reverse conversion to ArenaVec
294  return result_ovec.get_vec();
295  }
296  @endcode
297  *
298  * If we consider that size of input vector 'a' is 'M' and size of input vector 'b' is 'N'
299  * then size of returned vector is 'M*N'.
300  */
301 template<class T>
302 class ArenaOVec : public ArenaVec<T> {
303 public:
304  /// Default constructor
306  : ArenaVec<T>() {}
307 
308  /// Copy constructor
309  ArenaOVec(const ArenaOVec<T> &other)
310  : ArenaVec<T>(other) {}
311 
312  /// Constructor. Set scalar_val
314  : ArenaVec<T>(scalar_val) {}
315 
316  /**
317  * Constructor creates ArenaOVec on data of ArenaVec
318  */
320  ASSERT_PTR(vec.data_ptr());
321 
322  this->data_ptr_ = vec.data_ptr_;
323  this->data_size_ = vec.data_size_;
324  this->arena_ = vec.arena_;
325  }
326 
327  /// Convert ArenaOVec to ArenaVec and its
329  return ArenaVec<T>(*this);
330  }
331 
332  /// Assignment operator
333  inline ArenaOVec<T> &operator=(const ArenaOVec<T> &other) {
334  ArenaVec<T>::operator=(other);
335  return *this;
336  }
337 
338  /// Addition operator
339  inline ArenaOVec<T> operator+(const ArenaOVec<T> &other) const {
340  // Test of valid data_ptr is in constructor
341  ASSERT_EQ(this->data_size_, other.data_size());
342  ArenaVec<T> res_vec(this->data_size_, *this->arena_);
343  ArenaOVec<T> res(res_vec);
344  Eigen::Map<typename ArenaVec<T>::VecData> result_map = res.eigen_map();
345  result_map = this->eigen_map() + other.eigen_map();
346  return res;
347  }
348 
349  /// Multiplication operator
350  inline ArenaOVec<T> operator*(const ArenaOVec<T> &other) const {
351  typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> MatData;
352 
353  ArenaVec<T> res_vec(this->data_size_*other.data_size(), *this->arena_);
354  ArenaOVec<T> res(res_vec);
355  Eigen::Map<MatData> result_map = Eigen::Map<MatData>(res.data_ptr(), this->data_size_, other.data_size());
356  result_map = this->eigen_map() * other.eigen_map().transpose();
357  return res;
358  }
359 };
360 
361 
362 #endif /* ARENA_VEC_HH_ */
Definitions of ASSERTS.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:301
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:341
ArenaOVec< T > operator+(const ArenaOVec< T > &other) const
Addition operator.
Definition: arena_vec.hh:339
ArenaVec< T > get_vec() const
Convert ArenaOVec to ArenaVec and its.
Definition: arena_vec.hh:328
ArenaOVec(const ArenaVec< T > &vec)
Definition: arena_vec.hh:319
ArenaOVec< T > & operator=(const ArenaOVec< T > &other)
Assignment operator.
Definition: arena_vec.hh:333
ArenaOVec(const ArenaOVec< T > &other)
Copy constructor.
Definition: arena_vec.hh:309
ArenaOVec(T scalar_val)
Constructor. Set scalar_val.
Definition: arena_vec.hh:313
ArenaOVec()
Default constructor.
Definition: arena_vec.hh:305
ArenaOVec< T > operator*(const ArenaOVec< T > &other) const
Multiplication operator.
Definition: arena_vec.hh:350
ArenaVec(T scalar_val)
Definition: arena_vec.hh:48
Eigen::Array< T, Eigen::Dynamic, 1 > ArrayData
Definition: arena_vec.hh:39
ArenaVec()
Default constructor, set invalid data pointer.
Definition: arena_vec.hh:42
Eigen::Matrix< T, Eigen::Dynamic, 1 > VecData
Type definition.
Definition: arena_vec.hh:38
ArenaVec< T > operator/(const ArenaVec< T > &other) const
Definition: arena_vec.hh:254
const T * data_ptr() const
Smae as previous but return const pointer.
Definition: arena_vec.hh:99
PatchArena & arena()
Getter for arena_.
Definition: arena_vec.hh:109
T * data_ptr()
Return data pointer (development method)
Definition: arena_vec.hh:94
const T & operator()(std::size_t item) const
For development only. TODO remove.
Definition: arena_vec.hh:159
const Eigen::Map< ArrayData > array_map() const
Smae as previous but with const modifier.
Definition: arena_vec.hh:88
ArenaVec< T > sqrt() const
Returns copied vector of square root values.
Definition: arena_vec.hh:125
ArenaVec< T > operator*(T multi) const
Definition: arena_vec.hh:210
ArenaVec< T > operator*(const ArenaVec< T > &other) const
Definition: arena_vec.hh:223
Eigen::Map< VecData > eigen_map()
Definition: arena_vec.hh:68
ArenaVec< T > abs() const
Returns copied vector of absolute values.
Definition: arena_vec.hh:143
Eigen::Map< ArrayData > array_map()
Definition: arena_vec.hh:82
size_t data_size_
Length of data array.
Definition: arena_vec.hh:270
const Eigen::Map< VecData > eigen_map() const
Smae as previous but with const modifier.
Definition: arena_vec.hh:74
ArenaVec< T > operator/(T div_by) const
Definition: arena_vec.hh:240
ArenaVec< T > inverse() const
Returns copied vector of inverse values.
Definition: arena_vec.hh:134
ArenaVec< T > & operator=(const ArenaVec< T > &other)
Assignment operator.
Definition: arena_vec.hh:165
void set_patch_arena(PatchArena &arena)
Set pointer to PatchArena.
Definition: arena_vec.hh:119
ArenaVec< T > operator-(const ArenaVec< T > &other) const
Definition: arena_vec.hh:195
PatchArena * arena_
Pointer to Arena where intermediate calculations and results are stored, should be changed by set_pat...
Definition: arena_vec.hh:271
T & operator()(std::size_t item)
For development only. TODO remove.
Definition: arena_vec.hh:152
ArenaVec< T > operator+(const ArenaVec< T > &other) const
Definition: arena_vec.hh:179
ArenaVec(size_t data_size, PatchArena &arena)
Definition: arena_vec.hh:54
ArenaVec(const ArenaVec< T > &other)
Copy constructor.
Definition: arena_vec.hh:60
ArenaVec(T *data_ptr, size_t data_size, PatchArena &arena)
Constructor. Allows create ArenaVec from ArenaOVec.
Definition: arena_vec.hh:266
size_t data_size() const
Getter for data_size_.
Definition: arena_vec.hh:104
T scalar_val_
Scalar value of T type.
Definition: arena_vec.hh:272
T scalar_val() const
Getter for scalar_val_.
Definition: arena_vec.hh:114
T * data_ptr_
Pointer to data array.
Definition: arena_vec.hh:269
T * allocate_simd(size_t n_items)
Allocate and return data pointer of n_item array of type T (alignment to length given by simd_alignme...
ArmaVec< double, N > vec
Definition: armor.hh:933