Flow123d  release_2.2.0-914-gf1a3a4f
element_data_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 element_data_cache.cc
15  * @brief
16  */
17 
18 
19 #include "io/element_data_cache.hh"
20 #include "io/msh_basereader.hh"
22 #include "boost/lexical_cast.hpp"
23 
24 
25 
26 template <typename T>
29 
30 
31 template <typename T>
32 ElementDataCache<T>::ElementDataCache(std::string field_name, double time, unsigned int size_of_cache, unsigned int row_vec_size) {
33  this->time_ = time;
34  this->field_input_name_ = field_name;
35  this->data_ = create_data_cache(size_of_cache, row_vec_size);
36 }
37 
38 
39 template <typename T>
40 ElementDataCache<T>::ElementDataCache(std::string field_name, unsigned int n_rows, unsigned int n_cols, unsigned int size)
41 {
42  this->set_vtk_type<T>();
43  this->field_name_ = field_name;
44  this->field_input_name_ = this->field_name_;
45 
46  this->n_values_ = size;
47 
48  if (n_cols == 1) {
49  if (n_rows == 1) {
50  this->n_elem_ = N_SCALAR;
51  } else {
52  if (n_rows > 1) {
53  if (n_rows > 3) {
55  "Do not support output of vectors with fixed size >3. Field: %s\n",
56  this->field_input_name_.c_str());
57  } else {
58  this->n_elem_ = N_VECTOR;
59  }
60  } else {
61  THROW(ExcOutputVariableVector() << EI_FieldName(this->field_input_name_));
62  }
63  }
64  } else {
65  this->n_elem_ = N_TENSOR;
66  }
67 
69 }
70 
71 
72 template <typename T>
74 
75 
76 template <typename T>
78  ASSERT_LT(component_idx, data_.size()).error("Index of component is out of range.\n");
79  return data_[component_idx];
80 }
81 
82 
83 template <typename T>
84 typename ElementDataCache<T>::CacheData ElementDataCache<T>::create_data_cache(unsigned int size_of_cache, unsigned int row_vec_size) {
85  typename ElementDataCache<T>::CacheData data_cache(size_of_cache);
86  for (unsigned int i=0; i<size_of_cache; ++i) {
87  typename ElementDataCache<T>::ComponentDataPtr row_vec = std::make_shared<std::vector<T>>();
88  row_vec->resize(row_vec_size);
89  data_cache[i] = row_vec;
90  }
91 
92  return data_cache;
93 }
94 
95 
96 template <typename T>
97 void ElementDataCache<T>::read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) {
98  unsigned int idx;
99  for (unsigned int i_vec=0; i_vec<data_.size(); ++i_vec) {
100  idx = i_row * n_components;
101  std::vector<T> &vec = *( data_[i_vec].get() );
102  for (unsigned int i_col=0; i_col < n_components; ++i_col, ++idx) {
103  vec[idx] = boost::lexical_cast<T>(*tok);
104  ++tok;
105  }
106  }
107 }
108 
109 
110 template <typename T>
111 void ElementDataCache<T>::read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) {
112  unsigned int idx;
113  for (unsigned int i_vec=0; i_vec<data_.size(); ++i_vec) {
114  idx = i_row * n_components;
115  std::vector<T> &vec = *( data_[i_vec].get() );
116  for (unsigned int i_col=0; i_col < n_components; ++i_col, ++idx) {
117  data_stream.read(reinterpret_cast<char *>(&vec[idx]), sizeof(T));
118  }
119  }
120 }
121 
122 
123 /**
124  * Output data element on given index @p idx. Method for writing data
125  * to output stream.
126  *
127  * \note This method is used only by MSH file format.
128  */
129 template <typename T>
130 void ElementDataCache<T>::print_ascii(ostream &out_stream, unsigned int idx)
131 {
132  ASSERT_LT(idx, this->n_values_).error();
133  std::vector<T> &vec = *( this->data_[0].get() );
134  for(unsigned int i = n_elem_*idx; i < n_elem_*(idx+1); ++i )
135  out_stream << vec[i] << " ";
136 }
137 
138 /**
139  * \brief Print all data stored in output data
140  *
141  * TODO: indicate if the tensor data are output in column-first or raw-first order
142  * and possibly implement transposition. Set such property for individual file formats.
143  * Class OutputData stores always in raw-first order.
144  */
145 template <typename T>
146 void ElementDataCache<T>::print_ascii_all(ostream &out_stream)
147 {
148  std::vector<T> &vec = *( this->data_[0].get() );
149  for(unsigned int idx = 0; idx < this->n_values_; idx++) {
150  for(unsigned int i = n_elem_*idx; i < n_elem_*(idx+1); ++i )
151  out_stream << vec[i] << " ";
152  }
153 }
154 
155 
156 /// Prints the whole data vector into stream.
157 template <typename T>
158 void ElementDataCache<T>::print_binary_all(ostream &out_stream, bool print_data_size)
159 {
160  if (print_data_size) {
161  // write size of data
162  unsigned long long int data_byte_size = this->n_values_ * n_elem_ * sizeof(T);
163  out_stream.write(reinterpret_cast<const char*>(&data_byte_size), sizeof(unsigned long long int));
164  }
165  // write data
166  std::vector<T> &vec = *( this->data_[0].get() );
167  for(unsigned int idx = 0; idx < this->n_values_; idx++) {
168  for(unsigned int i = n_elem_*idx; i < n_elem_*(idx+1); ++i )
169  out_stream.write(reinterpret_cast<const char*>(&(vec[i])), sizeof(T));
170  }
171 }
172 
173 
174 template <typename T>
175 void ElementDataCache<T>::print_all_yaml(ostream &out_stream, unsigned int precision)
176 {
177  out_stream << "[ ";
178  std::vector<T> &vec = *( this->data_[0].get() );
179  for(unsigned int idx = 0; idx < this->n_values_; idx++) {
180  if (idx != 0) out_stream << " , ";
181  unsigned int vec_pos = n_elem_ * idx; // position of element value in data cache
182  switch (this->n_elem_) {
183  case NumCompValueType::N_SCALAR: {
184  out_stream << field_value_to_yaml( vec[vec_pos], precision );
185  break;
186  }
187  case NumCompValueType::N_VECTOR: {
188  typename arma::Col<T>::template fixed<3> vec_val;
189  for (unsigned int i=0; i<3; ++i, ++vec_pos)
190  vec_val(i) = vec[vec_pos];
191  out_stream << field_value_to_yaml( vec_val, precision );
192  break;
193  }
194  case NumCompValueType::N_TENSOR: {
195  typename arma::Mat<T>::template fixed<3,3> mat_val;
196  for (unsigned int i=0; i<3; ++i)
197  for (unsigned int j=0; j<3; ++j, ++vec_pos)
198  mat_val(i,j) = vec[vec_pos];
199  out_stream << field_value_to_yaml( mat_val, precision );
200  break;
201  }
202  }
203  }
204  out_stream << " ]";
205 }
206 
207 
208 template <typename T>
209 void ElementDataCache<T>::get_min_max_range(double &min, double &max)
210 {
211  min = std::numeric_limits<double>::max();
212  max = std::numeric_limits<double>::min();
213  std::vector<T> &vec = *( this->data_[0].get() );
214  for(unsigned int idx = 0; idx < this->n_values_; idx++) {
215  for(unsigned int i = n_elem_*idx; i < n_elem_*(idx+1); ++i ) {
216  if (vec[i] < min) min = vec[i];
217  if (vec[i] > max) max = vec[i];
218  }
219  }
220 }
221 
222 
223 /**
224  * Store data element of given data value under given index.
225  */
226 template <typename T>
227 void ElementDataCache<T>::store_value(unsigned int idx, const T * value) {
228  ASSERT_LT_DBG(idx, this->n_values_);
229  std::vector<T> &vec = *( this->data_[0].get() );
230  unsigned int vec_idx = idx*this->n_elem_;
231  for(unsigned int i = 0; i < this->n_elem_; i++, vec_idx++) {
232  vec[vec_idx] = value[i];
233  }
234 };
235 
236 /**
237  * Add value to given index
238  */
239 template <typename T>
240 void ElementDataCache<T>::add(unsigned int idx, const T * value) {
241  ASSERT_LT_DBG(idx, this->n_values_);
242  std::vector<T> &vec = *( this->data_[0].get() );
243  unsigned int vec_idx = idx*this->n_elem_;
244  for(unsigned int i = 0; i < this->n_elem_; i++, vec_idx++) {
245  vec[vec_idx] += value[i];
246  }
247 };
248 
249 /**
250  * Reset values at given index
251  */
252 template <typename T>
253 void ElementDataCache<T>::zero(unsigned int idx) {
254  ASSERT_LT_DBG(idx, this->n_values_);
255  std::vector<T> &vec = *( this->data_[0].get() );
256  unsigned int vec_idx = idx*this->n_elem_;
257  for(unsigned int i = 0; i < this->n_elem_; i++, vec_idx++) {
258  vec[vec_idx] = 0;
259  }
260 };
261 
262 /**
263  * Normalize values at given index
264  */
265 template <typename T>
266 void ElementDataCache<T>::normalize(unsigned int idx, unsigned int divisor) {
267  ASSERT_LT_DBG(idx, this->n_values_);
268  std::vector<T> &vec = *( this->data_[0].get() );
269  unsigned int vec_idx = idx*this->n_elem_;
270  for(unsigned int i = 0; i < this->n_elem_; i++, vec_idx++) {
271  vec[vec_idx] /= divisor;
272  }
273 };
274 
275 /// Access i-th element in the data vector.
276 template <class T>
278 {
279  std::vector<T> &vec = *( this->data_[0].get() );
280  ASSERT_DBG(i < vec.size());
281  return vec[i];
282 }
283 
284 
285 
286 // explicit instantiation of template class
287 template class ElementDataCache<unsigned int>;
288 template class ElementDataCache<int>;
289 template class ElementDataCache<double>;
double time_
time step stored in cache
void read_binary_data(std::istream &data_stream, unsigned int n_components, unsigned int i_row) override
Implements ElementDataCacheBase::read_binary_data.
std::shared_ptr< std::vector< T > > ComponentDataPtr
void print_ascii(ostream &out_stream, unsigned int idx) override
string field_value_to_yaml(const T &mat, unsigned int prec)
void store_value(unsigned int idx, const T *value)
T & operator[](unsigned int i)
Access i-th element in the data vector of 0th component.
void read_ascii_data(Tokenizer &tok, unsigned int n_components, unsigned int i_row) override
Implements ElementDataCacheBase::read_ascii_data.
static constexpr bool value
Definition: json.hpp:87
ElementDataCache()
Default constructor.
void get_min_max_range(double &min, double &max) override
void add(unsigned int idx, const T *value)
virtual ~ElementDataCache() override
Destructor of ElementDataCache.
static CacheData create_data_cache(unsigned int size_of_cache, unsigned int row_vec_size)
void zero(unsigned int idx)
#define xprintf(...)
Definition: system.hh:92
void print_all_yaml(ostream &out_stream, unsigned int precision) override
void normalize(unsigned int idx, unsigned int divisor)
void print_binary_all(ostream &out_stream, bool print_data_size=true) override
Print all data stored in output data to appended binary format.
std::string field_input_name_
name of field stored in cache
Definition: system.hh:64
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:295
ComponentDataPtr get_component_data(unsigned int component_idx)
Return vector of element data for get component.
#define ASSERT_DBG(expr)
Definition: asserts.hh:349
void print_ascii_all(ostream &out_stream) override
Print all data stored in output data ro ascii format.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:299