Flow123d  JS_before_hm-887-g601087d
field_value_cache.cc
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.cc
15  * @brief
16  * @author David Flanderka
17  */
18 
19 #include <limits>
21 #include "fields/field_values.hh"
22 #include "fields/eval_points.hh"
23 #include "fields/eval_subset.hh"
24 #include "fem/dh_cell_accessor.hh"
25 #include "mesh/accessors.hh"
26 
27 
28 /******************************************************************************
29  * Implementation of FieldValueCache methods
30  */
31 
32 template<class elm_type>
33 FieldValueCache<elm_type>::FieldValueCache(unsigned int n_rows, unsigned int n_cols)
34 : data_(n_rows, n_cols) {}
35 
36 template<class elm_type>
38 
39 template<class elm_type>
40 void FieldValueCache<elm_type>::init(std::shared_ptr<EvalPoints> eval_points, unsigned int n_cache_elements) {
41  ASSERT_EQ(data_.size(), 0).error("Repeated initialization!\n");
42 
43  this->n_cache_points_ = n_cache_elements * eval_points->max_size();
46 }
47 
48 
49 /******************************************************************************
50  * Implementation of ElementCacheMap methods
51  */
52 
53 const unsigned int ElementCacheMap::undef_elem_idx = std::numeric_limits<unsigned int>::max();
54 
55 
57 : elm_idx_(ElementCacheMap::n_cached_elements, ElementCacheMap::undef_elem_idx),
58  ready_to_reading_(false), element_eval_points_map_(nullptr), points_in_cache_(0) {
61 }
62 
63 
65  if (element_eval_points_map_!=nullptr) {
66  for (unsigned int i=0; i<ElementCacheMap::n_cached_elements; ++i)
67  delete element_eval_points_map_[i];
69  }
70 }
71 
72 
73 void ElementCacheMap::init(std::shared_ptr<EvalPoints> eval_points) {
74  this->eval_points_ = eval_points;
75 
76  unsigned int size = this->eval_points_->max_size();
78  for (unsigned int i=0; i<ElementCacheMap::n_cached_elements; ++i)
79  element_eval_points_map_[i] = new int [size];
80 }
81 
82 
83 void ElementCacheMap::add(const DHCellAccessor &dh_cell) {
85  ASSERT_LT(update_data_.n_elements_, ElementCacheMap::n_cached_elements).error("ElementCacheMap overflowed. List of added elements is too long!\n");
86  this->add_to_region(dh_cell.elm());
87 }
88 
89 
90 void ElementCacheMap::add(const DHCellSide &cell_side) {
92  ASSERT_LT(update_data_.n_elements_, ElementCacheMap::n_cached_elements).error("ElementCacheMap overflowed. List of added elements is too long!\n");
93  this->add_to_region(cell_side.cell().elm());
94 }
95 
96 
98  // Erase element data of previous step
99  cache_idx_.clear();
100  std::fill(elm_idx_.begin(), elm_idx_.end(), ElementCacheMap::undef_elem_idx);
102 
103  // Set new elements to elm_idx_, cache_idx_ sorted by region
104  unsigned int n_stored_element = 0, n_region = 0;
106  for (auto region_it = update_data_.region_cache_indices_map_.begin(); region_it != update_data_.region_cache_indices_map_.end(); region_it++) {
107  update_data_.region_cache_indices_range_[region_it->first] = n_region;
108  for (unsigned int i_elm=0; i_elm<region_it->second.n_elements_; ++i_elm) {
109  unsigned int elm_idx = region_it->second.elm_indices_[i_elm];
110  cache_idx_[elm_idx] = n_stored_element;
111  elm_idx_[n_stored_element] = elm_idx;
112  n_stored_element++;
113  }
114  update_data_.region_element_cache_range_[n_region+1] = n_stored_element;
115  n_region++;
116  }
117 }
118 
119 
121  unsigned int size = this->eval_points_->max_size();
122  unsigned int idx_to_region = 1;
123  unsigned int region_last_elm = update_data_.region_element_cache_range_[idx_to_region];
124  points_in_cache_ = 0;
126  for (unsigned int i_elm=0; i_elm<ElementCacheMap::n_cached_elements; ++i_elm) {
127  for (unsigned int i_point=0; i_point<size; ++i_point) {
129  element_eval_points_map_[i_elm][i_point] = points_in_cache_;
131  }
132  }
133  if (region_last_elm==i_elm+1) {
135  idx_to_region++;
136  region_last_elm = update_data_.region_element_cache_range_[idx_to_region];
137  }
138  }
139 }
140 
141 
144  ready_to_reading_ = false;
145 }
146 
150  ready_to_reading_ = true;
151 }
152 
153 void ElementCacheMap::mark_used_eval_points(const DHCellAccessor &dh_cell, unsigned int subset_idx, unsigned int data_size, unsigned int start_point) {
154  unsigned int elem_idx_in_cache = cache_idx_[dh_cell.elm_idx()];
155  unsigned int points_begin = eval_points_->subset_begin(dh_cell.dim(), subset_idx) + start_point;
156  for (unsigned int i=points_begin; i<points_begin+data_size; ++i)
158 }
159 
160 
163  unsigned int size = this->eval_points_->max_size();
164  for (unsigned int i_elm=0; i_elm<ElementCacheMap::n_cached_elements; ++i_elm)
165  for (unsigned int i_point=0; i_point<size; ++i_point)
167 }
168 
169 
171  // TODO: see unordered_map::insert(map::begin(), pair) variant
172  // this can be used and avoid dupicit find and the condition.
173 
174  unsigned int reg_idx = elm.region_idx().idx();
175  typename std::unordered_map<unsigned int, RegionData>::iterator region_it = update_data_.region_cache_indices_map_.find(reg_idx);
176  if (region_it == update_data_.region_cache_indices_map_.end()) {
177  update_data_.region_cache_indices_map_.insert( {reg_idx, RegionData()} );
178  region_it = update_data_.region_cache_indices_map_.find(reg_idx);
179  }
180 
181  // TODO: What is the reason for this condition, the elm should not be duplicate.
182  if ( region_it->second.add(elm) ) update_data_.n_elements_++;
183 }
184 
185 
188  unsigned int elm_idx = dh_cell.elm_idx();
189  std::unordered_map<unsigned int, unsigned int>::const_iterator it = cache_idx_.find(elm_idx);
190  if ( it != cache_idx_.end() ) dh_cell.set_element_cache_index( it->second );
192  return dh_cell;
193 }
194 
195 
196 /******************************************************************************
197  * Explicit instantiation of templates
198  */
199 
200 template class FieldValueCache<unsigned int>;
201 template class FieldValueCache<int>;
202 template class FieldValueCache<double>;
UpdateCacheHelper update_data_
Holds data used for cache update.
void mark_used_eval_points(const DHCellAccessor &dh_cell, unsigned int subset_idx, unsigned int data_size, unsigned int start_point=0)
void resize(uint size)
Definition: armor.hh:700
void init(std::shared_ptr< EvalPoints > eval_points)
Init cache.
unsigned int size() const
Definition: armor.hh:718
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
bool ready_to_reading_
Flag is set down during update of cache when this can&#39;t be read.
ElementCacheMap()
Constructor.
void clear_element_eval_points_map()
Reset all items of elements_eval_points_map.
static const int unused_point
Special constant (.
FieldValueCache(unsigned int n_rows, unsigned int n_cols)
Constructor.
unsigned int dim() const
Return dimension of element appropriate to cell.
Directing class of FieldValueCache.
Cell accessor allow iterate over DOF handler cells.
Class holds precomputed field values of selected element set.
void add_to_region(ElementAccessor< 3 > elm)
Add element to appropriate region data of update_data_ object.
void prepare_elements_to_update()
Prepare data member before reading data to cache.
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.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
unsigned int n_elements_
Number of elements in all regions holds in cache.
static const unsigned int undef_elem_idx
Index of invalid element in cache.
void create_elements_points_map()
Create map of used eval points on cached elements.
std::unordered_map< unsigned int, unsigned int > region_cache_indices_range_
void reinit(uint size)
Definition: armor.hh:688
Armor::Array< elm_type > data_
std::unordered_map< unsigned int, unsigned int > cache_idx_
~ElementCacheMap()
Destructor.
void set_element_cache_index(unsigned int idx) const
Setter of elm_cache_index_.
void add(const DHCellAccessor &dh_cell)
Adds element to region_cache_indices_map_ set.
~FieldValueCache()
Destructor.
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
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.
static constexpr unsigned int n_cached_elements
Number of cached elements which values are stored in cache.
std::vector< unsigned int > elm_idx_
DHCellAccessor & operator()(DHCellAccessor &dh_cell) const
Set index of cell in ElementCacheMap (or undef value if cell is not stored in cache).
unsigned int points_in_cache_
Number of points stored in cache.
void start_elements_update()
Start update of cache.
void finish_elements_update()
Finish update after reading data to cache.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:296
std::shared_ptr< EvalPoints > eval_points_
Pointer to EvalPoints.
RegionIdx region_idx() const
Definition: accessors.hh:168
#define ASSERT_DBG(expr)
std::shared_ptr< EvalPoints > eval_points() const
Getter of eval_points object.
#define ASSERT_PTR_DBG(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:340
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.
static const int point_in_proggress
Special constant (.
Side accessor allows to iterate over sides of DOF handler cell.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:328
unsigned int idx() const
Returns a global index of the region.
Definition: region.hh:82