12 #include <unordered_set> 30 return IT::Record(
"ObservePoint",
"Specification of the observation point. The actual observe element and the observe point on it is determined as follows:\n\n" 31 "1. Find an initial element containing the initial point. If no such element exists we report the error.\n" 32 "2. Use BFS starting from the inital element to find the 'observe element'. The observe element is the closest element " 33 "3. Find the closest projection of the inital point on the observe element and snap this projection according to the 'snap_dim'.\n")
37 "Default name have the form 'obs_<id>', where 'id' " 38 "is the rank of the point on the input."),
39 "Optional point name. Has to be unique. Any string that is valid YAML key in record without any quoting can be used however" 40 "using just alpha-numerical characters and underscore instead of the space is recommended. " 43 "Initial point for the observe point search.")
45 "The dimension of the sub-element to which center we snap. For value 4 no snapping is done. " 46 "For values 0 up to 3 the element containing the initial point is found and then the observe" 47 "point is snapped to the nearest center of the sub-element of the given dimension. " 48 "E.g. for dimension 2 we snap to the nearest center of the face of the initial element." 51 "The region of the initial element for snapping. Without snapping we make a projection to the initial element.")
53 "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.")
62 :
distance_(numeric_limits<double>::infinity())
67 name_ = in_rec.
val<
string>(
"name", default_label );
84 double dist = arma::norm(global_coords -
input_point_, 2);
97 return distance_ < numeric_limits<double>::infinity();
102 template <
int ele_dim>
107 double min_dist = 2.0;
108 arma::vec min_center;
112 if ( dist < min_dist) {
125 case 1: snap_to_subelement<1>();
break;
126 case 2: snap_to_subelement<2>();
break;
127 case 3: snap_to_subelement<3>();
break;
128 default:
ASSERT(
false).error(
"Clipping supported only for dim=1,2,3.");
137 if (region_set.size() == 0)
143 std::unordered_set<unsigned int> closed_elements(1023);
147 bih_tree.
find_point( projected_point, candidate_list );
148 process_list.swap(candidate_list);
149 candidate_list.clear();
151 unsigned int min_dist_idx=0;
152 double min_dist=numeric_limits<double>::max();
153 for (
unsigned int i_candidate=0; i_candidate<process_list.size(); ++i_candidate) {
154 unsigned int i_elm=process_list[i_candidate];
171 projection[elm.
dim()] = 1.0;
172 arma::vec global_coord = map*projection;
176 closed_elements.insert(i_elm);
178 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
180 candidate_list.push_back(i_node_ele);
184 double distance = fabs(projection.min());
185 if (distance < min_dist) {
187 min_dist_idx = i_candidate;
194 if (candidate_list.size() == 0) {
196 unsigned int i_elm=process_list[min_dist_idx];
204 projection[elm.
dim()] = 1.0;
205 arma::vec global_coord = map*projection;
209 WarningOut().fmt(
"Failed to find the element containing the initial observe point ({}).\n" 212 closed_elements.insert(i_elm);
214 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
216 candidate_list.push_back(i_node_ele);
222 for(
unsigned int i_level=0; i_level <
max_levels_; i_level++) {
224 process_list.swap(candidate_list);
225 candidate_list.clear();
226 for(
unsigned int i_elm : process_list) {
227 if (closed_elements.find(i_elm) != closed_elements.end())
continue;
236 point_on_element[elm.
dim()] = 1.0;
237 arma::vec global_coord = map*point_on_element;
241 for (
unsigned int n=0; n < elm.
n_nodes(); n++) {
243 candidate_list.push_back(i_node_ele);
254 if (dist > 2*elm_norm)
255 WarningOut().fmt(
"Observe point ({}) is too distant from the mesh.\n",
name_);
262 out << setw(indent_spaces) <<
"" <<
"- name: " <<
name_ << endl;
264 out << setw(indent_spaces) <<
"" <<
" snap_dim: " <<
snap_dim_ << endl;
265 out << setw(indent_spaces) <<
"" <<
" snap_region: " <<
snap_region_name_ << endl;
273 : observe_values_time_(numeric_limits<double>::signaling_NaN()),
274 observe_name_(observe_name),
275 precision_(precision)
281 point.find_observe_point(mesh);
293 if (
points_.size() == 0)
return;
302 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, in_array)
312 template <
typename T>
325 = std::make_shared< ElementDataCache<T> >(field_name, n_rows, n_cols,
points_.size());
332 #define OBSERVE_PREPARE_COMPUTE_DATA(TYPE) \ 333 template ElementDataCache<TYPE> & Observe::prepare_compute_data<TYPE>(std::string field_name, double field_time, \ 334 unsigned int n_rows, unsigned int n_cols) 342 unsigned int indent = 2;
354 if (
points_.size() == 0)
return;
372 unsigned int indent = 2;
375 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()