Flow123d  jenkins-Flow123d-windows32-release-multijob-28
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"
37 #include "mesh/ngh/include/point.h"
38 #include "system/sys_profiler.hh"
39 //#include "boost/lexical_cast.hpp"
40 //#include "system/tokenizer.hh"
41 //#include "system/xio.h"
42 
43 
44 namespace it = Input::Type;
45 
46 
47 
48 template <int spacedim, class Value>
51 
52 
53 
54 template <int spacedim, class Value>
56  Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit
57  )
58 {
59  it::Record type=
60  it::Record("FieldInterpolatedP0", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
61  .derive_from(a_type)
63  "Input file with ASCII GMSH file format.")
65  "The values of the Field are read from the $ElementData section with field name given by this key.")
66  .close();
67 
68  return type;
69 }
70 
71 
72 
73 template <int spacedim, class Value>
75 : FieldAlgorithmBase<spacedim, Value>(n_comp)
76 {}
77 
78 
79 
80 template <int spacedim, class Value>
82 
83  // read mesh, create tree
84  {
85  source_mesh_ = new Mesh();
86  reader_ = new GmshMeshReader( rec.val<FilePath>("gmsh_file") );
87  reader_->read_mesh( source_mesh_ );
88  // no call to mesh->setup_topology, we need only elements, no connectivity
89  }
90  bih_tree_ = new BIHTree( source_mesh_ );
91 
92  // allocate data_
93  unsigned int data_size = source_mesh_->element.size() * (this->value_.n_rows() * this->value_.n_cols());
94  data_ = new double[data_size];
95  std::fill(data_, data_ + data_size, 0.0);
96 
97  field_name_ = rec.val<std::string>("field_name");
98 }
99 
100 
101 
102 
103 template <int spacedim, class Value>
105  ASSERT(source_mesh_, "Null mesh pointer of elementwise field: %s, did you call init_from_input(Input::Record)?\n", field_name_.c_str());
106  ASSERT(data_, "Null data pointer.\n");
107  if (reader_ == NULL) return false;
108 
109  //walkaround for the steady time governor - there is no data to be read in time==infinity
110  //TODO: is it possible to check this before calling set_time?
111  if (time == numeric_limits< double >::infinity()) return false;
112 
113  // value of last computed element must be recalculated if time is changed
114  computed_elm_idx_ = numeric_limits<unsigned int>::max();
115 
116  GMSH_DataHeader search_header;
117  search_header.actual = false;
118  search_header.field_name = field_name_;
119  search_header.n_components = this->value_.n_rows() * this->value_.n_cols();
120  search_header.n_entities = source_mesh_->element.size();
121  search_header.time = time;
122 
123  bool boundary_domain_ = false;
124  //DBGMSG("reading data for interpolation: name: %s \t time: %f \t n: %d\n", field_name_.c_str(), time, source_mesh_->element.size());
125  reader_->read_element_data(search_header, data_, source_mesh_->elements_id_maps(boundary_domain_) );
126  //DBGMSG("end of reading data for interpolation: %s\n", field_name_.c_str());
127 
128  return search_header.actual;
129 }
130 
131 
132 
133 template <int spacedim, class Value>
134 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
135 {
136  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
137  if (elm.idx() != computed_elm_idx_ || elm.is_boundary() != computed_elm_boundary_) {
138  computed_elm_idx_ = elm.idx();
139  computed_elm_boundary_ = elm.is_boundary();
140 
141  if (elm.dim() == 3) {
142  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
143  }
144 
145  double epsilon = 4* numeric_limits<double>::epsilon() * elm.element()->measure();
146 
147  // gets suspect elements
148  if (elm.dim() == 0) {
149  //Point point;
150  //for (unsigned int i=0; i<3; i++) point(i) = elm.element()->node[0]->point()(i);
151  searched_elements_.clear();
152  ((BIHTree *)bih_tree_)->find_point(elm.element()->node[0]->point(), searched_elements_);
153  } else {
154  BoundingBox bb;
155  elm.element()->get_bounding_box(bb);
156  searched_elements_.clear();
157  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
158  }
159 
160  // set zero values of value_ object
161  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
162  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
163  this->value_(i,j) = 0.0;
164  }
165  }
166 
167  double total_measure=0.0, measure;
168  TIntersectionType iType;
169 
170  START_TIMER("compute_pressure");
171  ADD_CALLS(searched_elements_.size());
172  for (std::vector<unsigned int>::iterator it = searched_elements_.begin(); it!=searched_elements_.end(); it++)
173  {
174  ElementFullIter ele = source_mesh_->element( *it );
175  if (ele->dim() == 3) {
176  ngh::set_tetrahedron_from_element(tetrahedron_, ele);
177  // get intersection (set measure = 0 if intersection doesn't exist)
178  switch (elm.dim()) {
179  case 0: {
180  ngh::set_point_from_element(point_, elm.element());
181  if ( tetrahedron_.IsInner(point_) ) {
182  measure = 1.0;
183  } else {
184  measure = 0.0;
185  }
186  break;
187  }
188  case 1: {
189  ngh::set_abscissa_from_element(abscissa_, elm.element());
190  GetIntersection(abscissa_, tetrahedron_, iType, measure);
191  if (iType != line) {
192  measure = 0.0;
193  }
194  break;
195  }
196  case 2: {
197  ngh::set_triangle_from_element(triangle_, elm.element());
198  GetIntersection(triangle_, tetrahedron_, iType, measure);
199  if (iType != area) {
200  measure = 0.0;
201  }
202  break;
203  }
204  }
205 
206 
207 
208  //adds values to value_ object if intersection exists
209  if (measure > epsilon) {
210  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
211  typename Value::element_type * ele_data_ptr = (typename Value::element_type *)(data_+index);
212  typename Value::return_type & ret_type_value = const_cast<typename Value::return_type &>( Value::from_raw(this->r_value_, ele_data_ptr) );
213  Value tmp_value = Value( ret_type_value );
214 
215  /*cout << "n_rows, n_cols = " << tmp_value.n_rows() << ", " << tmp_value.n_cols() << endl;
216  for (unsigned int i=0; i < tmp_value.n_rows(); i++) {
217  for (unsigned int j=0; j < tmp_value.n_cols(); j++) {
218  cout << "(" << i << "," << j << ") = " << tmp_value(i,j) << ", ";
219  }
220  cout << endl;
221  }
222  cout << endl;*/
223 
224  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
225  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
226  this->value_(i,j) += tmp_value(i,j) * measure;
227  }
228  }
229  total_measure += measure;
230  }
231  } else {
232  xprintf(Err, "Dimension of element in source mesh must be 3!\n");
233  }
234  }
235 
236  // computes weighted average
237  if (total_measure > epsilon) {
238  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
239  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
240  this->value_(i,j) /= total_measure;
241  }
242  }
243  } else {
244  xprintf(Warn, "Processed element with idx %d is out of source mesh!\n", elm.idx());
245  }
246  END_TIMER("compute_pressure");
247 
248  }
249  return this->r_value_;
250 }
251 
252 
253 
254 template <int spacedim, class Value>
257 {
258  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
259  xprintf(Err, "Not implemented.");
260  // not supported yet
261 }
262 
263 
264 
265 
266 
267 #endif
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:107
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:101
static Default obligatory()
Definition: type_record.hh:87
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: mesh.h:108
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:172
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:120
Definition: system.hh:75
static FileName input()
Definition: type_base.hh:443
Accessor to the data with type Type::Record.
Definition: accessors.hh:308
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:104
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:467
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:215
const Record & close() const
Definition: type_record.cc:290
enum Intersections TIntersectionType
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:34
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)
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: system.hh:75
Record type proxy class.
Definition: type_record.hh:161
unsigned int dim() const
Definition: accessors.hh:73
arma::vec3 & point()
Definition: nodes.hh:80
virtual bool set_time(double time)
unsigned int idx() const
Definition: accessors.hh:105
void GetIntersection(const TBisector &, const TBisector &, TPosition &, double &, double &)
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:390