Flow123d  JS_before_hm-1602-g5680f2c
field_value_cache.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 field_value_cache.hh
15  * @brief
16  * @author David Flanderka
17  */
18 
19 #ifndef FIELD_VALUE_CACHE_HH_
20 #define FIELD_VALUE_CACHE_HH_
21 
22 #include <set>
23 #include <unordered_map>
24 #include <unordered_set>
25 #include <vector>
26 #include "system/armor.hh"
27 #include "fields/eval_points.hh"
28 #include "mesh/accessors.hh"
29 #include "tools/mixed.hh"
30 #include "tools/revertable_list.hh"
31 #include "fem/dofhandler.hh"
32 
33 class EvalPoints;
34 class ElementCacheMap;
35 class DHCellAccessor;
36 class DHCellSide;
37 template < template<IntDim...> class DimAssembly> class GenericAssembly;
38 
39 
40 /**
41  * @brief Class holds precomputed field values of selected element set.
42  *
43  * Every field in equation use own instance used for elements of all dimensions.
44  */
45 template<class elm_type> using FieldValueCache = Armor::Array<elm_type>;
46 
47 
48 /**
49  * Specifies eval points by idx of region, element and eval point.
50  *
51  * TODO Add better description after finish implementation
52  */
53 struct EvalPointData {
54  EvalPointData() {} ///< Default constructor
55  /// Constructor sets all data members
56  EvalPointData(unsigned int i_reg, unsigned int i_ele, unsigned int i_ep, unsigned int dh_loc_idx)
57  : i_reg_(i_reg), i_element_(i_ele), i_eval_point_(i_ep), dh_loc_idx_(dh_loc_idx) {}
58  /// Copy constructor
61 
62 
63  bool operator < (const EvalPointData &other) {
64  if (i_reg_ == other.i_reg_) {
65  if (i_element_ == other.i_element_)
66  return (i_eval_point_ < other.i_eval_point_);
67  else
68  return (i_element_ < other.i_element_);
69  } else
70  return (i_reg_ < other.i_reg_);
71  }
72 
73  unsigned int i_reg_; ///< region_idx of element
74  unsigned int i_element_; ///< mesh_idx of ElementAccessor appropriate to element
75  unsigned int i_eval_point_; ///< index of point in EvalPoint object
76  unsigned int dh_loc_idx_; ///< local index of cell in DOF handler
77 };
78 
79 
80 /// Holds pair of positions of point in cache (element and eval point)
81 struct PatchCacheLoc {
82  PatchCacheLoc() {} ///< Default constructor
83  /// Constructor sets all data members
84  PatchCacheLoc(unsigned int i_elm, unsigned int i_ep)
85  : i_elm_(i_elm), i_ep_(i_ep) {}
86 
87  unsigned int i_elm_; ///< index of element in patch
88  unsigned int i_ep_; ///< index of eval point in patch
89 };
90 
91 
92 /**
93  * @brief Auxiliary data class holds number of elements in cache and allow to set this value
94  * explicitly (e.g. as input parameter).
95  *
96  * Implementation is done as singletone with two access through static methods 'get' and 'set'.
97  */
99 public:
100  /// Return number of stored elements
101  static unsigned int get() {
102  return get_instance().n_elem_;
103  }
104 
105  /// Set number of stored elements
106  static void set(unsigned int n_elem) {
107  get_instance().n_elem_ = n_elem;
108  }
109 
110  CacheMapElementNumber(CacheMapElementNumber const&) = delete; ///< We don't need copy constructor.
111  void operator=(CacheMapElementNumber const&) = delete; ///< We don't need assignment operator.
112 
113 private:
114  /// Forbiden default constructor
115  CacheMapElementNumber() : n_elem_(300) {}
116 
117 
119  {
120  static CacheMapElementNumber instance;
121  return instance;
122  }
123 
124  /// Maximal number of elements stored in cache.
125  unsigned int n_elem_;
126 };
127 
128 
129 /**
130  * @brief Directing class of FieldValueCache.
131  *
132  * Manage storing and updating element data (elements of same dimension) to cache. We need only
133  * one shared instance of this class for all fields in equation (but typically for dim = 1,2,3).
134  *
135  * IMPORTANT: Because there are combuned bulk and boundary elements, we must use mesh_idx value
136  * to correct identification of elements.
137  *
138  * TODO: The logic of creating and updating this class is quite complex, describe in which order
139  * the methods are supposed to be called and which internal structures are updated when.
140  */
142 public:
143  /// Index of invalid element in cache.
144  static const unsigned int undef_elem_idx;
145 
146  /// Size of block (evaluation of FieldFormula) must be multiple of this value.
147  /// TODO We should take this value from BParser and it should be dependent on processor configuration.
148  static const unsigned int simd_size_double;
149 
150  /// Constructor
151  ElementCacheMap();
152 
153  /// Destructor
154  ~ElementCacheMap();
155 
156  /// Init cache
157  void init(std::shared_ptr<EvalPoints> eval_points);
158 
159  /// Create patch of cached elements before reading data to cache.
160  void create_patch();
161 
162  /// Reset all items of elements_eval_points_map
164  ASSERT_PTR_DBG(element_eval_points_map_);
165  unsigned int last_element_idx = -1, i_elem_row = -1;
166  for (unsigned int i=0; i<eval_point_data_.permanent_size(); ++i) {
167  if (eval_point_data_[i].i_element_ != last_element_idx) { // new element
168  i_elem_row++;
169  last_element_idx =eval_point_data_[i].i_element_;
170  }
171  set_element_eval_point(i_elem_row, eval_point_data_[i].i_eval_point_, ElementCacheMap::unused_point);
172  }
173  eval_point_data_.reset();
174  }
175 
176  /// Start update of cache.
177  void start_elements_update();
178 
179  /// Finish update after reading data to cache.
180  void finish_elements_update();
181 
182  /// Getter of eval_points object.
183  inline std::shared_ptr<EvalPoints> eval_points() const {
184  return eval_points_;
185  }
186 
187  /*
188  * Access to item of \p element_eval_points_map_ like to two-dimensional array.
189  *
190  * @param i_elem_in_cache idx of ElementAccessor in ElementCacheMap
191  * @param i_eval_point index of local point in EvalPoints
192  * @return index of point in FieldValueCache.
193  */
194  inline int element_eval_point(unsigned int i_elem_in_cache, unsigned int i_eval_point) const {
195  ASSERT_PTR_DBG(element_eval_points_map_);
196  return element_eval_points_map_[i_elem_in_cache*eval_points_->max_size()+i_eval_point];
197  }
198 
199  /// Return mesh_idx of element stored at given position of ElementCacheMap
200  inline unsigned int elm_idx_on_position(unsigned pos) const {
201  return elm_idx_[pos];
202  }
203 
204  /// Return position of element stored in ElementCacheMap
205  inline unsigned int position_in_cache(unsigned mesh_elm_idx) const {
206  std::unordered_map<unsigned int, unsigned int>::const_iterator it = element_to_map_.find(mesh_elm_idx);
207  if ( it != element_to_map_.end() ) return it->second;
209  }
210 
211  /// Return number of stored regions.
212  inline unsigned int n_regions() const {
213  return regions_starts_.permanent_size() - 1;
214  }
215 
216  /// Return number of stored elements.
217  inline unsigned int n_elements() const {
218  return element_starts_.permanent_size() - 1;
219  }
220 
221  /// Return begin position of element chunk in FieldValueCache
222  inline unsigned int element_chunk_begin(unsigned int elm_patch_idx) const {
223  ASSERT_LT_DBG(elm_patch_idx, n_elements());
224  return element_starts_[elm_patch_idx];
225  }
226 
227  /// Return end position of element chunk in FieldValueCache
228  inline unsigned int element_chunk_end(unsigned int elm_patch_idx) const {
229  ASSERT_LT_DBG(elm_patch_idx, n_elements());
230  return element_starts_[elm_patch_idx+1];
231  }
232 
233  /// Return begin position of region chunk in FieldValueCache
234  inline unsigned int region_chunk_begin(unsigned int region_patch_idx) const {
235  ASSERT_LT_DBG(region_patch_idx, n_regions());
236  return element_starts_[ regions_starts_[region_patch_idx] ];
237  }
238 
239  /// Return end position of region chunk in FieldValueCache
240  inline unsigned int region_chunk_end(unsigned int region_patch_idx) const {
241  ASSERT_LT_DBG(region_patch_idx, n_regions());
242  return element_starts_[ regions_starts_[region_patch_idx+1] ];
243  }
244 
245  /// Return begin position of region chunk specified by position in map
246  inline unsigned int region_chunk_by_map_index(unsigned int r_idx) const {
247  if (r_idx <= n_regions()) return element_starts_[ regions_starts_[r_idx] ];
249  }
250 
251  /// Return begin position of region chunk specified by position in map
252  inline unsigned int region_idx_from_chunk_position(unsigned int chunk_pos) const {
253  return eval_point_data_[ this->region_chunk_by_map_index(chunk_pos) ].i_reg_;
254  }
255 
256  /// Return item of eval_point_data_ specified by its position
257  inline const EvalPointData &eval_point_data(unsigned int point_idx) const {
258  return eval_point_data_[point_idx];
259  }
260 
261  /// Return value of evaluation point given by idx of element in patch and local point idx in EvalPoints from cache.
262  template<class Value>
263  inline typename Value::return_type get_value(const FieldValueCache<typename Value::element_type> &field_cache,
264  unsigned int elem_patch_idx, unsigned int eval_points_idx) const {
265  ASSERT_EQ_DBG(Value::NRows_, field_cache.n_rows());
266  ASSERT_EQ_DBG(Value::NCols_, field_cache.n_cols());
267  unsigned int value_cache_idx = this->element_eval_point(elem_patch_idx, eval_points_idx);
268  ASSERT_DBG(value_cache_idx != ElementCacheMap::undef_elem_idx);
269  return Value::get_from_array(field_cache, value_cache_idx);
270  }
271 protected:
272 
273  /// Special constant (@see element_eval_points_map_).
274  static const int unused_point = -1;
275 
276  /// Base number of stored regions in patch
277  static const unsigned int regions_in_chunk = 3;
278 
279  /// Base number of stored elements in patch
280  static const unsigned int elements_in_chunk = 10;
281 
282  /// Set item of \p element_eval_points_map_.
283  inline void set_element_eval_point(unsigned int i_elem_in_cache, unsigned int i_eval_point, int val) const {
284  ASSERT_PTR_DBG(element_eval_points_map_);
285  element_eval_points_map_[i_elem_in_cache*eval_points_->max_size()+i_eval_point] = val;
286  }
287 
288  /// Vector of element indexes stored in cache.
290 
291  /// Pointer to EvalPoints
292  std::shared_ptr<EvalPoints> eval_points_;
293 
294  /// Flag is set down during update of cache when this can't be read
296 
297  /**
298  * This array provides indexes to FieldValueCache.
299  *
300  * This one dimensional array behaves like two dimensional factually.
301  * Size is set to 'n_cached_elements * n_eval_points' and items are
302  * accessible through two indices:
303  *
304  * 1: Over elements holds in ElementCacheMap
305  * 2: Over EvalPoints for each element
306  *
307  * Use always and only methods \p element_eval_point for read and
308  * \p set_element_eval_point (for write) to access to items!
309  *
310  * Array is filled in those three steps:
311  * a. Reset - all items are set to ElementCacheMap::unused_point
312  * b. Used eval points are set to ElementCacheMap::point_in_proggress
313  * c. Eval points marked in previous step are sequentially numbered
314  *
315  * TODO improve description
316  */
318 
319  ///< Holds data of evaluating points in patch.
321 
322  /// @name Holds start positions and orders of region chunks and element chunks
323  // @{
324 
325  RevertableList<unsigned int> regions_starts_; ///< Start positions of elements in regions (size = n_regions+1, last value is end of last region)
326  RevertableList<unsigned int> element_starts_; ///< Start positions of elements in eval_point_data_ (size = n_elements+1)
327  std::unordered_map<unsigned int, unsigned int> element_to_map_; ///< Maps element_idx to element index in patch - TODO remove
328 
329  // @}
330 
331  template < template<IntDim...> class DimAssembly>
332  friend class GenericAssembly;
333 };
334 
335 
336 
337 #endif /* FIELD_VALUE_CACHE_HH_ */
unsigned int region_chunk_begin(unsigned int region_patch_idx) const
Return begin position of region chunk in FieldValueCache.
RevertableList< unsigned int > regions_starts_
Start positions of elements in regions (size = n_regions+1, last value is end of last region) ...
PatchCacheLoc(unsigned int i_elm, unsigned int i_ep)
Constructor sets all data members.
Declaration of class which handles the ordering of degrees of freedom (dof) and mappings between loca...
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:332
bool operator<(const EvalPointData &other)
bool ready_to_reading_
Flag is set down during update of cache when this can&#39;t be read.
Value::return_type get_value(const FieldValueCache< typename Value::element_type > &field_cache, unsigned int elem_patch_idx, unsigned int eval_points_idx) const
Return value of evaluation point given by idx of element in patch and local point idx in EvalPoints f...
void clear_element_eval_points_map()
Reset all items of elements_eval_points_map.
unsigned int i_element_
mesh_idx of ElementAccessor appropriate to element
unsigned int dh_loc_idx_
local index of cell in DOF handler
const EvalPointData & eval_point_data(unsigned int point_idx) const
Return item of eval_point_data_ specified by its position.
static const int unused_point
Special constant (.
Directing class of FieldValueCache.
std::unordered_map< unsigned int, unsigned int > element_to_map_
Maps element_idx to element index in patch - TODO remove.
Cell accessor allow iterate over DOF handler cells.
unsigned int i_elm_
index of element in patch
uint n_cols() const
Definition: armor.hh:720
unsigned int position_in_cache(unsigned mesh_elm_idx) const
Return position of element stored in ElementCacheMap.
unsigned int element_chunk_end(unsigned int elm_patch_idx) const
Return end position of element chunk in FieldValueCache.
Auxiliary data class holds number of elements in cache and allow to set this value explicitly (e...
unsigned int n_regions() const
Return number of stored regions.
unsigned int region_idx_from_chunk_position(unsigned int chunk_pos) const
Return begin position of region chunk specified by position in map.
unsigned int element_chunk_begin(unsigned int elm_patch_idx) const
Return begin position of element chunk in FieldValueCache.
int * element_eval_points_map_
Holds data of evaluating points in patch.
RevertableList< EvalPointData > eval_point_data_
EvalPointData(unsigned int i_reg, unsigned int i_ele, unsigned int i_ep, unsigned int dh_loc_idx)
Constructor sets all data members.
unsigned int i_ep_
index of eval point in patch
Holds pair of positions of point in cache (element and eval point)
void set_element_eval_point(unsigned int i_elem_in_cache, unsigned int i_eval_point, int val) const
Set item of element_eval_points_map_.
static const unsigned int undef_elem_idx
Index of invalid element in cache.
static CacheMapElementNumber & get_instance()
unsigned int i_reg_
region_idx of element
unsigned int region_chunk_end(unsigned int region_patch_idx) const
Return end position of region chunk in FieldValueCache.
uint n_rows() const
Definition: armor.hh:715
int element_eval_point(unsigned int i_elem_in_cache, unsigned int i_eval_point) const
unsigned int IntDim
A dimension index type.
Definition: mixed.hh:19
unsigned int i_eval_point_
index of point in EvalPoint object
unsigned int elm_idx_on_position(unsigned pos) const
Return mesh_idx of element stored at given position of ElementCacheMap.
std::vector< unsigned int > elm_idx_
Vector of element indexes stored in cache.
Class holds local coordinations of evaluating points (bulk and sides) specified by element dimension...
Definition: eval_points.hh:43
std::shared_ptr< EvalPoints > eval_points_
Pointer to EvalPoints.
Generic class of assemblation.
#define ASSERT_DBG(expr)
std::shared_ptr< EvalPoints > eval_points() const
Getter of eval_points object.
EvalPointData(const EvalPointData &other)
Copy constructor.
static const unsigned int simd_size_double
RevertableList< unsigned int > element_starts_
Start positions of elements in eval_point_data_ (size = n_elements+1)
unsigned int region_chunk_by_map_index(unsigned int r_idx) const
Return begin position of region chunk specified by position in map.
unsigned int n_elem_
Maximal number of elements stored in cache.
#define ASSERT_PTR_DBG(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:340
CacheMapElementNumber()
Forbiden default constructor.
Side accessor allows to iterate over sides of DOF handler cell.
unsigned int n_elements() const
Return number of stored elements.
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:300