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