Flow123d  release_2.1.0-87-gfbc1563
field_interpolated_p0.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file field_interpolated_p0.cc
15  * @brief
16  */
17 
18 
19 #include "field_interpolated_p0.hh"
20 #include "fields/field_instances.hh" // for instantiation macros
21 #include "system/system.hh"
22 #include "mesh/msh_gmshreader.h"
23 #include "mesh/bih_tree.hh"
24 #include "mesh/reader_instances.hh"
26 #include "mesh/ngh/include/point.h"
27 #include "system/sys_profiler.hh"
28 
29 
30 namespace it = Input::Type;
31 
32 FLOW123D_FORCE_LINK_IN_CHILD(field_interpolated)
33 
34 
35 
36 template <int spacedim, class Value>
37 const Input::Type::Record & FieldInterpolatedP0<spacedim, Value>::get_input_type()
38 {
39  return it::Record("FieldInterpolatedP0", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
43  "Input file with ASCII GMSH file format.")
45  "The values of the Field are read from the ```$ElementData``` section with field name given by this key.")
46  //.declare_key("unit", FieldAlgorithmBase<spacedim, Value>::get_input_type_unit_si(), it::Default::optional(),
47  // "Definition of unit.")
48  .close();
49 }
50 
51 
52 
53 template <int spacedim, class Value>
55  Input::register_class< FieldInterpolatedP0<spacedim, Value>, unsigned int >("FieldInterpolatedP0") +
57 
58 
59 template <int spacedim, class Value>
61 : FieldAlgorithmBase<spacedim, Value>(n_comp)
62 {}
63 
64 
65 
66 template <int spacedim, class Value>
68  this->init_unit_conversion_coefficient(rec, init_data);
69 
70 
71  // read mesh, create tree
72  {
73  source_mesh_ = new Mesh( Input::Record() );
74  reader_file_ = FilePath( rec.val<FilePath>("gmsh_file") );
76  // no call to mesh->setup_topology, we need only elements, no connectivity
77  }
79 
80  // allocate data_
81  unsigned int data_size = source_mesh_->element.size() * (this->value_.n_rows() * this->value_.n_cols());
82  data_ = std::make_shared<std::vector<typename Value::element_type>>();
83  data_->resize(data_size);
84 
85  field_name_ = rec.val<std::string>("field_name");
86 }
87 
88 
89 
90 
91 template <int spacedim, class Value>
93  OLD_ASSERT(source_mesh_, "Null mesh pointer of elementwise field: %s, did you call init_from_input(Input::Record)?\n", field_name_.c_str());
94  if ( reader_file_ == FilePath() ) return false;
95 
96  //walkaround for the steady time governor - there is no data to be read in time==infinity
97  //TODO: is it possible to check this before calling set_time?
98  //if (time == numeric_limits< double >::infinity()) return false;
99 
100  // value of last computed element must be recalculated if time is changed
101  computed_elm_idx_ = numeric_limits<unsigned int>::max();
102 
103  GMSH_DataHeader search_header;
104  search_header.actual = false;
105  search_header.field_name = field_name_;
106  search_header.n_components = this->value_.n_rows() * this->value_.n_cols();
107  search_header.n_entities = source_mesh_->element.size();
108  search_header.time = time.end();
109 
110  bool boundary_domain_ = false;
111  data_ = ReaderInstances::instance()->get_reader(reader_file_)->template get_element_data<typename Value::element_type>(search_header,
112  source_mesh_->elements_id_maps(boundary_domain_), this->component_idx_);
113  this->scale_data();
114 
115  return search_header.actual;
116 }
117 
118 
119 
120 template <int spacedim, class Value>
121 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
122 {
123  OLD_ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
124  if (elm.idx() != computed_elm_idx_ || elm.is_boundary() != computed_elm_boundary_) {
125  computed_elm_idx_ = elm.idx();
127 
128  if (elm.dim() == 3) {
129  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
130  }
131 
132  double epsilon = 4* numeric_limits<double>::epsilon() * elm.element()->measure();
133 
134  // gets suspect elements
135  if (elm.dim() == 0) {
136  searched_elements_.clear();
137  ((BIHTree *)bih_tree_)->find_point(elm.element()->node[0]->point(), searched_elements_);
138  } else {
139  BoundingBox bb;
140  elm.element()->get_bounding_box(bb);
141  searched_elements_.clear();
142  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
143  }
144 
145  // set zero values of value_ object
146  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
147  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
148  this->value_(i,j) = 0.0;
149  }
150  }
151 
152  double total_measure=0.0, measure;
153  TIntersectionType iType;
154 
155  START_TIMER("compute_pressure");
158  {
160  if (ele->dim() == 3) {
162  // get intersection (set measure = 0 if intersection doesn't exist)
163  switch (elm.dim()) {
164  case 0: {
166  if ( tetrahedron_.IsInner(point_) ) {
167  measure = 1.0;
168  } else {
169  measure = 0.0;
170  }
171  break;
172  }
173  case 1: {
175  GetIntersection(abscissa_, tetrahedron_, iType, measure);
176  if (iType != line) {
177  measure = 0.0;
178  }
179  break;
180  }
181  case 2: {
183  GetIntersection(triangle_, tetrahedron_, iType, measure);
184  if (iType != area) {
185  measure = 0.0;
186  }
187  break;
188  }
189  }
190 
191 
192 
193  //adds values to value_ object if intersection exists
194  if (measure > epsilon) {
195  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
197  typename Value::return_type & ret_type_value = const_cast<typename Value::return_type &>( Value::from_raw(this->r_value_, (typename Value::element_type *)(&vec[index])) );
198  Value tmp_value = Value( ret_type_value );
199 
200  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
201  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
202  this->value_(i,j) += tmp_value(i,j) * measure;
203  }
204  }
205  total_measure += measure;
206  }
207  }
208  }
209 
210  // computes weighted average
211  if (total_measure > epsilon) {
212  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
213  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
214  this->value_(i,j) /= total_measure;
215  }
216  }
217  } else {
218  WarningOut().fmt("Processed element with idx {} is out of source mesh!\n", elm.idx());
219  }
220  END_TIMER("compute_pressure");
221 
222  }
223  return this->r_value_;
224 }
225 
226 
227 
228 template <int spacedim, class Value>
231 {
232  OLD_ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
233  FieldAlgorithmBase<spacedim, Value>::value_list(point_list, elm, value_list);
234 }
235 
236 
237 
238 template <int spacedim, class Value>
240 {
241  if (Value::is_scalable()) {
243  for(unsigned int i=0; i<vec.size(); ++i)
244  vec[i] *= this->unit_conversion_coefficient_;
245  }
246 }
247 
248 
249 
250 // Instantiations of FieldInterpolatedP0
unsigned int computed_elm_boundary_
stored flag if last computed element is boundary
std::string field_name
void init_unit_conversion_coefficient(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Init value of unit_conversion_coefficient_ from input.
const Element * element() const
Definition: accessors.hh:86
Bounding box in 3d ambient space.
Definition: bounding_box.hh:45
double measure() const
Definition: elements.cc:89
bool set_time(const TimeStep &time) override
void set_point_from_element(TPoint &p, const Element *ele)
unsigned int component_idx_
Specify if the field is part of a MultiField and which component it is.
bool is_boundary() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:109
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)=0
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:105
FilePath reader_file_
mesh reader file
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
#define INSTANCE_ALL(field)
Definition: mesh.h:95
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Node ** node
Definition: elements.h:79
unsigned int computed_elm_idx_
stored index to last computed element
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
TAbscissa abscissa_
1D (abscissa) element, used for computing intersection
TPoint point_
0D (point) element, used for computing intersection
Value::return_type r_value_
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:301
void set_tetrahedron_from_element(TTetrahedron &te, Element *ele)
double unit_conversion_coefficient_
Coeficient of conversion of user-defined unit.
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:193
unsigned int size() const
Returns size of the container. This is independent of the allocated space.
Definition: sys_vector.hh:391
#define OLD_ASSERT(...)
Definition: global_defs.h:131
unsigned int n_entities
Number of rows.
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
bool is_elemental() const
Definition: accessors.hh:75
Mesh * source_mesh_
mesh, which is interpolated
vector< int > const & elements_id_maps(bool boundary_domain) const
Definition: mesh.cc:709
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:501
Accessor to the data with type Type::Record.
Definition: accessors.hh:286
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:87
FieldInterpolatedP0(unsigned int n_comp=0)
#define START_TIMER(tag)
Starts a timer with specified tag.
void set_abscissa_from_element(TAbscissa &ab, const Element *ele)
Class for O(log N) lookup for intersections with a set of bounding boxes.
Definition: bih_tree.hh:36
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:488
void get_bounding_box(BoundingBox &bounding_box) const
Definition: elements.cc:196
enum Intersections TIntersectionType
double end() const
Space< spacedim >::Point Point
unsigned int n_components
Number of values on one row.
BIHTree * bih_tree_
tree of mesh elements
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:213
Dedicated class for storing path to input and output files.
Definition: file_path.hh:48
const double epsilon
Definition: mathfce.h:23
Value value_
Last value, prevents passing large values (vectors) by value.
std::vector< unsigned int > searched_elements_
vector stored suspect elements in calculating the intersection
void scale_data()
Multiply data_ with unit_conversion_coefficient_.
void set_triangle_from_element(TTriangle &tr, const Element *ele)
TTriangle triangle_
2D (triangle) element, used for computing intersection
std::shared_ptr< GmshMeshReader > get_reader(const FilePath &file_path)
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:234
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: system.hh:59
TTetrahedron tetrahedron_
3D (tetrahedron) element, used for computing intersection
Record type proxy class.
Definition: type_record.hh:177
unsigned int dim() const
Definition: accessors.hh:83
std::string field_name_
field name read from input
arma::vec3 & point()
Definition: nodes.hh:68
static ReaderInstances * instance()
Returns singleton instance.
unsigned int idx() const
Definition: accessors.hh:113
std::shared_ptr< std::vector< typename Value::element_type > > data_
Raw buffer of n_entities rows each containing Value::size() doubles.
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
void GetIntersection(const TBisector &, const TBisector &, TPosition &, double &, double &)
Representation of one time step..
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
bool IsInner(const TPoint &) const
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:216