12 #include <unordered_set> 38 template<
unsigned int dim>
64 if (snap_dim <= dim) {
65 double min_dist = 2.0;
69 double dist = arma::norm(center - observe_data.
local_coords_, 2);
70 if ( dist < min_dist) {
109 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" 110 "1. Find an initial element containing the initial point. If no such element exists we report the error.\n" 111 "2. Use BFS starting from the inital element to find the 'observe element'. The observe element is the closest element " 112 "3. Find the closest projection of the inital point on the observe element and snap this projection according to the 'snap_dim'.\n")
116 "Default name have the form 'obs_<id>', where 'id' " 117 "is the rank of the point on the input."),
118 "Optional point name. Has to be unique. Any string that is valid YAML key in record without any quoting can be used however" 119 "using just alpha-numerical characters and underscore instead of the space is recommended. " 122 "Initial point for the observe point search.")
124 "The dimension of the sub-element to which center we snap. For value 4 no snapping is done. " 125 "For values 0 up to 3 the element containing the initial point is found and then the observe" 126 "point is snapped to the nearest center of the sub-element of the given dimension. " 127 "E.g. for dimension 2 we snap to the nearest center of the face of the initial element." 130 "The region of the initial element for snapping. Without snapping we make a projection to the initial element.")
132 IT::Default::read_time(
"Maximal distance of observe point from Mesh relative to its size (bounding box). "),
133 "Global value is define in Mesh by the key global_observe_search_radius.")
145 string default_label = string(
"obs_") +
std::to_string(point_idx);
146 name_ = in_rec.
val<
string>(
"name", default_label );
150 input_point_= arma::vec(tmp_coords);
152 snap_dim_ = in_rec.
val<
unsigned int>(
"snap_dim");
154 snap_region_name_ = in_rec.
val<
string>(
"snap_region");
157 double max_mesh_size = arma::max(main_box.max() - main_box.min());
158 max_search_radius_ = in_rec_.val<
double>(
"search_radius", mesh.
global_observe_radius()) * max_mesh_size;
164 return observe_data_.distance_ < numeric_limits<double>::infinity();
191 default:
ASSERT(
false).error(
"Clipping supported only for dim=1,2,3.");
199 if (region_set.size() == 0)
200 THROW( RegionDB::ExcUnknownSet() << RegionDB::EI_Label(snap_region_name_) << in_rec_.ei_address() );
205 std::unordered_set<unsigned int> closed_elements(1023);
206 std::priority_queue< ObservePointData, std::vector<ObservePointData>,
CompareByDist > candidate_queue;
209 bih_tree.
find_point(input_point_, candidate_list,
true);
211 for (
unsigned int i_candidate=0; i_candidate<candidate_list.size(); ++i_candidate) {
212 unsigned int i_elm=candidate_list[i_candidate];
216 auto observe_data = point_projection(i_elm, elm);
217 if (observe_data.distance_ <= max_search_radius_)
218 candidate_queue.push(observe_data);
219 closed_elements.insert(i_elm);
222 while (!candidate_queue.empty())
224 auto candidate_data = candidate_queue.top();
225 candidate_queue.pop();
227 unsigned int i_elm=candidate_data.element_idx_;
232 ASSERT_LE(candidate_data.distance_, observe_data_.distance_).error();
234 observe_data_.distance_ = candidate_data.distance_;
235 observe_data_.element_idx_ = candidate_data.element_idx_;
236 observe_data_.local_coords_ = candidate_data.local_coords_;
237 observe_data_.global_coords_ = candidate_data.global_coords_;
242 for (
unsigned int n=0; n < elm.
n_nodes(); n++)
244 if (closed_elements.find(i_node_ele) == closed_elements.end()) {
246 auto observe_data = point_projection(i_node_ele, neighbor_elm);
247 if (observe_data.distance_ <= max_search_radius_)
248 candidate_queue.push(observe_data);
249 closed_elements.insert(i_node_ele);
254 if (! have_observe_element()) {
255 THROW(ExcNoObserveElement() << EI_RegionName(snap_region_name_) );
264 out << setw(indent_spaces) <<
"" <<
"- name: " << name_ << endl;
265 out << setw(indent_spaces) <<
"" <<
" init_point: " <<
field_value_to_yaml(input_point_) << endl;
266 out << setw(indent_spaces) <<
"" <<
" snap_dim: " << snap_dim_ << endl;
267 out << setw(indent_spaces) <<
"" <<
" snap_region: " << snap_region_name_ << endl;
268 out << setw(indent_spaces) <<
"" <<
" observe_point: " <<
field_value_to_yaml(observe_data_.global_coords_, precision) << endl;
278 return ph.
projection(input_point_, i_elm, elm);
284 return ph.
projection(input_point_, i_elm, elm);
290 return ph.
projection(input_point_, i_elm, elm);
294 ASSERT(
false).error(
"Invalid element dimension!");
309 observe_values_time_(numeric_limits<double>::signaling_NaN()),
310 observe_name_(observe_name),
311 precision_(precision)
329 if (
points_.size() == 0)
return;
335 }
INPUT_CATCH(FilePath::ExcFileOpen, FilePath::EI_Address_String, in_array)
345 template<
int spacedim,
class Value>
348 if (
points_.size() == 0)
return;
351 double field_time = field.
time();
365 unsigned int i_data=0;
367 unsigned int ele_index = o_point.observe_data_.element_idx_;
368 const Value &obs_value =
369 Value( const_cast<typename Value::return_type &>(
370 field.
value(o_point.observe_data_.global_coords_,
379 #define INSTANCE_DIM(dim) \ 380 template void Observe::compute_field_values(Field<dim, FieldValue<0>::Enum> &); \ 381 template void Observe::compute_field_values(Field<dim, FieldValue<0>::Integer> &); \ 382 template void Observe::compute_field_values(Field<dim, FieldValue<0>::Scalar> &); \ 383 template void Observe::compute_field_values(Field<dim, FieldValue<dim>::VectorFixed> &); \ 384 template void Observe::compute_field_values(Field<dim, FieldValue<dim>::TensorFixed> &); 392 unsigned int indent = 2;
404 if (
points_.size() == 0)
return;
422 unsigned int indent = 2;
425 observe_file_ << setw(indent) <<
"" <<
" " << field_data.second->field_name <<
": ";
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.
OutputDataFieldMap observe_field_values_
Stored field values.
unsigned int n_nodes() const
std::ofstream observe_file_
Output file stream.
vector< vector< unsigned int > > node_elements
ProjectionHandler()
Constructor.
Class template representing a field with values dependent on: point, element, and region...
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)
#define ASSERT_LE(a, b)
Definition of comparative assert macro (Less or Equal)
void snap_to_subelement(ObservePointData &observe_data, Element &elm, unsigned int snap_dim)
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...
This class is used for storing data that are copied from field.
std::string to_string(const T &value)
std::string observe_name_
ObservePointData point_projection(unsigned int i_elm, Element &elm)
Project point to given element by dimension of this element.
arma::vec local_coords_
Local (barycentric) coordinates on the element.
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)
ObservePointData projection(arma::vec3 input_point, unsigned int i_elm, Element &elm)
bool operator()(const ObservePointData &lhs, const ObservePointData &rhs) const
const BoundingBox & tree_box() const
arma::vec::fixed< dim+1 > clip_to_element(arma::vec::fixed< dim+1 > &barycentric)
std::vector< unsigned int > observed_element_indices_
Elements of the o_points.
Class for O(log N) lookup for intersections with a set of bounding boxes.
unsigned int index(const T *pointer) const
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
double observe_values_time_
Common evaluation time of the fields for single time frame.
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.
void compute_field_values(Field< spacedim, Value > &field)
arma::mat::fixed< 3, dim+1 > element_map(Element &elm) const
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.
bool is_in_region_set(const RegionSet &set) const
MappingP1< dim, 3 > mapping_
Mapping object.
#define WarningOut()
Macro defining 'warning' record of log.
FieldCommon & name(const string &name)
#define INSTANCE_DIM(dim)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
~Observe()
Destructor, must close the file.
arma::vec::fixed< dim+1 > project_point(const arma::vec3 &point, const arma::mat::fixed< 3, dim+1 > &map) const
NodeVector node_vector
Vector of nodes of the mesh.
double global_observe_radius() const
Maximal distance of observe point from Mesh relative to its size.
void store_value(unsigned int idx, const Value &value)
void output_time_frame(double time)
ElementVector element
Vector of elements of the mesh.