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