Flow123d  master-e663071
observe.hh
Go to the documentation of this file.
1  /*
2  * observe.hh
3  *
4  * Created on: Jun 28, 2016
5  * Author: jb
6  */
7 
8 #ifndef SRC_IO_OBSERVE_HH_
9 #define SRC_IO_OBSERVE_HH_
10 
11 
12 #include <iosfwd> // for ofstream, ostream
13 #include <map> // for map, map<>::value_compare
14 #include <memory> // for shared_ptr
15 #include <new> // for operator new[]
16 #include <string> // for string, operator<<
17 #include <vector> // for vector
18 #include <armadillo>
19 #include "input/accessors.hh" // for Array (ptr only), Record
20 #include "input/input_exception.hh" // for DECLARE_INPUT_EXCEPTION
21 #include "system/exceptions.hh" // for operator<<, ExcStream, EI
22 #include "system/armadillo_tools.hh" // for Armadillo vec string
23 #include "system/index_types.hh" // for LongIdx
24 #include "mesh/range_wrapper.hh"
26 #include "la/distribution.hh"
27 
29 class Mesh;
30 class TimeUnitConversion;
31 namespace Input { namespace Type { class Record; } }
32 template <typename T> class ElementDataCache;
33 
34 
35 
36 /// Holds data of one eval point on patch (index of element and local coordinations).
38  /// Default constructor
40 
41  /// Constructor with data mebers initialization
42  PatchPointData(unsigned int elm_idx, arma::vec loc_coords)
43  : elem_idx(elm_idx), local_coords(loc_coords), i_quad(0), i_quad_point(0) {}
44 
45  /// Copy constructor
47  : elem_idx(other.elem_idx), local_coords(other.local_coords),
48  i_quad(other.i_quad), i_quad_point(other.i_quad_point) {}
49 
50  unsigned int elem_idx; ///< Index of element
51  arma::vec local_coords; ///< Local coords of point
52  unsigned int i_reg; ///< Index of region (use during patch creating)
53  unsigned int i_quad; ///< Index of quadrature (use during patch creating), i_quad = dim-1
54  unsigned int i_quad_point; ///< Index of point in quadrature (use during patch creating)
55 };
57 
58 
59 
60 /**
61  * Helper class stores base data of ObservePoint and allows to evaluate
62  * the nearest point to input_point_.
63  */
65 public:
66  /// Constructor
68  : distance_(numeric_limits<double>::infinity()) {};
69 
70  /// Final element of the observe point. The index in the mesh.
71  unsigned int element_idx_;
72 
73  /// Global coordinates of the observation point.
75 
76  /// Local (barycentric) coordinates on the element.
78 
79  /// Distance of found projection from the initial point.
80  /// If we find more candidates we pass in the closest one.
81  double distance_;
82 
83  /// Actual process of the observe point.
84  unsigned int proc_;
85 
86  /// Global index of the observe point.
88 
89  /// Local index on actual process of the observe point.
91 };
92 
93 
94 /**
95  * Class representing single observe point, used internally by the class Observe.
96  * Members: input_pos_, snap_dim_, snap_region_name_ are set in constructor. Should be checked before passed in.
97  * Members: element_idx_, global_coords_, local_coords_ are derived, set in Observe::find_observe_points.
98  */
99 class ObservePoint {
100 public:
101  DECLARE_INPUT_EXCEPTION(ExcNoInitialPoint,
102  << "Failed to find the element containing the initial observe point.\n");
103  TYPEDEF_ERR_INFO(EI_RegionName, std::string);
104  TYPEDEF_ERR_INFO(EI_PointName, std::string);
105  TYPEDEF_ERR_INFO(EI_Point, arma::vec3);
106  TYPEDEF_ERR_INFO(EI_ClosestEle, ObservePointData);
107  DECLARE_INPUT_EXCEPTION(ExcNoObserveElementCandidates,
108  << "Failed to find any element in the search radius of the observe point " << EI_PointName::qval
109  << " with given coordinates " << field_value_to_yaml(EI_Point::ref(*this)) << ".\n"
110  << "The closest element has index " << EI_ClosestEle::ref(*this).element_idx_ << ", its distance is " << EI_ClosestEle::ref(*this).distance_ << ".\n"
111  << "Solution: check the position of the observe point, possibly increase the maximal snapping distance "
112  << "(keys: observe_points:search_radius, mesh:global_snap_radius)"<< "\n");
113  DECLARE_INPUT_EXCEPTION(ExcNoObserveElement,
114  << "Failed to find any element in the search radius of the observe point" << EI_PointName::qval
115  << " inside the snap region: " << EI_RegionName::qval << ".\n"
116  << "The observe point coordinates are " << field_value_to_yaml(EI_Point::ref(*this)) << ".\n"
117  << "The closest element (outside the snap region) has index " << EI_ClosestEle::ref(*this).element_idx_
118  << ", its distance is " << EI_ClosestEle::ref(*this).distance_ << ".\n"
119  << "Solution: check the position/region of the observe point, possibly increase the maximal snapping distance "
120  << "(keys: observe_points:search_radius, mesh:global_snap_radius)"<< "\n");
121 
122  static const Input::Type::Record & get_input_type();
123 
124  /**
125  * Return index of observation point in the mesh.
126  */
127  inline unsigned int element_idx() const
128  { return observe_data_.element_idx_; }
129 
130  /**
131  * Return Local coordinates of the observation point.
132  */
133  inline arma::vec local_coords() const
134  { return observe_data_.local_coords_; }
135 
136  /**
137  * Return global coordinates of the observation point.
138  */
139  inline arma::vec3 global_coords() const
140  { return observe_data_.global_coords_; }
141 
142 protected:
143  /**
144  * Default constructor just for testing.
145  */
146  ObservePoint();
147 
148  /**
149  * Constructor. Read from input.
150  */
151  ObservePoint(Input::Record in_rec, Mesh &mesh, unsigned int point_idx);
152 
153  /**
154  * Returns true if we have already found any observe element.
155  */
156  bool have_observe_element();
157 
158  /**
159  * Snap to the center of closest subelement with dimension snap_dim_.
160  * This makes final adjustment of global_coords_ and local_coords_.
161  */
162  void snap(Mesh &mesh);
163 
164 
165  /**
166  * Find the observe element and the definitive observe point.
167  *
168  * Algorithm:
169  * 1. find element containing the point (initial element)
170  * 2. check initial element for region match possibly set it as (observe element)
171  * 3. add neighbours into processing_list for the next level
172  * 4. while we have no observe element: pass through the processing list of the current level
173  * 5. if element match the region, project and clip the init point, update observe element.
174  * 6. snapping on the observe element
175  *
176  */
177  void find_observe_point(Mesh &mesh);
178 
179  /**
180  * Output the observe point information into a YAML formated stream, indent by
181  * given number of spaces + "- ".
182  */
183  void output(ostream &out, unsigned int indent_spaces, unsigned int precision);
184 
185  /// Project point to given element by dimension of this element.
186  ObservePointData point_projection(unsigned int i_elm, ElementAccessor<3> elm);
187 
188  /// Index in the input array.
190 
191  /// Observation point name.
192  std::string name_;
193 
194  /**
195  * Snap to the center of the object of given dimension.
196  * Value 4 and greater means no snapping.
197  */
198  unsigned int snap_dim_;
199 
200  /**
201  * Region of the snapping element.
202  */
204 
205  /**
206  * Maximal distance of observe element from input point.
207  */
209 
210  /// Input coordinates of the initial position of the observation point.
212 
213  /// Helper object stored projection data
215 
216  /// Only Observe should use this class directly.
217  friend class Observe;
218 
219 };
220 
221 
223 
224 /**
225  * This class takes care about the observe points in the output stream, storing observe values of the fields and
226  * their output in the YAML format.
227  */
228 class Observe {
229 public:
230 
231  typedef std::shared_ptr<ElementDataCacheBase> OutputDataPtr;
233 
234  /**
235  * Construct the observation object.
236  *
237  * observe_name - base name of the output file, the equation name.
238  * mesh - the mesh used for search for the observe points
239  * in_array - the array of observe points
240  */
241  Observe(string observe_name, Mesh &mesh, Input::Array in_array,
242  unsigned int precision, const std::shared_ptr<TimeUnitConversion>& time_unit_conv);
243 
244  /// Destructor, must close the file.
245  ~Observe();
246 
247 
248  /**
249  * Provides a vector of element indices on which the observation values are evaluated.
250  * This can be used to evaluate derived fields only on these elements in the times not selected to
251  * full output.
252  */
254  { return observed_element_indices_;}
255 
256  /**
257  * Output file header.
258  */
259  void output_header();
260 
261  /**
262  * Sets next output time frame of observe. If the table is full, writes field values to the output
263  * file. Using the YAML format. Argument flush starts writing to output file explicitly.
264  */
265  void output_time_frame(bool flush);
266 
267  /**
268  * Return \p points_ vector
269  */
270  inline const std::vector<ObservePoint> & points() const
271  { return points_; }
272 
273  /**
274  * Return point distribution
275  */
276  inline const Distribution * point_ds() const
277  { return point_ds_; }
278 
279  /// Returns local range of observe points
281 
282  /**
283  * Prepare data for computing observe values.
284  *
285  * Method:
286  * - check that all fields of one time frame are evaluated at the same time
287  * - find and return ElementDataCache of given field_name, create its if doesn't exist.
288  *
289  * @param field_name Quantity name of founding ElementDataCache
290  * @param field_time Actual computing time
291  * @param n_shape Count of rows * cols of data cache (used only if new cache is created)
292  */
293  OutputDataPtr prepare_compute_data(std::string field_name, double field_time, unsigned int n_shape);
294 
295  /**
296  * Return pointer to ElementDataCache of given field.
297  *
298  * @param field_name Quantity name of founding ElementDataCache
299  */
300  inline OutputDataPtr get_output_cache(std::string field_name) {
301  OutputDataFieldMap::iterator it=observe_field_values_.find(field_name);
302  ASSERT(it != observe_field_values_.end())(field_name).error("Element data cache of given field doesn't exist. Did you call prepare_compute_data?\n");
303  return it->second;
304  }
305 
306  /// Getter of patch_point_data.
308  return patch_point_data_;
309  }
310 
311 
312 
313 protected:
314  /// Effectively writes the data into the observe stream.
315  void flush_values();
316 
317  /// Maximal size of observe values times vector
318  static const unsigned int max_observe_value_time;
319 
320  // MPI rank.
321  int rank_;
322 
323  /// Full information about observe points.
325  /// Elements of the o_points.
327 
328  /// Stored field values.
330 
331 
332  /// Common evaluation time of the fields for single time frame.
334 
335  // Name of the observation stream. Base for the output filename.
336  std::string observe_name_;
337 
338  /// Output file stream.
339  std::ofstream observe_file_;
340 
341  /// Precision of float output
342  unsigned int precision_;
343  /// Time unit conversion object.
344  std::shared_ptr<TimeUnitConversion> time_unit_conversion_;
345 
346  // Warn for no observe fields only once.
347  bool no_fields_warning=false;
348 
349  /// Index set assigning to local point index its global index.
351 
352  /// Parallel distribution of observe points.
354 
355  /// Index of actual (last) time in \p observe_values_time_ vector
356  unsigned int observe_time_idx_;
357 
358  /// Holds observe data of eval points on patch
360 
361  friend class ObservePointAccessor;
362 };
363 
364 
365 /**
366  * @brief Point accessor allow iterate over local Observe points.
367  *
368  * Iterator is defined by:
369  * - Observe object
370  * - local index of observe point (iterated value)
371  */
373 public:
374  /// Default invalid accessor.
376  : observe_(NULL)
377  {}
378 
379  /**
380  * Observe point accessor.
381  */
382  ObservePointAccessor(const Observe *observe, unsigned int loc_idx)
383  : observe_(observe), loc_point_idx_(loc_idx)
384  {}
385 
386  /// Return local index to point.
387  inline unsigned int local_idx() const {
388  return loc_point_idx_;
389  }
390 
391  /// Return global index to point.
392  inline unsigned int global_idx() const {
394  }
395 
396  /// Return ElementAccessor to element of loc_ele_idx_.
397  inline const ObservePoint observe_point() const {
398  return observe_->points_[ this->global_idx() ];
399  }
400 
401  /// Return local index in data cache (combination of local point index and index of stored time)
402  inline unsigned int loc_point_time_index() const {
404  }
405 
406  /// Check validity of accessor (see default constructor)
407  inline bool is_valid() const {
408  return observe_ != NULL;
409  }
410 
411  /// Iterates to next local point.
412  inline void inc() {
413  loc_point_idx_++;
414  }
415 
416  /// Comparison of accessors.
417  bool operator==(const ObservePointAccessor& other) {
418  return (loc_point_idx_ == other.loc_point_idx_);
419  }
420 
421 protected:
422  /// Pointer to the Observe owning the point.
423  const Observe * observe_;
424  /// Index into Observe::point_4_loc_ array.
425  unsigned int loc_point_idx_;
426 
427 };
428 
429 
430 
431 
432 #endif /* SRC_IO_OBSERVE_HH_ */
Observe::patch_point_data_
PatchPointVec patch_point_data_
Holds observe data of eval points on patch.
Definition: observe.hh:359
Observe::point_ds
const Distribution * point_ds() const
Definition: observe.hh:276
general_iterator.hh
Template Iter serves as general template for internal iterators.
Observe
Definition: observe.hh:228
Observe::precision_
unsigned int precision_
Precision of float output.
Definition: observe.hh:342
Armor::vec
ArmaVec< double, N > vec
Definition: armor.hh:885
ObservePointAccessor::operator==
bool operator==(const ObservePointAccessor &other)
Comparison of accessors.
Definition: observe.hh:417
PatchPointData::i_quad_point
unsigned int i_quad_point
Index of point in quadrature (use during patch creating)
Definition: observe.hh:54
Observe::OutputDataFieldMap
std::map< string, OutputDataPtr > OutputDataFieldMap
Definition: observe.hh:232
Input
Abstract linear system class.
Definition: balance.hh:40
ObservePointAccessor::ObservePointAccessor
ObservePointAccessor()
Default invalid accessor.
Definition: observe.hh:375
ElementDataCache
Definition: element_data_cache.hh:44
ASSERT
#define ASSERT(expr)
Definition: asserts.hh:351
ObservePointData::local_idx_
LongIdx local_idx_
Local index on actual process of the observe point.
Definition: observe.hh:90
Observe::point_ds_
Distribution * point_ds_
Parallel distribution of observe points.
Definition: observe.hh:353
PatchPointData::PatchPointData
PatchPointData()
Default constructor.
Definition: observe.hh:39
PatchPointData::i_quad
unsigned int i_quad
Index of quadrature (use during patch creating), i_quad = dim-1.
Definition: observe.hh:53
ObservePoint::local_coords
arma::vec local_coords() const
Definition: observe.hh:133
distribution.hh
Support classes for parallel programing.
ObservePointAccessor::observe_point
const ObservePoint observe_point() const
Return ElementAccessor to element of loc_ele_idx_.
Definition: observe.hh:397
ObservePointData::distance_
double distance_
Definition: observe.hh:81
Observe::local_range
Range< ObservePointAccessor > local_range() const
Returns local range of observe points.
Definition: observe.cc:490
std::vector< PatchPointData >
Observe::observe_values_time_
std::vector< double > observe_values_time_
Common evaluation time of the fields for single time frame.
Definition: observe.hh:333
ElementAccessor< 3 >
field_value_to_yaml
string field_value_to_yaml(const T &mat, unsigned int prec)
Definition: armadillo_tools.cc:138
arma::vec3
Definition: doxy_dummy_defs.hh:17
Observe::no_fields_warning
bool no_fields_warning
Definition: observe.hh:347
ObservePointAccessor::global_idx
unsigned int global_idx() const
Return global index to point.
Definition: observe.hh:392
Observe::observed_elements
const std::vector< unsigned int > & observed_elements() const
Definition: observe.hh:253
ObservePoint::global_coords
arma::vec3 global_coords() const
Definition: observe.hh:139
index_types.hh
TimeUnitConversion
Helper class storing unit conversion coefficient and functionality for conversion of units.
Definition: time_governor.hh:58
PatchPointData::i_reg
unsigned int i_reg
Index of region (use during patch creating)
Definition: observe.hh:52
exceptions.hh
ObservePoint::have_observe_element
bool have_observe_element()
Definition: observe.cc:164
Distribution
Definition: distribution.hh:50
ObservePointData
Definition: observe.hh:64
ObservePoint::get_input_type
static const Input::Type::Record & get_input_type()
Definition: observe.cc:107
ObservePointAccessor::inc
void inc()
Iterates to next local point.
Definition: observe.hh:412
armadillo_tools.hh
ObservePoint::snap_dim_
unsigned int snap_dim_
Definition: observe.hh:198
Observe::prepare_compute_data
OutputDataPtr prepare_compute_data(std::string field_name, double field_time, unsigned int n_shape)
Definition: observe.cc:403
Observe::flush_values
void flush_values()
Effectively writes the data into the observe stream.
Definition: observe.cc:434
ObservePointAccessor
Point accessor allow iterate over local Observe points.
Definition: observe.hh:372
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
PatchPointData::local_coords
arma::vec local_coords
Local coords of point.
Definition: observe.hh:51
ObservePoint::TYPEDEF_ERR_INFO
TYPEDEF_ERR_INFO(EI_RegionName, std::string)
Observe::OutputDataPtr
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: observe.hh:231
ObservePointData::proc_
unsigned int proc_
Actual process of the observe point.
Definition: observe.hh:84
ObservePoint::output
void output(ostream &out, unsigned int indent_spaces, unsigned int precision)
Definition: observe.cc:292
ObservePoint::DECLARE_INPUT_EXCEPTION
DECLARE_INPUT_EXCEPTION(ExcNoInitialPoint,<< "Failed to find the element containing the initial observe point.\n")
ObservePoint::snap
void snap(Mesh &mesh)
Definition: observe.cc:170
accessors.hh
Observe::output_header
void output_header()
Definition: observe.cc:422
Observe::rank_
int rank_
Definition: observe.hh:321
ObservePoint
Definition: observe.hh:99
Observe::Observe
Observe(string observe_name, Mesh &mesh, Input::Array in_array, unsigned int precision, const std::shared_ptr< TimeUnitConversion > &time_unit_conv)
Definition: observe.cc:340
ElementDataCacheBase
Definition: element_data_cache_base.hh:33
Observe::patch_point_data
PatchPointVec & patch_point_data()
Getter of patch_point_data.
Definition: observe.hh:307
input_exception.hh
Observe::observe_file_
std::ofstream observe_file_
Output file stream.
Definition: observe.hh:339
std::map< string, OutputDataPtr >
ObservePoint::element_idx
unsigned int element_idx() const
Definition: observe.hh:127
PatchPointData::PatchPointData
PatchPointData(const PatchPointData &other)
Copy constructor.
Definition: observe.hh:46
Input::Type
Definition: balance.hh:41
ObservePointAccessor::loc_point_idx_
unsigned int loc_point_idx_
Index into Observe::point_4_loc_ array.
Definition: observe.hh:425
ObservePointAccessor::is_valid
bool is_valid() const
Check validity of accessor (see default constructor)
Definition: observe.hh:407
Observe::output_time_frame
void output_time_frame(bool flush)
Definition: observe.cc:463
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
ObservePoint::snap_region_name_
string snap_region_name_
Definition: observe.hh:203
Observe::observed_element_indices_
std::vector< unsigned int > observed_element_indices_
Elements of the o_points.
Definition: observe.hh:326
LongIdx
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
Definition: index_types.hh:24
Observe::points
const std::vector< ObservePoint > & points() const
Definition: observe.hh:270
Observe::~Observe
~Observe()
Destructor, must close the file.
Definition: observe.cc:394
Mesh
Definition: mesh.h:362
ObservePointAccessor::ObservePointAccessor
ObservePointAccessor(const Observe *observe, unsigned int loc_idx)
Definition: observe.hh:382
Range
Range helper class.
Definition: range_wrapper.hh:65
ObservePointData::local_coords_
arma::vec local_coords_
Local (barycentric) coordinates on the element.
Definition: observe.hh:77
ObservePointAccessor::observe_
const Observe * observe_
Pointer to the Observe owning the point.
Definition: observe.hh:423
Input::Array
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
Observe::max_observe_value_time
static const unsigned int max_observe_value_time
Maximal size of observe values times vector.
Definition: observe.hh:318
PatchPointData::PatchPointData
PatchPointData(unsigned int elm_idx, arma::vec loc_coords)
Constructor with data mebers initialization.
Definition: observe.hh:42
ObservePointAccessor::loc_point_time_index
unsigned int loc_point_time_index() const
Return local index in data cache (combination of local point index and index of stored time)
Definition: observe.hh:402
Observe::observe_field_values_
OutputDataFieldMap observe_field_values_
Stored field values.
Definition: observe.hh:329
PatchPointVec
std::vector< PatchPointData > PatchPointVec
Definition: observe.hh:56
ObservePointAccessor::local_idx
unsigned int local_idx() const
Return local index to point.
Definition: observe.hh:387
ObservePoint::point_projection
ObservePointData point_projection(unsigned int i_elm, ElementAccessor< 3 > elm)
Project point to given element by dimension of this element.
Definition: observe.cc:303
ObservePoint::observe_data_
ObservePointData observe_data_
Helper object stored projection data.
Definition: observe.hh:214
ObservePointData::ObservePointData
ObservePointData()
Constructor.
Definition: observe.hh:67
Observe::point_4_loc_
std::vector< LongIdx > point_4_loc_
Index set assigning to local point index its global index.
Definition: observe.hh:350
PatchPointData
Holds data of one eval point on patch (index of element and local coordinations).
Definition: observe.hh:37
Observe::observe_name_
std::string observe_name_
Definition: observe.hh:336
ObservePointData::element_idx_
unsigned int element_idx_
Final element of the observe point. The index in the mesh.
Definition: observe.hh:68
ObservePoint::max_search_radius_
double max_search_radius_
Definition: observe.hh:208
Observe::time_unit_conversion_
std::shared_ptr< TimeUnitConversion > time_unit_conversion_
Time unit conversion object.
Definition: observe.hh:344
Observe::observe_time_idx_
unsigned int observe_time_idx_
Index of actual (last) time in observe_values_time_ vector.
Definition: observe.hh:356
Observe::get_output_cache
OutputDataPtr get_output_cache(std::string field_name)
Definition: observe.hh:300
Observe::points_
std::vector< ObservePoint > points_
Full information about observe points.
Definition: observe.hh:324
ObservePointData::global_idx_
LongIdx global_idx_
Global index of the observe point.
Definition: observe.hh:87
ObservePointData::global_coords_
arma::vec3 global_coords_
Global coordinates of the observation point.
Definition: observe.hh:74
ObservePoint::in_rec_
Input::Record in_rec_
Index in the input array.
Definition: observe.hh:189
PatchPointData::elem_idx
unsigned int elem_idx
Index of element.
Definition: observe.hh:50
ObservePoint::find_observe_point
void find_observe_point(Mesh &mesh)
Definition: observe.cc:198
ObservePoint::ObservePoint
ObservePoint()
Definition: observe.cc:138
ObservePoint::name_
std::string name_
Observation point name.
Definition: observe.hh:192
ObservePoint::input_point_
arma::vec3 input_point_
Input coordinates of the initial position of the observation point.
Definition: observe.hh:211
range_wrapper.hh
Implementation of range helper class.