Flow123d
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", FieldBase<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 : FieldBase<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  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;
119 
120  bool boundary_domain_ = false;
121  //DBGMSG("reading data for interpolation: name: %s \t time: %f \t n: %d\n", field_name_.c_str(), time, source_mesh_->element.size());
122  reader_->read_element_data(search_header, data_, source_mesh_->elements_id_maps(boundary_domain_) );
123  //DBGMSG("end of reading data for interpolation: %s\n", field_name_.c_str());
124 
125  return search_header.actual;
126 }
127 
128 
129 
130 template <int spacedim, class Value>
131 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
132 {
133  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
134  if (elm.idx() != computed_elm_idx_) {
135  computed_elm_idx_ = elm.idx();
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  //Point point;
146  //for (unsigned int i=0; i<3; i++) point(i) = elm.element()->node[0]->point()(i);
147  searched_elements_.clear();
148  ((BIHTree *)bih_tree_)->find_point(elm.element()->node[0]->point(), searched_elements_);
149  } else {
150  BoundingBox bb;
151  elm.element()->get_bounding_box(bb);
152  searched_elements_.clear();
153  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
154  }
155 
156  // set zero values of value_ object
157  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
158  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
159  this->value_(i,j) = 0.0;
160  }
161  }
162 
163  double total_measure=0.0, measure;
164  TIntersectionType iType;
165 
166  START_TIMER("compute_pressure");
167  ADD_CALLS(searched_elements_.size());
168  for (std::vector<unsigned int>::iterator it = searched_elements_.begin(); it!=searched_elements_.end(); it++)
169  {
170  ElementFullIter ele = source_mesh_->element( *it );
171  if (ele->dim() == 3) {
172  ngh::set_tetrahedron_from_element(tetrahedron_, ele);
173  // get intersection (set measure = 0 if intersection doesn't exist)
174  switch (elm.dim()) {
175  case 0: {
176  ngh::set_point_from_element(point_, elm.element());
177  if ( tetrahedron_.IsInner(point_) ) {
178  measure = 1.0;
179  } else {
180  measure = 0.0;
181  }
182  break;
183  }
184  case 1: {
185  ngh::set_abscissa_from_element(abscissa_, elm.element());
186  GetIntersection(abscissa_, tetrahedron_, iType, measure);
187  if (iType != line) {
188  measure = 0.0;
189  }
190  break;
191  }
192  case 2: {
193  ngh::set_triangle_from_element(triangle_, elm.element());
194  GetIntersection(triangle_, tetrahedron_, iType, measure);
195  if (iType != area) {
196  measure = 0.0;
197  }
198  break;
199  }
200  }
201 
202 
203 
204  //adds values to value_ object if intersection exists
205  if (measure > epsilon) {
206  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
207  typename Value::element_type * ele_data_ptr = (typename Value::element_type *)(data_+index);
208  typename Value::return_type & ret_type_value = const_cast<typename Value::return_type &>( Value::from_raw(this->r_value_, ele_data_ptr) );
209  Value tmp_value = Value( ret_type_value );
210 
211  /*cout << "n_rows, n_cols = " << tmp_value.n_rows() << ", " << tmp_value.n_cols() << endl;
212  for (unsigned int i=0; i < tmp_value.n_rows(); i++) {
213  for (unsigned int j=0; j < tmp_value.n_cols(); j++) {
214  cout << "(" << i << "," << j << ") = " << tmp_value(i,j) << ", ";
215  }
216  cout << endl;
217  }
218  cout << endl;*/
219 
220  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
221  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
222  this->value_(i,j) += tmp_value(i,j) * measure;
223  }
224  }
225  total_measure += measure;
226  }
227  } else {
228  xprintf(Err, "Dimension of element in source mesh must be 3!\n");
229  }
230  }
231 
232  // computes weighted average
233  if (total_measure > epsilon) {
234  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
235  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
236  this->value_(i,j) /= total_measure;
237  }
238  }
239  } else {
240  xprintf(Warn, "Processed element with idx %d is out of source mesh!\n", elm.idx());
241  }
242  END_TIMER("compute_pressure");
243 
244  }
245  return this->r_value_;
246 }
247 
248 
249 
250 template <int spacedim, class Value>
253 {
254  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
255  xprintf(Err, "Not implemented.");
256  // not supported yet
257 }
258 
259 
260 
261 
262 
263 #endif