Flow123d  jenkins-Flow123d-linux-release-multijob-282
field_interpolated_p0.impl.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id: function_interpolated_p0.cc 1567 2012-02-28 13:24:58Z jan.brezina $
21  * $Revision: 1567 $
22  * $LastChangedBy: jan.brezina $
23  * $LastChangedDate: 2012-02-28 14:24:58 +0100 (Tue, 28 Feb 2012) $
24  *
25  *
26  */
27 
28 
29 #ifndef FIELD_INTERPOLATED_P0_IMPL_HH_
30 #define FIELD_INTERPOLATED_P0_IMPL_HH_
31 
32 #include "field_interpolated_p0.hh"
33 #include "system/system.hh"
34 #include "mesh/msh_gmshreader.h"
35 #include "mesh/bih_tree.hh"
36 #include "mesh/reader_instances.hh"
38 #include "mesh/ngh/include/point.h"
39 #include "system/sys_profiler.hh"
40 
41 
42 namespace it = Input::Type;
43 
44 
45 
46 template <int spacedim, class Value>
49 
50 
51 
52 template <int spacedim, class Value>
54  Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit
55  )
56 {
57  it::Record type=
58  it::Record("FieldInterpolatedP0", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
59  .derive_from(a_type)
61  "Input file with ASCII GMSH file format.")
63  "The values of the Field are read from the \\$ElementData section with field name given by this key.")
64  .close();
65 
66  return type;
67 }
68 
69 
70 
71 template <int spacedim, class Value>
73 : FieldAlgorithmBase<spacedim, Value>(n_comp)
74 {}
75 
76 
77 
78 template <int spacedim, class Value>
80 
81  // read mesh, create tree
82  {
83  source_mesh_ = new Mesh();
84  reader_file_ = FilePath( rec.val<FilePath>("gmsh_file") );
85  ReaderInstances::instance()->get_reader(reader_file_)->read_mesh( source_mesh_ );
86  // no call to mesh->setup_topology, we need only elements, no connectivity
87  }
88  bih_tree_ = new BIHTree( source_mesh_ );
89 
90  // allocate data_
91  unsigned int data_size = source_mesh_->element.size() * (this->value_.n_rows() * this->value_.n_cols());
92  data_ = std::make_shared<std::vector<typename Value::element_type>>();
93  data_->resize(data_size);
94 
95  field_name_ = rec.val<std::string>("field_name");
96 }
97 
98 
99 
100 
101 template <int spacedim, class Value>
103  ASSERT(source_mesh_, "Null mesh pointer of elementwise field: %s, did you call init_from_input(Input::Record)?\n", field_name_.c_str());
104  if ( reader_file_ == FilePath() ) return false;
105 
106  //walkaround for the steady time governor - there is no data to be read in time==infinity
107  //TODO: is it possible to check this before calling set_time?
108  //if (time == numeric_limits< double >::infinity()) return false;
109 
110  // value of last computed element must be recalculated if time is changed
111  computed_elm_idx_ = numeric_limits<unsigned int>::max();
112 
113  GMSH_DataHeader search_header;
114  search_header.actual = false;
115  search_header.field_name = field_name_;
116  search_header.n_components = this->value_.n_rows() * this->value_.n_cols();
117  search_header.n_entities = source_mesh_->element.size();
118  search_header.time = time.end();
119 
120  bool boundary_domain_ = false;
121  data_ = ReaderInstances::instance()->get_reader(reader_file_)->get_element_data<typename Value::element_type>(search_header,
122  source_mesh_->elements_id_maps(boundary_domain_), this->component_idx_);
123 
124  return search_header.actual;
125 }
126 
127 
128 
129 template <int spacedim, class Value>
130 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
131 {
132  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
133  if (elm.idx() != computed_elm_idx_ || elm.is_boundary() != computed_elm_boundary_) {
134  computed_elm_idx_ = elm.idx();
135  computed_elm_boundary_ = elm.is_boundary();
136 
137  if (elm.dim() == 3) {
138  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
139  }
140 
141  double epsilon = 4* numeric_limits<double>::epsilon() * elm.element()->measure();
142 
143  // gets suspect elements
144  if (elm.dim() == 0) {
145  searched_elements_.clear();
146  ((BIHTree *)bih_tree_)->find_point(elm.element()->node[0]->point(), searched_elements_);
147  } else {
148  BoundingBox bb;
149  elm.element()->get_bounding_box(bb);
150  searched_elements_.clear();
151  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
152  }
153 
154  // set zero values of value_ object
155  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
156  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
157  this->value_(i,j) = 0.0;
158  }
159  }
160 
161  double total_measure=0.0, measure;
162  TIntersectionType iType;
163 
164  START_TIMER("compute_pressure");
165  ADD_CALLS(searched_elements_.size());
166  for (std::vector<unsigned int>::iterator it = searched_elements_.begin(); it!=searched_elements_.end(); it++)
167  {
168  ElementFullIter ele = source_mesh_->element( *it );
169  if (ele->dim() == 3) {
170  ngh::set_tetrahedron_from_element(tetrahedron_, ele);
171  // get intersection (set measure = 0 if intersection doesn't exist)
172  switch (elm.dim()) {
173  case 0: {
174  ngh::set_point_from_element(point_, elm.element());
175  if ( tetrahedron_.IsInner(point_) ) {
176  measure = 1.0;
177  } else {
178  measure = 0.0;
179  }
180  break;
181  }
182  case 1: {
183  ngh::set_abscissa_from_element(abscissa_, elm.element());
184  GetIntersection(abscissa_, tetrahedron_, iType, measure);
185  if (iType != line) {
186  measure = 0.0;
187  }
188  break;
189  }
190  case 2: {
191  ngh::set_triangle_from_element(triangle_, elm.element());
192  GetIntersection(triangle_, tetrahedron_, iType, measure);
193  if (iType != area) {
194  measure = 0.0;
195  }
196  break;
197  }
198  }
199 
200 
201 
202  //adds values to value_ object if intersection exists
203  if (measure > epsilon) {
204  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
205  std::vector<typename Value::element_type> &vec = *( data_.get() );
206  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])) );
207  Value tmp_value = Value( ret_type_value );
208 
209  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
210  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
211  this->value_(i,j) += tmp_value(i,j) * measure;
212  }
213  }
214  total_measure += measure;
215  }
216  } else {
217  xprintf(Err, "Dimension of element in source mesh must be 3!\n");
218  }
219  }
220 
221  // computes weighted average
222  if (total_measure > epsilon) {
223  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
224  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
225  this->value_(i,j) /= total_measure;
226  }
227  }
228  } else {
229  xprintf(Warn, "Processed element with idx %d is out of source mesh!\n", elm.idx());
230  }
231  END_TIMER("compute_pressure");
232 
233  }
234  return this->r_value_;
235 }
236 
237 
238 
239 template <int spacedim, class Value>
242 {
243  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
244  FieldAlgorithmBase<spacedim, Value>::value_list(point_list, elm, value_list);
245 }
246 
247 
248 
249 
250 
251 #endif /* FIELD_INTERPOLATED_P0_IMPL_HH_ */
std::string field_name
const Element * element() const
Definition: accessors.hh:76
Bounding box in 3d ambient space.
Definition: bounding_box.hh:55
double measure() const
Definition: elements.cc:101
bool set_time(const TimeStep &time) override
void set_point_from_element(TPoint &p, const Element *ele)
static Input::Type::Record get_input_type(Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit)
bool is_boundary() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:99
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()
Definition: type_record.hh:89
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: mesh.h:109
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
Node ** node
Definition: elements.h:90
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
void set_tetrahedron_from_element(TTetrahedron &te, Element *ele)
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:65
#define ASSERT(...)
Definition: global_defs.h:121
Definition: system.hh:72
static FileName input()
Definition: type_base.hh:464
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:100
FieldInterpolatedP0(unsigned int n_comp=0)
#define START_TIMER(tag)
Starts a timer with specified tag.
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
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:46
void get_bounding_box(BoundingBox &bounding_box) const
Definition: elements.cc:208
const Record & close() const
Definition: type_record.cc:314
enum Intersections TIntersectionType
double end() const
Space< spacedim >::Point Point
unsigned int n_components
Number of values on one row.
Dedicated class for storing path to input and output files.
Definition: file_path.hh:32
const double epsilon
Definition: mathfce.h:6
virtual void init_from_input(const Input::Record &rec)
void set_triangle_from_element(TTriangle &tr, const Element *ele)
std::shared_ptr< GmshMeshReader > get_reader(const FilePath &file_path)
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: system.hh:72
Record type proxy class.
Definition: type_record.hh:169
unsigned int dim() const
Definition: accessors.hh:73
arma::vec3 & point()
Definition: nodes.hh:80
static ReaderInstances * instance()
Returns singleton instance.
unsigned int idx() const
Definition: accessors.hh:103
void GetIntersection(const TBisector &, const TBisector &, TPosition &, double &, double &)
Representation of one time step.
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430