Flow123d  JS_before_hm-1008-g3dab983
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 
30 class EvalPoints;
31 class ElementCacheMap;
32 class DHCellAccessor;
33 class DHCellSide;
34 
35 
36 /**
37  * @brief Class holds precomputed field values of selected element set.
38  *
39  * Every field in equation use own instance for every dimension of elements
40  * (typically 3 instances for dim = 1,2,3).
41  */
42 template<class elm_type>
44 public:
45  /// Constructor
46  FieldValueCache(unsigned int n_rows, unsigned int n_cols);
47 
48  /// Destructor
50 
51  /// Initialize cache
52  void init(std::shared_ptr<EvalPoints> eval_points, unsigned int n_cache_elements);
53 
54  /// Return size of data cache (number of stored field values)
55  inline unsigned int size() const {
56  return data_.size();
57 
58  }
59 
60  /// Return data vector.
61  inline const Armor::Array<elm_type> &data() const
62  {
63  return data_;
64  }
65 
67  {
68  return data_;
69  }
70 
71  /// Return data vector.
72  template<uint nr, uint nc = 1>
73  typename arma::Mat<elm_type>::template fixed<nr, nc> &get(uint i) {
74  return data_.template mat<nr, nc>(i);
75  }
76 
77  /// Return number of elements that data is stored in cache.
78  inline unsigned int n_cache_points() const {
79  return n_cache_points_;
80  }
81 
82  /// Return value of evaluation point given by DHCell and local point idx in EvalPoints.
83  template<class Value>
84  typename Value::return_type get_value(const ElementCacheMap &map,
85  const DHCellAccessor &dh_cell, unsigned int eval_points_idx);
86 
87 private:
88  /**
89  * Data cache.
90  *
91  * Data is ordered like three dimensional table. The highest level is determinated by subsets,
92  * those data ranges are holds in subset_starts. Data block size of each subset is determined
93  * by number of eval_points (of subset) and maximal number of stored elements.
94  * The table is allocated to hold all subsets, but only those marked in used_subsets are updated.
95  * Order of subsets is same as in eval_points.
96  */
98 
99  /// Maximal number of points stored in cache.
100  unsigned int n_cache_points_;
101 };
102 
103 
104 /**
105  * @brief Directing class of FieldValueCache.
106  *
107  * Manage storing and updating element data (elements of same dimension) to cache. We need only
108  * one shared instance of this class for all fields in equation (but typically for dim = 1,2,3).
109  *
110  * TODO: The logic of creating and updating this class is quite complex, describe in which order
111  * the methods are supposed to be called and which internal structures are updated when.
112  */
114 public:
115  /// Number of cached elements which values are stored in cache.
116  static constexpr unsigned int n_cached_elements = 20;
117 
118  /// Index of invalid element in cache.
119  static const unsigned int undef_elem_idx;
120 
121  /**
122  * Holds elements indices of one region stored in cache.
123  *
124  * TODO: Auxilliary structure, needs optimization:
125  * Proposal -
126  * - store element indices of all regions to one unique set (hold as data member of ElementCacheMap)
127  * - sort elements by regions in prepare_elements_to_update method
128  * - there is only problem that we have to construct ElementAccessors repeatedly
129  */
130  struct RegionData {
131  public:
132  /// Constructor
133  RegionData() : n_elements_(0) {}
134 
135  /// Add element if does not exist
137  if (std::find(elm_indices_.begin(), elm_indices_.begin()+n_elements_, elm.idx()) == elm_indices_.begin()+n_elements_) {
138  elm_indices_[n_elements_] = elm.idx();
139  n_elements_++;
140  return true;
141  } else
142  return false;
143  }
144 
145  /// Array of elements idx, ensures element uniqueness
146  std::array<unsigned int, ElementCacheMap::n_cached_elements> elm_indices_;
147  /// Number of element indices
148  unsigned int n_elements_;
149  };
150 
151  /**
152  * Holds data of regions (and their elements) stored in ElementCacheMap.
153  *
154  * TODO: Needs further optimization.
155  * Is this like a public par of the data?
156  * The name is too generic.
157  */
159  public:
160  /// Maps of data of different regions in cache
161  /// TODO: auxiliary data membershould be removed or moved to sepaate structure.
162  std::unordered_map<unsigned int, RegionData> region_cache_indices_map_;
163 
164  /// Holds positions of regions in cache
165  /// TODO
166  /// Elements of the common region forms continuous chunks in the
167  /// ElementCacheMap table. This array gives start indices of the regions
168  /// in array of all cached elements.
169  /// The last value is number of actually cached elements.
170  std::unordered_map<unsigned int, unsigned int> region_cache_indices_range_;
171 
172  /// Maps of begin and end positions of different regions data in FieldValueCache
173  std::array<unsigned int, ElementCacheMap::n_cached_elements+1> region_value_cache_range_;
174 
175  /// Maps of begin and end positions of elements of different regions in ElementCacheMap
176  std::array<unsigned int, ElementCacheMap::n_cached_elements+1> region_element_cache_range_;
177 
178  /// Number of elements in all regions holds in cache
179  // TODO: This is dulicated with the last element of region_cache_indices_range_
180  // We rather need number of regions, i.e. number of region chunks.
181  unsigned int n_elements_;
182  };
183 
184  /// Constructor
185  ElementCacheMap();
186 
187  /// Destructor
188  ~ElementCacheMap();
189 
190  /// Init cache
191  void init(std::shared_ptr<EvalPoints> eval_points);
192 
193  /// Adds element to region_cache_indices_map_ set.
194  void add(const DHCellAccessor &dh_cell);
195 
196  /// Same as previous but passes DHCellSide as parameter.
197  void add(const DHCellSide &cell_side);
198 
199  /// Prepare data member before reading data to cache.
200  void prepare_elements_to_update();
201 
202  /// Create map of used eval points on cached elements.
203  void create_elements_points_map();
204 
205  /// Start update of cache.
206  void start_elements_update();
207 
208  /// Finish update after reading data to cache.
209  void finish_elements_update();
210 
211  /// Return update cache data helper
212  inline const UpdateCacheHelper &update_cache_data() const {
213  return update_data_;
214  }
215 
216  /// Return update cache data helper
218  return update_data_;
219  }
220 
221  /// Getter of eval_points object.
222  inline std::shared_ptr<EvalPoints> eval_points() const {
223  return eval_points_;
224  }
225 
226  /**
227  * Set used element eval points to value ElementCacheMap::point_in_proggress
228  *
229  * @param dh_cell Specified element
230  * @param subset_idx Index of subset
231  * @param data_size Number of points
232  * @param start_point Index of first used point in subset (e.g. subset holds eval points of all sides but EdgeIntegral represents only one of them)
233  */
234  void mark_used_eval_points(const DHCellAccessor &dh_cell, unsigned int subset_idx, unsigned int data_size, unsigned int start_point=0);
235 
236  /// Return index of point in FieldValueCache
237  inline int get_field_value_cache_index(unsigned int elm_idx, unsigned int loc_point_idx) const {
238  ASSERT_PTR_DBG(element_eval_points_map_);
239  return element_eval_points_map_[elm_idx][loc_point_idx];
240  }
241 
242  /// Return idx of element stored at given position of ElementCacheMap
243  inline unsigned int elm_idx_on_position(unsigned pos) const {
244  return elm_idx_[pos];
245  }
246 
247  /// Set index of cell in ElementCacheMap (or undef value if cell is not stored in cache).
248  DHCellAccessor & operator() (DHCellAccessor &dh_cell) const;
249 protected:
250 
251  /// Special constant (@see element_eval_points_map_).
252  static const int unused_point = -2;
253 
254  /// Special constant (@see element_eval_points_map_).
255  static const int point_in_proggress = -1;
256 
257  /// Reset all items of elements_eval_points_map
258  void clear_element_eval_points_map();
259 
260  /// Add element to appropriate region data of update_data_ object
261  void add_to_region(ElementAccessor<3> elm);
262 
263  /// Vector of element indexes stored in cache.
264  /// TODO: could be moved to UpdateCacheHelper structure
266 
267  /// Map of element indices stored in cache, allows reverse search to previous vector.
268  /// TODO: could be moved to UpdateCacheHelper structure
269  std::unordered_map<unsigned int, unsigned int> cache_idx_;
270 
271  /// Pointer to EvalPoints
272  std::shared_ptr<EvalPoints> eval_points_;
273 
274  /// Holds data used for cache update.
276 
277  /// Flag is set down during update of cache when this can't be read
279 
280  /**
281  * Two dimensional array provides indexes to FieldValueCache.
282  *
283  * 1: Over elements holds in ElementCacheMap
284  * 2: Over EvalPoints for each element
285  *
286  * Array is filled in those three steps:
287  * a. Reset - all items are set to ElementCacheMap::unused_point
288  * b. Used eval points are set to ElementCacheMap::point_in_proggress
289  * c. Eval points marked in previous step are sequentially numbered
290  */
291  // TODO: What are the dimensions of the table?
292  // should be n_cached_elements * n_eval_points, document it.
293  //
294  // Better use just int *, and use just single allocation of the whole table
295  // current impl. have bad memory locality. Define a private access method.
297 
298 
299  /// Number of points stored in cache
300  unsigned int points_in_cache_;
301 };
302 
303 
304 
305 #endif /* FIELD_VALUE_CACHE_HH_ */
UpdateCacheHelper update_data_
Holds data used for cache update.
unsigned int n_elements_
Number of element indices.
unsigned int size() const
Definition: armor.hh:718
bool ready_to_reading_
Flag is set down during update of cache when this can&#39;t be read.
unsigned int uint
Value::return_type get_value(const ElementCacheMap &map, const DHCellAccessor &dh_cell, unsigned int eval_points_idx)
Return value of evaluation point given by DHCell and local point idx in EvalPoints.
const UpdateCacheHelper & update_cache_data() const
Return update cache data helper.
FieldValueCache(unsigned int n_rows, unsigned int n_cols)
Constructor.
Directing class of FieldValueCache.
Cell accessor allow iterate over DOF handler cells.
bool add(ElementAccessor< 3 > elm)
Add element if does not exist.
Armor::Array< elm_type > & data()
Class holds precomputed field values of selected element set.
std::array< unsigned int, ElementCacheMap::n_cached_elements+1 > region_value_cache_range_
Maps of begin and end positions of different regions data in FieldValueCache.
unsigned int size() const
Return size of data cache (number of stored field values)
unsigned int n_elements_
Number of elements in all regions holds in cache.
const Armor::Array< elm_type > & data() const
Return data vector.
static const unsigned int undef_elem_idx
Index of invalid element in cache.
std::unordered_map< unsigned int, unsigned int > region_cache_indices_range_
Armor::Array< elm_type > data_
std::unordered_map< unsigned int, unsigned int > cache_idx_
unsigned int elm_idx_on_position(unsigned pos) const
Return idx of element stored at given position of ElementCacheMap.
int get_field_value_cache_index(unsigned int elm_idx, unsigned int loc_point_idx) const
Return index of point in FieldValueCache.
~FieldValueCache()
Destructor.
unsigned int n_cache_points_
Maximal number of points stored in cache.
std::array< unsigned int, ElementCacheMap::n_cached_elements+1 > region_element_cache_range_
Maps of begin and end positions of elements of different regions in ElementCacheMap.
std::vector< unsigned int > elm_idx_
Class holds local coordinations of evaluating points (bulk and sides) specified by element dimension...
Definition: eval_points.hh:43
unsigned int points_in_cache_
Number of points stored in cache.
unsigned int n_cache_points() const
Return number of elements that data is stored in cache.
std::shared_ptr< EvalPoints > eval_points_
Pointer to EvalPoints.
std::shared_ptr< EvalPoints > eval_points() const
Getter of eval_points object.
UpdateCacheHelper & update_cache_data()
Return update cache data helper.
std::array< unsigned int, ElementCacheMap::n_cached_elements > elm_indices_
Array of elements idx, ensures element uniqueness.
#define ASSERT_PTR_DBG(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:340
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:181
std::unordered_map< unsigned int, RegionData > region_cache_indices_map_
void init(std::shared_ptr< EvalPoints > eval_points, unsigned int n_cache_elements)
Initialize cache.
Side accessor allows to iterate over sides of DOF handler cell.