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