12 #include <unordered_set> 41 template<
unsigned int dim>
67 if (snap_dim <= dim) {
68 double min_dist = 2.0;
72 double dist = arma::norm(center - observe_data.
local_coords_, 2);
73 if ( dist < min_dist) {
112 return IT::Record(
"ObservePoint",
"Specification of the observation point.\n" 113 "The actual observation element and the observation point on it is determined as follows:\n\n" 114 "1. Find an initial element containing the initial point. If no such element exists, we report an error.\n" 115 "2. Use BFS (Breadth-first search) starting from the inital element to find the 'observe element'. The observe element is the closest element.\n" 116 "3. Find the closest projection of the inital point on the observe element and snap this projection according to the ``snap_dim``.\n")
120 "Default name have the form 'obs_<id>', where 'id' " 121 "is the rank of the point on the input."),
122 "Optional point name, which has to be unique.\n" 123 "Any string that is a valid YAML key in record without any quoting can be used, however, " 124 "using just alpha-numerical characters, and underscore instead of the space, is recommended." 127 "Initial point for the observe point search.")
129 "The dimension of the sub-element to which center we snap. For value 4 no snapping is done. " 130 "For values 0 up to 3 the element containing the initial point is found and then the observe" 131 "point is snapped to the nearest center of the sub-element of the given dimension. " 132 "E.g. for dimension 2 we snap to the nearest center of the face of the initial element." 135 "The region of the initial element for snapping. Without snapping we make a projection to the initial element.")
137 IT::Default::read_time(
"Maximal distance of the observe point from the mesh relative to the mesh diameter. "),
138 "Global value is defined in mesh record by the key global_snap_radius.")
150 string default_label = string(
"obs_") +
std::to_string(point_idx);
151 name_ = in_rec.
val<
string>(
"name", default_label );
157 snap_dim_ = in_rec.
val<
unsigned int>(
"snap_dim");
159 snap_region_name_ = in_rec.
val<
string>(
"snap_region");
162 double max_mesh_size = arma::max(main_box.max() - main_box.min());
163 max_search_radius_ = in_rec_.val<
double>(
"search_radius", mesh.
global_snap_radius()) * max_mesh_size;
169 return observe_data_.distance_ < numeric_limits<double>::infinity();
196 default:
ASSERT(
false).error(
"Clipping supported only for dim=1,2,3.");
204 if (region_set.size() == 0)
205 THROW( RegionDB::ExcUnknownSet() << RegionDB::EI_Label(snap_region_name_) << in_rec_.ei_address() );
210 std::unordered_set<unsigned int> closed_elements(1023);
211 std::priority_queue< ObservePointData, std::vector<ObservePointData>,
CompareByDist > candidate_queue;
215 bih_tree.
find_point(projected_point, candidate_list,
true);
220 for (
unsigned int i_candidate=0; i_candidate<candidate_list.size(); ++i_candidate) {
221 unsigned int i_elm=candidate_list[i_candidate];
225 auto observe_data = point_projection( i_elm, elm );
228 if(observe_data.distance_ < min_observe_point_data.
distance_)
229 min_observe_point_data = observe_data;
232 if (observe_data.distance_ <= max_search_radius_)
233 candidate_queue.push(observe_data);
234 closed_elements.insert(i_elm);
238 if (candidate_queue.empty()) {
239 THROW(ExcNoObserveElementCandidates()
240 << EI_PointName(name_)
241 << EI_Point(input_point_)
242 << EI_ClosestEle(min_observe_point_data));
245 while (!candidate_queue.empty())
247 auto candidate_data = candidate_queue.top();
248 candidate_queue.pop();
250 unsigned int i_elm=candidate_data.element_idx_;
255 ASSERT_LE(candidate_data.distance_, observe_data_.distance_).error();
257 observe_data_.distance_ = candidate_data.distance_;
258 observe_data_.element_idx_ = candidate_data.element_idx_;
259 observe_data_.local_coords_ = candidate_data.local_coords_;
260 observe_data_.global_coords_ = candidate_data.global_coords_;
261 observe_data_.proc_ = candidate_data.proc_;
266 for (
unsigned int n=0; n < elm->
n_nodes(); n++)
268 if (closed_elements.find(i_node_ele) == closed_elements.end()) {
270 auto observe_data = point_projection( i_node_ele, neighbor_elm );
271 if (observe_data.distance_ <= max_search_radius_)
272 candidate_queue.push(observe_data);
273 closed_elements.insert(i_node_ele);
278 if (! have_observe_element()) {
279 THROW(ExcNoObserveElement()
280 << EI_RegionName(snap_region_name_)
281 << EI_PointName(name_)
282 << EI_Point(input_point_)
283 << EI_ClosestEle(min_observe_point_data));
287 double dist = arma::norm(elm.
centre() - input_point_, 2);
289 if (dist > 2*elm_norm)
290 WarningOut().fmt(
"Observe point ({}) is too distant from the mesh.\n", name_);
298 out << setw(indent_spaces) <<
"" <<
"- name: " << name_ << endl;
299 out << setw(indent_spaces) <<
"" <<
" init_point: " <<
field_value_to_yaml(input_point_, precision) << endl;
300 out << setw(indent_spaces) <<
"" <<
" snap_dim: " << snap_dim_ << endl;
301 out << setw(indent_spaces) <<
"" <<
" snap_region: " << snap_region_name_ << endl;
302 out << setw(indent_spaces) <<
"" <<
" observe_point: " <<
field_value_to_yaml(observe_data_.global_coords_, precision) << endl;
312 return ph.
projection(input_point_, i_elm, elm);
318 return ph.
projection(input_point_, i_elm, elm);
324 return ph.
projection(input_point_, i_elm, elm);
328 ASSERT(
false).error(
"Invalid element dimension!");
345 : observe_name_(observe_name),
346 precision_(precision),
353 unsigned int global_point_idx=0, local_point_idx=0;
359 point.observe_data_.global_idx_ = global_point_idx++;
360 if (point.observe_data_.proc_ == mesh.
get_el_ds()->
myp()) {
361 point.observe_data_.local_idx_ = local_point_idx++;
362 point_4_loc_.push_back(point.observe_data_.global_idx_);
365 point.observe_data_.local_idx_ = -1;
380 if (
points_.size() == 0)
return;
389 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, in_array)
400 template <
typename T>
413 = std::make_shared< ElementDataCache<T> >(field_name, n_rows * n_cols,
point_ds_->
lsize());
420 #define OBSERVE_PREPARE_COMPUTE_DATA(TYPE) \ 421 template ElementDataCache<TYPE> & Observe::prepare_compute_data<TYPE>(std::string field_name, double field_time, \ 422 unsigned int n_rows, unsigned int n_cols) 430 unsigned int indent = 2;
442 if (
points_.size() == 0)
return;
466 auto serial_data = field_data.second->gather(
point_ds_, &(local_to_global[0]));
467 if (
rank_==0) field_data.second = serial_data;
471 unsigned int indent = 2;
474 for(
auto &field_data : observe_field_values_) {
475 observe_file_ << setw(indent) <<
"" <<
" " << field_data.second->field_input_name() <<
": ";
485 observe_time_idx_ = 0;
ObservePointData point_projection(unsigned int i_elm, ElementAccessor< 3 > elm)
Project point to given element by dimension of this element.
std::vector< ObservePoint > points_
Full information about observe points.
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Bounding box in 3d ambient space.
#define OBSERVE_PREPARE_COMPUTE_DATA(TYPE)
OutputDataFieldMap observe_field_values_
Stored field values.
unsigned int n_nodes() const
Observe(string observe_name, Mesh &mesh, Input::Array in_array, unsigned int precision, std::string unit_str)
vector< vector< unsigned int > > const & node_elements()
std::ofstream observe_file_
Output file stream.
RegionSet get_region_set(const std::string &set_name) const
NodeAccessor< 3 > node_accessor(unsigned int ni) const
unsigned int proc_
Actual process of the observe point.
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
std::vector< LongIdx > point_4_loc_
Index set assigning to local point index its global index.
ProjectionHandler()
Constructor.
double convert_unit_from(std::string actual_unit) const
Convert and check user-defined unit.
static const Input::Type::Record & get_input_type()
void output_time_frame(double time, bool flush)
bool have_observe_element()
double global_snap_radius() const
Maximal distance of observe point from Mesh relative to its size.
void output(ostream &out, unsigned int indent_spaces, unsigned int precision)
static const unsigned int max_observe_value_time
Maximal size of observe values times vector.
#define ASSERT_LE(a, b)
Definition of comparative assert macro (Less or Equal)
unsigned int element_idx_
Final element of the observe point. The index in the mesh.
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 local_coords_
Local (barycentric) coordinates on the element.
unsigned int proc() const
virtual ElementAccessor< 3 > element_accessor(unsigned int idx) const
Create and return ElementAccessor to element of given idx.
arma::vec::fixed< spacedim > centre() const
Computes the barycenter.
void open_stream(Stream &stream) const
Global macros to enhance readability and debugging, general constants.
arma::vec3 global_coords_
Global coordinates of the observation point.
unsigned int precision_
Precision of float output.
void find_observe_point(Mesh &mesh)
bool operator()(const ObservePointData &lhs, const ObservePointData &rhs) const
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.
BoundingBox bounding_box() const
void snap_to_subelement(ObservePointData &observe_data, ElementAccessor< 3 > elm, unsigned int snap_dim)
Range< ObservePointAccessor > local_range() const
Returns local range of observe points.
ElementDataCache< T > & prepare_compute_data(std::string field_name, double field_time, unsigned int n_rows, unsigned int n_cols)
Distribution * get_el_ds() const
ObservePointData projection(arma::vec3 input_point, unsigned int i_elm, ElementAccessor< 3 > elm)
const BIHTree & get_bih_tree()
Getter for BIH. Creates and compute BIH at first call.
Dedicated class for storing path to input and output files.
unsigned int myp() const
get my processor
friend class ObservePointAccessor
void find_point(const Space< 3 >::Point &point, std::vector< unsigned int > &result_list, bool full_list=false) const
double time_unit_seconds_
Time unit in seconds.
std::vector< double > observe_values_time_
Common evaluation time of the fields for single time frame.
bool is_in_region_set(const RegionSet &set) const
MappingP1< dim, 3 > mapping_
Mapping object.
Point project_point(const Point &point) const
#define WarningOut()
Macro defining 'warning' record of log.
static BaryPoint local_to_bary(const LocalPoint &lp)
Converts from local to barycentric coordinates.
unsigned int observe_time_idx_
Index of actual (last) time in observe_values_time_ vector.
const Point & min() const
Distribution * point_ds_
Parallel distribution of observe points.
Class for representation SI units of Fields.
BaryPoint clip_to_element(BaryPoint &barycentric)
ElementMap element_map(ElementAccessor< 3 > elm) const
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
~Observe()
Destructor, must close the file.
unsigned int lsize(int proc) const
get local size