Flow123d  release_3.0.0-1094-g626f1a1
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 
25 class Mesh;
26 namespace Input { namespace Type { class Record; } }
27 template <typename T> class ElementDataCache;
28 
29 
30 
31 /**
32  * Helper class stores base data of ObservePoint and allows to evaluate
33  * the nearest point to input_point_.
34  */
36 public:
37  /// Constructor
39  : distance_(numeric_limits<double>::infinity()) {};
40 
41  /// Final element of the observe point. The index in the mesh.
42  unsigned int element_idx_;
43 
44  /// Global coordinates of the observation point.
46 
47  /// Local (barycentric) coordinates on the element.
48  arma::vec local_coords_;
49 
50  /// Distance of found projection from the initial point.
51  /// If we find more candidates we pass in the closest one.
52  double distance_;
53 
54 };
55 
56 
57 /**
58  * Class representing single observe point, used internally by the class Observe.
59  * Members: input_pos_, snap_dim_, snap_region_name_ are set in constructor. Should be checked before passed in.
60  * Members: element_idx_, global_coords_, local_coords_ are derived, set in Observe::find_observe_points.
61  */
62 class ObservePoint {
63 public:
64  DECLARE_INPUT_EXCEPTION(ExcNoInitialPoint,
65  << "Failed to find the element containing the initial observe point.\n");
66  TYPEDEF_ERR_INFO(EI_RegionName, std::string);
67  TYPEDEF_ERR_INFO(EI_PointName, std::string);
68  TYPEDEF_ERR_INFO(EI_Point, arma::vec3);
69  TYPEDEF_ERR_INFO(EI_ClosestEle, ObservePointData);
70  DECLARE_INPUT_EXCEPTION(ExcNoObserveElementCandidates,
71  << "Failed to find any element in the search radius of the observe point " << EI_PointName::qval
72  << " with given coordinates " << field_value_to_yaml(EI_Point::ref(*this)) << ".\n"
73  << "The closest element has index " << EI_ClosestEle::ref(*this).element_idx_ << ", its distance is " << EI_ClosestEle::ref(*this).distance_ << ".\n"
74  << "Solution: check the position of the observe point, possibly increase the maximal snapping distance "
75  << "(keys: observe_points:search_radius, mesh:global_snap_radius)"<< "\n");
76  DECLARE_INPUT_EXCEPTION(ExcNoObserveElement,
77  << "Failed to find any element in the search radius of the observe point" << EI_PointName::qval
78  << " inside the snap region: " << EI_RegionName::qval << ".\n"
79  << "The observe point coordinates are " << field_value_to_yaml(EI_Point::ref(*this)) << ".\n"
80  << "The closest element (outside the snap region) has index " << EI_ClosestEle::ref(*this).element_idx_
81  << ", its distance is " << EI_ClosestEle::ref(*this).distance_ << ".\n"
82  << "Solution: check the position/region of the observe point, possibly increase the maximal snapping distance "
83  << "(keys: observe_points:search_radius, mesh:global_snap_radius)"<< "\n");
84 
85  static const Input::Type::Record & get_input_type();
86 
87  /**
88  * Return index of observation point in the mesh.
89  */
90  inline unsigned int element_idx() const
91  { return observe_data_.element_idx_; }
92 
93  /**
94  * Return global coordinates of the observation point.
95  */
96  inline arma::vec3 global_coords() const
97  { return observe_data_.global_coords_; }
98 
99 protected:
100  /**
101  * Default constructor just for testing.
102  */
103  ObservePoint();
104 
105  /**
106  * Constructor. Read from input.
107  */
108  ObservePoint(Input::Record in_rec, Mesh &mesh, unsigned int point_idx);
109 
110  /**
111  * Returns true if we have already found any observe element.
112  */
113  bool have_observe_element();
114 
115  /**
116  * Snap to the center of closest subelement with dimension snap_dim_.
117  * This makes final adjustment of global_coords_ and local_coords_.
118  */
119  void snap(Mesh &mesh);
120 
121 
122  /**
123  * Find the observe element and the definitive observe point.
124  *
125  * Algorithm:
126  * 1. find element containing the point (initial element)
127  * 2. check initial element for region match possibly set it as (observe element)
128  * 3. add neighbours into processing_list for the next level
129  * 4. while we have no observe element: pass through the processing list of the current level
130  * 5. if element match the region, project and clip the init point, update observe element.
131  * 6. snapping on the observe element
132  *
133  */
134  void find_observe_point(Mesh &mesh);
135 
136  /**
137  * Output the observe point information into a YAML formated stream, indent by
138  * given number of spaces + "- ".
139  */
140  void output(ostream &out, unsigned int indent_spaces, unsigned int precision);
141 
142  /// Project point to given element by dimension of this element.
143  ObservePointData point_projection(unsigned int i_elm, ElementAccessor<3> elm);
144 
145  /// Index in the input array.
147 
148  /// Observation point name.
149  std::string name_;
150 
151  /**
152  * Snap to the center of the object of given dimension.
153  * Value 4 and greater means no snapping.
154  */
155  unsigned int snap_dim_;
156 
157  /**
158  * Region of the snapping element.
159  */
161 
162  /**
163  * Maximal distance of observe element from input point.
164  */
166 
167  /// Input coordinates of the initial position of the observation point.
169 
170  /// Helper object stored projection data
172 
173  /// Only Observe should use this class directly.
174  friend class Observe;
175 
176 };
177 
178 
179 /**
180  * This class takes care about the observe points in the output stream, storing observe values of the fields and
181  * their output in the YAML format.
182  */
183 
184 class Observe {
185 public:
186 
187  typedef std::shared_ptr<ElementDataCacheBase> OutputDataPtr;
189 
190  /**
191  * Construct the observation object.
192  *
193  * observe_name - base name of the output file, the equation name.
194  * mesh - the mesh used for search for the observe points
195  * in_array - the array of observe points
196  */
197  Observe(string observe_name, Mesh &mesh, Input::Array in_array, unsigned int precision, std::string unit_str);
198 
199  /// Destructor, must close the file.
200  ~Observe();
201 
202 
203  /**
204  * Provides a vector of element indices on which the observation values are evaluated.
205  * This can be used to evaluate derived fields only on these elements in the times not selected to
206  * full output.
207  */
209  { return observed_element_indices_;}
210 
211  /**
212  * Output file header.
213  */
214  void output_header();
215 
216  /**
217  * Write field values to the output file. Using the YAML format.
218  */
219  void output_time_frame(double time);
220 
221  /**
222  * Return \p points_ vector
223  */
224  inline const std::vector<ObservePoint> & points() const
225  { return points_; }
226 
227  /**
228  * Prepare data for computing observe values.
229  *
230  * Method:
231  * - check that all fields of one time frame are evaluated at the same time
232  * - find and return ElementDataCache of given field_name, create its if doesn't exist.
233  *
234  * @param field_name Quantity name of founding ElementDataCache
235  * @param field_time Actual computing time
236  * @param n_rows Count of rows of data cache (used only if new cache is created)
237  * @param n_cols Count of columns of data cache (used only if new cache is created)
238  */
239  template <typename T>
240  ElementDataCache<T> & prepare_compute_data(std::string field_name, double field_time, unsigned int n_rows, unsigned int n_cols);
241 
242 
243 
244 protected:
245  // MPI rank.
246  int rank_;
247 
248  /// Full information about observe points.
250  /// Elements of the o_points.
252 
253  /// Stored field values.
254  OutputDataFieldMap observe_field_values_;
255 
256 
257  /// Common evaluation time of the fields for single time frame.
259 
260  // Name of the observation stream. Base for the output filename.
261  std::string observe_name_;
262 
263  /// Output file stream.
264  std::ofstream observe_file_;
265 
266  /// String representation of the time unit.
267  std::string time_unit_str_;
268  /// Time unit in seconds.
270  /// Precision of float output
271  unsigned int precision_;
272 
273  // Warn for no observe fields only once.
274  bool no_fields_warning=false;
275 
276 };
277 
278 
279 
280 #endif /* SRC_IO_OBSERVE_HH_ */
std::vector< ObservePoint > points_
Full information about observe points.
Definition: observe.hh:249
double max_search_radius_
Definition: observe.hh:165
OutputDataFieldMap observe_field_values_
Stored field values.
Definition: observe.hh:254
std::ofstream observe_file_
Output file stream.
Definition: observe.hh:264
Accessor to input data conforming to declared Array.
Definition: accessors.hh:567
string field_value_to_yaml(const T &mat, unsigned int prec)
TYPEDEF_ERR_INFO(EI_KeyName, const string)
arma::vec3 input_point_
Input coordinates of the initial position of the observation point.
Definition: observe.hh:168
const std::vector< ObservePoint > & points() const
Definition: observe.hh:224
ObservePointData()
Constructor.
Definition: observe.hh:38
Abstract linear system class.
Definition: balance.hh:35
Definition: mesh.h:76
unsigned int element_idx_
Final element of the observe point. The index in the mesh.
Definition: observe.hh:39
std::string time_unit_str_
String representation of the time unit.
Definition: observe.hh:267
int rank_
Definition: observe.hh:246
std::string observe_name_
Definition: observe.hh:261
arma::vec local_coords_
Local (barycentric) coordinates on the element.
Definition: observe.hh:48
Input::Record in_rec_
Index in the input array.
Definition: observe.hh:146
unsigned int element_idx() const
Definition: observe.hh:90
arma::vec3 global_coords_
Global coordinates of the observation point.
Definition: observe.hh:45
unsigned int precision_
Precision of float output.
Definition: observe.hh:271
std::string name_
Observation point name.
Definition: observe.hh:149
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:251
double distance_
Definition: observe.hh:52
double observe_values_time_
Common evaluation time of the fields for single time frame.
Definition: observe.hh:258
unsigned int snap_dim_
Definition: observe.hh:155
const std::vector< unsigned int > & observed_elements() const
Definition: observe.hh:208
ObservePointData observe_data_
Helper object stored projection data.
Definition: observe.hh:171
double time_unit_seconds_
Time unit in seconds.
Definition: observe.hh:269
std::map< string, OutputDataPtr > OutputDataFieldMap
Definition: observe.hh:188
std::shared_ptr< ElementDataCacheBase > OutputDataPtr
Definition: observe.hh:187
string snap_region_name_
Definition: observe.hh:160
Record type proxy class.
Definition: type_record.hh:182
arma::vec3 global_coords() const
Definition: observe.hh:96
DECLARE_INPUT_EXCEPTION(ExcInputMessage,<< EI_Message::val)
Simple input exception that accepts just string message.