Flow123d  jenkins-Flow123d-windows32-release-multijob-51
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 
40 
41 namespace it = Input::Type;
42 
43 
44 
45 template <int spacedim, class Value>
48 
49 
50 
51 template <int spacedim, class Value>
53  Input::Type::AbstractRecord &a_type, const typename Value::ElementInputType *eit
54  )
55 {
56  it::Record type=
57  it::Record("FieldInterpolatedP0", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field constant in space.")
58  .derive_from(a_type)
60  "Input file with ASCII GMSH file format.")
62  "The values of the Field are read from the \\$ElementData section with field name given by this key.")
63  .close();
64 
65  return type;
66 }
67 
68 
69 
70 template <int spacedim, class Value>
72 : FieldAlgorithmBase<spacedim, Value>(n_comp)
73 {}
74 
75 
76 
77 template <int spacedim, class Value>
79 
80  // read mesh, create tree
81  {
82  source_mesh_ = new Mesh();
83  reader_ = new GmshMeshReader( rec.val<FilePath>("gmsh_file") );
84  reader_->read_mesh( source_mesh_ );
85  // no call to mesh->setup_topology, we need only elements, no connectivity
86  }
87  bih_tree_ = new BIHTree( source_mesh_ );
88 
89  // allocate data_
90  unsigned int data_size = source_mesh_->element.size() * (this->value_.n_rows() * this->value_.n_cols());
91  data_ = new double[data_size];
92  std::fill(data_, data_ + data_size, 0.0);
93 
94  field_name_ = rec.val<std::string>("field_name");
95 }
96 
97 
98 
99 
100 template <int spacedim, class Value>
102  ASSERT(source_mesh_, "Null mesh pointer of elementwise field: %s, did you call init_from_input(Input::Record)?\n", field_name_.c_str());
103  ASSERT(data_, "Null data pointer.\n");
104  if (reader_ == NULL) 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;
119 
120  bool boundary_domain_ = false;
121  reader_->read_element_data(search_header, data_, source_mesh_->elements_id_maps(boundary_domain_) );
122 
123  return search_header.actual;
124 }
125 
126 
127 
128 template <int spacedim, class Value>
129 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
130 {
131  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
132  if (elm.idx() != computed_elm_idx_ || elm.is_boundary() != computed_elm_boundary_) {
133  computed_elm_idx_ = elm.idx();
134  computed_elm_boundary_ = elm.is_boundary();
135 
136  if (elm.dim() == 3) {
137  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
138  }
139 
140  double epsilon = 4* numeric_limits<double>::epsilon() * elm.element()->measure();
141 
142  // gets suspect elements
143  if (elm.dim() == 0) {
144  searched_elements_.clear();
145  ((BIHTree *)bih_tree_)->find_point(elm.element()->node[0]->point(), searched_elements_);
146  } else {
147  BoundingBox bb;
148  elm.element()->get_bounding_box(bb);
149  searched_elements_.clear();
150  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
151  }
152 
153  // set zero values of value_ object
154  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
155  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
156  this->value_(i,j) = 0.0;
157  }
158  }
159 
160  double total_measure=0.0, measure;
161  TIntersectionType iType;
162 
163  START_TIMER("compute_pressure");
164  ADD_CALLS(searched_elements_.size());
165  for (std::vector<unsigned int>::iterator it = searched_elements_.begin(); it!=searched_elements_.end(); it++)
166  {
167  ElementFullIter ele = source_mesh_->element( *it );
168  if (ele->dim() == 3) {
169  ngh::set_tetrahedron_from_element(tetrahedron_, ele);
170  // get intersection (set measure = 0 if intersection doesn't exist)
171  switch (elm.dim()) {
172  case 0: {
173  ngh::set_point_from_element(point_, elm.element());
174  if ( tetrahedron_.IsInner(point_) ) {
175  measure = 1.0;
176  } else {
177  measure = 0.0;
178  }
179  break;
180  }
181  case 1: {
182  ngh::set_abscissa_from_element(abscissa_, elm.element());
183  GetIntersection(abscissa_, tetrahedron_, iType, measure);
184  if (iType != line) {
185  measure = 0.0;
186  }
187  break;
188  }
189  case 2: {
190  ngh::set_triangle_from_element(triangle_, elm.element());
191  GetIntersection(triangle_, tetrahedron_, iType, measure);
192  if (iType != area) {
193  measure = 0.0;
194  }
195  break;
196  }
197  }
198 
199 
200 
201  //adds values to value_ object if intersection exists
202  if (measure > epsilon) {
203  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
204  typename Value::element_type * ele_data_ptr = (typename Value::element_type *)(data_+index);
205  typename Value::return_type & ret_type_value = const_cast<typename Value::return_type &>( Value::from_raw(this->r_value_, ele_data_ptr) );
206  Value tmp_value = Value( ret_type_value );
207 
208  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
209  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
210  this->value_(i,j) += tmp_value(i,j) * measure;
211  }
212  }
213  total_measure += measure;
214  }
215  } else {
216  xprintf(Err, "Dimension of element in source mesh must be 3!\n");
217  }
218  }
219 
220  // computes weighted average
221  if (total_measure > epsilon) {
222  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
223  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
224  this->value_(i,j) /= total_measure;
225  }
226  }
227  } else {
228  xprintf(Warn, "Processed element with idx %d is out of source mesh!\n", elm.idx());
229  }
230  END_TIMER("compute_pressure");
231 
232  }
233  return this->r_value_;
234 }
235 
236 
237 
238 template <int spacedim, class Value>
241 {
242  ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
243  FieldAlgorithmBase<spacedim, Value>::value_list(point_list, elm, value_list);
244 }
245 
246 
247 
248 
249 
250 #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:99
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: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:169
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: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: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:463
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:206
const Record & close() const
Definition: type_record.cc:286
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: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)
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: system.hh:72
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:103
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:386