Flow123d  release_3.0.0-968-gc87a28e79
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 "io/msh_gmshreader.h"
23 #include "mesh/bih_tree.hh"
24 #include "mesh/accessors.hh"
25 #include "io/reader_cache.hh"
26 #include "system/sys_profiler.hh"
27 
28 #include "fem/mapping_p1.hh"
29 
33 
34 namespace it = Input::Type;
35 
36 FLOW123D_FORCE_LINK_IN_CHILD(field_interpolated)
37 
38 
39 
40 template <int spacedim, class Value>
42 {
43  return it::Record("FieldInterpolatedP0", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field interpolated from external mesh data and piecewise constant on mesh elements.")
47  "Input file with ASCII GMSH file format.")
49  "The values of the Field are read from the ```$ElementData``` section with field name given by this key.")
50  //.declare_key("unit", FieldAlgorithmBase<spacedim, Value>::get_input_type_unit_si(), it::Default::optional(),
51  // "Definition of unit.")
52  .declare_key("default_value", IT::Double(), IT::Default::optional(),
53  "Allow set default value of elements that have not listed values in mesh data file.")
54  .declare_key("time_unit", IT::String(), IT::Default::read_time("Common unit of TimeGovernor."),
55  "Definition of unit of all times defined in mesh data file.")
56  .declare_key("read_time_shift", TimeGovernor::get_input_time_type(), IT::Default("0.0"),
57  "Allow set time shift of field data read from the mesh data file. For time 't', field descriptor with time 'T', "
58  "time shift 'S' and if 't > T', we read time frame 't + S'.")
59  .close();
60 }
61 
62 
63 
64 template <int spacedim, class Value>
66  Input::register_class< FieldInterpolatedP0<spacedim, Value>, unsigned int >("FieldInterpolatedP0") +
68 
69 
70 template <int spacedim, class Value>
72 : FieldAlgorithmBase<spacedim, Value>(n_comp)
73 {
74  this->is_constant_in_space_ = false;
75 }
76 
77 
78 
79 template <int spacedim, class Value>
81  this->init_unit_conversion_coefficient(rec, init_data);
82  this->in_rec_ = rec;
83 
84 
85  // read mesh, create tree
86  {
87  reader_file_ = FilePath( rec.val<FilePath>("mesh_data_file") );
88  source_mesh_ = ReaderCache::get_mesh(reader_file_ );
89  //source_mesh_->setup_topology();
90  ReaderCache::check_compatible_mesh(reader_file_, *source_mesh_);
91  }
92  bih_tree_ = new BIHTree();
93  bih_tree_->add_boxes( source_mesh_->get_element_boxes() );
94  bih_tree_->construct();
95 
96  // allocate data_
97  unsigned int data_size = source_mesh_->n_elements() * (this->value_.n_rows() * this->value_.n_cols());
98  data_ = std::make_shared<std::vector<typename Value::element_type>>();
99  data_->resize(data_size);
100 
101  field_name_ = rec.val<std::string>("field_name");
102  if (!rec.opt_val("default_value", default_value_) ) {
103  default_value_ = numeric_limits<double>::signaling_NaN();
104  }
105 }
106 
107 
108 
109 
110 template <int spacedim, class Value>
112  OLD_ASSERT(source_mesh_, "Null mesh pointer of elementwise field: %s, did you call init_from_input(Input::Record)?\n", field_name_.c_str());
113  if ( reader_file_ == FilePath() ) return false;
114 
115  //walkaround for the steady time governor - there is no data to be read in time==infinity
116  //TODO: is it possible to check this before calling set_time?
117  //if (time == numeric_limits< double >::infinity()) return false;
118 
119  // value of last computed element must be recalculated if time is changed
120  computed_elm_idx_ = numeric_limits<unsigned int>::max();
121 
122  bool boundary_domain_ = false;
123  double time_unit_coef = time.read_coef(in_rec_.find<string>("time_unit"));
124  double time_shift = time.read_time( in_rec_.find<Input::Tuple>("read_time_shift") );
125  double read_time = (time.end()+time_shift) / time_unit_coef;
126  BaseMeshReader::HeaderQuery header_query(field_name_, read_time, OutputTime::DiscreteSpace::ELEM_DATA);
127  ReaderCache::get_reader(reader_file_ )->find_header(header_query);
128  data_ = ReaderCache::get_reader(reader_file_ )->template get_element_data<typename Value::element_type>(
129  source_mesh_->n_elements(), this->value_.n_rows() * this->value_.n_cols(), boundary_domain_, this->component_idx_);
130  CheckResult checked_data = ReaderCache::get_reader(reader_file_)->scale_and_check_limits(field_name_,
131  this->unit_conversion_coefficient_, default_value_);
132 
133  if (checked_data == CheckResult::not_a_number) {
134  THROW( ExcUndefElementValue() << EI_Field(field_name_) );
135  }
136 
137  return true;
138 }
139 
140 
141 
142 template <int spacedim, class Value>
143 typename Value::return_type const &FieldInterpolatedP0<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
144 {
145  OLD_ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
146  if (elm.idx() != computed_elm_idx_ || elm.is_boundary() != computed_elm_boundary_) {
147  computed_elm_idx_ = elm.idx();
148  computed_elm_boundary_ = elm.is_boundary();
149 
150  if (elm.dim() == 3) {
151  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
152  }
153 
154  double epsilon = 4* numeric_limits<double>::epsilon() * elm.measure();
155 
156  // gets suspect elements
157  if (elm.dim() == 0) {
158  searched_elements_.clear();
159  ((BIHTree *)bih_tree_)->find_point(elm.node(0)->point(), searched_elements_);
160  } else {
161  BoundingBox bb = elm.bounding_box();
162  searched_elements_.clear();
163  ((BIHTree *)bih_tree_)->find_bounding_box(bb, searched_elements_);
164  }
165 
166  // set zero values of value_ object
167  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
168  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
169  this->value_(i,j) = 0.0;
170  }
171  }
172 
173  double total_measure=0.0, measure;
174 
175  START_TIMER("compute_pressure");
176  ADD_CALLS(searched_elements_.size());
177 
178 
179  MappingP1<3,3> mapping;
180 
181  for (std::vector<unsigned int>::iterator it = searched_elements_.begin(); it!=searched_elements_.end(); it++)
182  {
183  ElementAccessor<3> ele = source_mesh_->element_accessor(*it);
184  if (ele->dim() == 3) {
185  // get intersection (set measure = 0 if intersection doesn't exist)
186  switch (elm.dim()) {
187  case 0: {
188  arma::vec::fixed<3> real_point = elm.node(0)->point();
189  arma::mat::fixed<3, 4> elm_map = mapping.element_map(ele);
190  arma::vec::fixed<4> unit_point = mapping.project_real_to_unit(real_point, elm_map);
191 
192  measure = (std::fabs(arma::sum( unit_point )-1) <= 1e-14
193  && arma::min( unit_point ) >= 0)
194  ? 1.0 : 0.0;
195  break;
196  }
197  case 1: {
199  ComputeIntersection<1,3> CI(elm, ele, source_mesh_.get());
200  CI.init();
201  CI.compute(is);
202 
203  IntersectionLocal<1,3> ilc(is);
204  measure = ilc.compute_measure() * elm.measure();
205  break;
206  }
207  case 2: {
209  ComputeIntersection<2,3> CI(elm, ele, source_mesh_.get());
210  CI.init();
211  CI.compute(is);
212 
213  IntersectionLocal<2,3> ilc(is);
214  measure = 2 * ilc.compute_measure() * elm.measure();
215  break;
216  }
217  }
218 
219  //adds values to value_ object if intersection exists
220  if (measure > epsilon) {
221  unsigned int index = this->value_.n_rows() * this->value_.n_cols() * (*it);
222  std::vector<typename Value::element_type> &vec = *( data_.get() );
223  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])) );
224  Value tmp_value = Value( ret_type_value );
225 
226  for (unsigned int i=0; i < this->value_.n_rows(); i++) {
227  for (unsigned int j=0; j < this->value_.n_cols(); j++) {
228  this->value_(i,j) += tmp_value(i,j) * measure;
229  }
230  }
231  total_measure += measure;
232  }
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  WarningOut().fmt("Processed element with idx {} 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  OLD_ASSERT( elm.is_elemental(), "FieldInterpolatedP0 works only for 'elemental' ElementAccessors.\n");
259  FieldAlgorithmBase<spacedim, Value>::value_list(point_list, elm, value_list);
260 }
261 
262 
263 
264 // Instantiations of FieldInterpolatedP0
ElementAccessor::dim
unsigned int dim() const
Definition: accessors.hh:87
field_interpolated_p0.hh
FieldInterpolatedP0::init_from_input
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Definition: field_interpolated_p0.cc:80
bih_tree.hh
ComputeIntersection< 2, 3 >
Class for 2D-2D intersections.
Definition: compute_intersection.hh:462
FieldInterpolatedP0::value_list
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Definition: field_interpolated_p0.cc:255
Element::dim
unsigned int dim() const
Definition: elements.h:124
ComputeIntersection< 1, 3 >
Definition: compute_intersection.hh:345
Input::Record::val
const Ret val(const string &key) const
Definition: accessors_impl.hh:31
IntersectionLocal::compute_measure
double compute_measure() const override
Computes the relative measure of intersection object.
Definition: intersection_local.cc:53
FilePath
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
Input::Type::Double
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
FLOW123D_FORCE_LINK_IN_CHILD
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
BIHTree
Class for O(log N) lookup for intersections with a set of bounding boxes.
Definition: bih_tree.hh:38
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
FieldAlgorithmBase::is_constant_in_space_
bool is_constant_in_space_
Flag detects that field is only dependent on time.
Definition: field_algo_base.hh:271
std::vector
Definition: doxy_dummy_defs.hh:7
Input::Type::Default::read_time
static Default read_time(const std::string &description)
The factory function to make an default value that will be specified at the time when a key will be r...
Definition: type_record.hh:97
ElementAccessor
Definition: fe_value_handler.hh:29
system.hh
reader_cache.hh
ElementAccessor::node
const Node * node(unsigned int ni) const
Definition: accessors.hh:145
FieldInterpolatedP0::value
virtual const Value::return_type & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_interpolated_p0.cc:143
ElementAccessor::is_elemental
bool is_elemental() const
Definition: accessors.hh:79
TimeStep::read_time
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
Definition: time_governor.cc:238
FieldAlgorithmBase::Point
Space< spacedim >::Point Point
Definition: field_algo_base.hh:113
msh_gmshreader.h
FieldInterpolatedP0::get_input_type
static const Input::Type::Record & get_input_type()
Definition: field_interpolated_p0.cc:41
BoundingBox
Bounding box in 3d ambient space.
Definition: bounding_box.hh:54
ComputeIntersection< 2, 3 >::init
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
Definition: compute_intersection.cc:1056
FieldInterpolatedP0::set_time
bool set_time(const TimeStep &time) override
Definition: field_interpolated_p0.cc:111
Input::Type::Default
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Input::Type::Record::derive_from
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
ElementAccessor::is_boundary
bool is_boundary() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:106
ElementAccessor::bounding_box
BoundingBox bounding_box() const
Definition: accessors.hh:157
accessors.hh
TimeStep::end
double end() const
Definition: time_governor.hh:151
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
MappingP1::project_real_to_unit
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:275
sys_profiler.hh
FieldAlgoBaseInitData
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Definition: field_algo_base.hh:79
xprintf
#define xprintf(...)
Definition: system.hh:92
TimeStep
Representation of one time step..
Definition: time_governor.hh:113
CheckResult
CheckResult
Return type of method that checked data stored in ElementDataCache (NaN values, limits)
Definition: element_data_cache.hh:36
MappingP1::element_map
ElementMap element_map(ElementAccessor< 3 > elm) const
Definition: mapping_p1.cc:265
Input::Type::Default::obligatory
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
Input::Record::opt_val
bool opt_val(const string &key, Ret &value) const
Definition: accessors_impl.hh:107
Input::Type::Record::declare_key
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:501
Node::point
arma::vec3 & point()
Definition: nodes.hh:67
ComputeIntersection< 1, 3 >::init
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
Definition: compute_intersection.cc:812
Input::Type::FileName::input
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:525
Input::Type::Record::close
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
FieldAlgorithmBase::value_list
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)=0
Definition: field_algo_base.impl.hh:167
Input::Type
Definition: balance.hh:38
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
ComputeIntersection< 1, 3 >::compute
unsigned int compute(std::vector< IPAux > &IP13s)
Computes intersection points for 1D-3D intersection. Computes lower dimensional CIs abscissa vs tetra...
Definition: compute_intersection.cc:833
Value
@ Value
Definition: finite_element.hh:47
FieldInterpolatedP0
Definition: field_interpolated_p0.hh:44
Err
@ Err
Definition: system.hh:64
not_a_number
@ not_a_number
Some value(s) is set to NaN.
Definition: element_data_cache.hh:39
intersection_aux.hh
Internal class representing intersection object.
Input::Type::Record::copy_keys
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:215
FieldAlgorithmBase
Definition: field_algo_base.hh:110
OLD_ASSERT
#define OLD_ASSERT(...)
Definition: global_defs.h:131
Input::Type::String
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
WarningOut
#define WarningOut()
Macro defining 'warning' record of log.
Definition: logger.hh:246
IntersectionAux
Internal auxiliary class representing intersection object of simplex<dimA> and simplex<dimB>.
Definition: compute_intersection.hh:49
INSTANCE_ALL
#define INSTANCE_ALL(field)
Definition: field_instances.hh:43
Input::Tuple
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:411
ReaderCache::check_compatible_mesh
static bool check_compatible_mesh(const FilePath &file_path, Mesh &mesh)
Definition: reader_cache.cc:73
compute_intersection.hh
Fundamental simplicial intersections.
MappingP1< 3, 3 >
field_instances.hh
IntersectionLocal< 1, 3 >
ReaderCache::get_mesh
static std::shared_ptr< Mesh > get_mesh(const FilePath &file_path)
Definition: reader_cache.cc:40
ADD_CALLS
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
Definition: sys_profiler.hh:190
ElementAccessor::idx
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:111
mapping_p1.hh
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell.
ReaderCache::get_reader
static std::shared_ptr< BaseMeshReader > get_reader(const FilePath &file_path)
Definition: reader_cache.cc:36
TimeGovernor::get_input_time_type
static const Input::Type::Tuple & get_input_time_type(double lower_bound=-std::numeric_limits< double >::max(), double upper_bound=std::numeric_limits< double >::max())
Definition: time_governor.cc:46
FieldInterpolatedP0::FieldInterpolatedP0
FieldInterpolatedP0(unsigned int n_comp=0)
Definition: field_interpolated_p0.cc:71
Input::Type::Default::optional
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
START_TIMER
#define START_TIMER(tag)
Starts a timer with specified tag.
Definition: sys_profiler.hh:119
ComputeIntersection< 2, 3 >::compute
void compute(IntersectionAux< 2, 3 > &intersection)
Computes intersection points for 2D-3D intersection. Computes lower dimensional CIs: 1) 3x triangle s...
Definition: compute_intersection.cc:1116
BaseMeshReader::HeaderQuery
Definition: msh_basereader.hh:132
ElementAccessor::measure
double measure() const
Computes the measure of the element.
Definition: accessors.hh:254
END_TIMER
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: sys_profiler.hh:153
TimeStep::read_coef
double read_coef(Input::Iterator< std::string > unit_it) const
Definition: time_governor.cc:244
intersection_local.hh
Classes with algorithms for computation of intersections of meshes.