12 #include <unordered_set> 30 return IT::Record(
"ObservePoint",
"Specification of the observation point.\n" 31 "The actual observation element and the observation point on it is determined as follows:\n\n" 32 "1. Find an initial element containing the initial point. If no such element exists, we report an error.\n" 33 "2. Use BFS (Breadth-first search) starting from the inital element to find the 'observe element'. The observe element is the closest element.\n" 34 "3. Find the closest projection of the inital point on the observe element and snap this projection according to the ``snap_dim``.\n")
38 "Default name have the form 'obs_<id>', where 'id' " 39 "is the rank of the point on the input."),
40 "Optional point name, which has to be unique.\n" 41 "Any string that is a valid YAML key in record without any quoting can be used, however," 42 "using just alpha-numerical characters, and underscore instead of the space, is recommended." 45 "Initial point for the observe point search.")
47 "The dimension of the sub-element to which center we snap. For value 4 no snapping is done. " 48 "For values 0 up to 3 the element containing the initial point is found and then the observe" 49 "point is snapped to the nearest center of the sub-element of the given dimension. " 50 "E.g. for dimension 2 we snap to the nearest center of the face of the initial element." 53 "The region of the initial element for snapping. Without snapping we make a projection to the initial element.")
55 "Maximum number of levels of the breadth first search used to find the observe element from the initial element. Value zero means to search only the initial element itself.")
64 :
distance_(numeric_limits<double>::infinity())
69 name_ = in_rec.
val<
string>(
"name", default_label );
86 double dist = arma::norm(global_coords -
input_point_, 2);
99 return distance_ < numeric_limits<double>::infinity();
104 template <
int ele_dim>
109 double min_dist = 2.0;
110 arma::vec min_center;
114 if ( dist < min_dist) {
127 case 1: snap_to_subelement<1>();
break;
128 case 2: snap_to_subelement<2>();
break;
129 case 3: snap_to_subelement<3>();
break;
130 default:
ASSERT(
false).error(
"Clipping supported only for dim=1,2,3.");
139 if (region_set.size() == 0)
145 std::unordered_set<unsigned int> closed_elements(1023);
149 bih_tree.
find_point( projected_point, candidate_list );
150 process_list.swap(candidate_list);
151 candidate_list.clear();
153 unsigned int min_dist_idx=0;
154 double min_dist=numeric_limits<double>::max();
155 for (
unsigned int i_candidate=0; i_candidate<process_list.size(); ++i_candidate) {
156 unsigned int i_elm=process_list[i_candidate];
173 projection[elm.
dim()] = 1.0;
174 arma::vec global_coord = map*projection;
178 closed_elements.insert(i_elm);
180 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
182 candidate_list.push_back(i_node_ele);
186 double distance = fabs(projection.min());
187 if (distance < min_dist) {
189 min_dist_idx = i_candidate;
196 if (candidate_list.size() == 0) {
198 unsigned int i_elm=process_list[min_dist_idx];
206 projection[elm.
dim()] = 1.0;
207 arma::vec global_coord = map*projection;
211 WarningOut().fmt(
"Failed to find the element containing the initial observe point ({}).\n" 214 closed_elements.insert(i_elm);
216 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
218 candidate_list.push_back(i_node_ele);
224 for(
unsigned int i_level=0; i_level <
max_levels_; i_level++) {
226 process_list.swap(candidate_list);
227 candidate_list.clear();
228 for(
unsigned int i_elm : process_list) {
229 if (closed_elements.find(i_elm) != closed_elements.end())
continue;
238 point_on_element[elm.
dim()] = 1.0;
239 arma::vec global_coord = map*point_on_element;
243 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
245 candidate_list.push_back(i_node_ele);
256 if (dist > 2*elm_norm)
257 WarningOut().fmt(
"Observe point ({}) is too distant from the mesh.\n",
name_);
264 out << setw(indent_spaces) <<
"" <<
"- name: " <<
name_ << endl;
266 out << setw(indent_spaces) <<
"" <<
" snap_dim: " <<
snap_dim_ << endl;
267 out << setw(indent_spaces) <<
"" <<
" snap_region: " <<
snap_region_name_ << endl;
275 : observe_values_time_(numeric_limits<double>::signaling_NaN()),
276 observe_name_(observe_name),
277 precision_(precision)
283 point.find_observe_point(mesh);
295 if (
points_.size() == 0)
return;
304 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, in_array)
314 template <
typename T>
327 = std::make_shared< ElementDataCache<T> >(field_name, n_rows, n_cols,
points_.size());
334 #define OBSERVE_PREPARE_COMPUTE_DATA(TYPE) \ 335 template ElementDataCache<TYPE> & Observe::prepare_compute_data<TYPE>(std::string field_name, double field_time, \ 336 unsigned int n_rows, unsigned int n_cols) 344 unsigned int indent = 2;
356 if (
points_.size() == 0)
return;
374 unsigned int indent = 2;
377 observe_file_ << setw(indent) <<
"" <<
" " << field_data.second->field_input_name() <<
": ";
std::vector< ObservePoint > points_
Full information about observe points.
arma::vec project_point(const arma::vec3 &point, const arma::mat &map) const
#define OBSERVE_PREPARE_COMPUTE_DATA(TYPE)
OutputDataFieldMap observe_field_values_
Stored field values.
unsigned int n_nodes() const
vector< vector< unsigned int > > const & node_elements()
std::ofstream observe_file_
Output file stream.
arma::vec3 input_point_
Input coordinates of the initial position of the observation point.
arma::mat element_map() const
static const Input::Type::Record & get_input_type()
bool have_observe_element()
RegionSet get_region_set(const string &set_name) const
void output(ostream &out, unsigned int indent_spaces, unsigned int precision)
Observe(string observe_name, Mesh &mesh, Input::Array in_array, unsigned int precision)
static const double epsilon
stabilization parameter
std::string time_unit_str_
String representation of the time unit.
const RegionDB & region_db() const
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
std::string to_string(const T &value)
std::string observe_name_
arma::vec clip_to_element(arma::vec &barycentric)
Input::Record in_rec_
Index in the input array.
void open_stream(Stream &stream) const
Global macros to enhance readability and debugging, general constants.
unsigned int precision_
Precision of float output.
void find_observe_point(Mesh &mesh)
void snap_to_subelement()
std::string name_
Observation point name.
const BoundingBox & tree_box() const
std::vector< unsigned int > observed_element_indices_
Elements of the o_points.
const Point & max() const
Class for O(log N) lookup for intersections with a set of bounding boxes.
unsigned int index(const T *pointer) const
ElementDataCache< T > & prepare_compute_data(std::string field_name, double field_time, unsigned int n_rows, unsigned int n_cols)
double observe_values_time_
Common evaluation time of the fields for single time frame.
void find_point(const Space< 3 >::Point &point, std::vector< unsigned int > &result_list) const
const BIHTree & get_bih_tree()
Dedicated class for storing path to input and output files.
arma::vec3 global_coords_
Global coordinates of the observation point.
arma::vec local_coords_
Local (barycentric) coordinates on the element.
void update_projection(unsigned int i_elm, arma::vec local_coords, arma::vec3 global_coords)
arma::vec3 centre() const
double time_unit_seconds_
Time unit in seconds.
bool is_in_region_set(const RegionSet &set) const
Point project_point(const Point &point) const
#define WarningOut()
Macro defining 'warning' record of log.
const Point & min() const
unsigned int element_idx_
Final element of the observe point. The index in the mesh.
arma::vec3 global_coords() const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
~Observe()
Destructor, must close the file.
NodeVector node_vector
Vector of nodes of the mesh.
void output_time_frame(double time)
ElementVector element
Vector of elements of the mesh.
BoundingBox bounding_box()