Flow123d  release_3.0.0-695-g67d21c4
field_fe.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_fe.cc
15  * @brief
16  */
17 
18 
19 #include <limits>
20 
21 #include "fields/field_fe.hh"
22 #include "la/vector_mpi.hh"
23 #include "fields/field_instances.hh" // for instantiation macros
25 #include "input/input_type.hh"
26 #include "fem/fe_p.hh"
27 #include "fem/fe_system.hh"
28 #include "fem/dh_cell_accessor.hh"
29 #include "io/reader_cache.hh"
30 #include "io/msh_gmshreader.h"
31 #include "mesh/accessors.hh"
32 #include "mesh/range_wrapper.hh"
33 #include "mesh/bc_mesh.hh"
35 
36 #include "system/sys_profiler.hh"
40 
41 
42 
43 
44 /// Implementation.
45 
46 namespace it = Input::Type;
47 
48 
49 
50 
52 
53 
54 template <int spacedim, class Value>
55 const Input::Type::Record & FieldFE<spacedim, Value>::get_input_type()
56 {
57  return it::Record("FieldFE", FieldAlgorithmBase<spacedim,Value>::template_name()+" Field given by finite element approximation.")
61  "GMSH mesh with data. Can be different from actual computational mesh.")
63  "Section where to find the field.\n Some sections are specific to file format: "
64  "point_data/node_data, cell_data/element_data, -/element_node_data, native/-.\n"
65  "If not given by a user, we try to find the field in all sections, but we report an error "
66  "if it is found in more than one section.")
68  "The values of the Field are read from the ```$ElementData``` section with field name given by this key.")
69  .declare_key("default_value", IT::Double(), IT::Default::optional(),
70  "Default value is set on elements which values have not been listed in the mesh data file.")
71  .declare_key("time_unit", IT::String(), IT::Default::read_time("Common unit of TimeGovernor."),
72  "Definition of the unit of all times defined in the mesh data file.")
73  .declare_key("read_time_shift", TimeGovernor::get_input_time_type(), IT::Default("0.0"),
74  "This key allows reading field data from the mesh data file shifted in time. Considering the time 't', field descriptor with time 'T', "
75  "time shift 'S', then if 't > T', we read the time frame 't + S'.")
77  IT::Default("\"equivalent_mesh\""), "Type of interpolation applied to the input spatial data.\n"
78  "The default value 'equivalent_mesh' assumes the data being constant on elements living on the same mesh "
79  "as the computational mesh, but possibly with different numbering. In the case of the same numbering, "
80  "the user can set 'identical_mesh' to omit algorithm for guessing node and element renumbering. "
81  "Alternatively, in case of different input mesh, several interpolation algorithms are available.")
82  .close();
83 }
84 
85 template <int spacedim, class Value>
87 {
88  return it::Selection("FE_discretization",
89  "Specify the section in mesh input file where field data is listed.\nSome sections are specific to file format.")
90  .add_value(OutputTime::DiscreteSpace::NODE_DATA, "node_data", "point_data (VTK) / node_data (GMSH)")
91  .add_value(OutputTime::DiscreteSpace::ELEM_DATA, "element_data", "cell_data (VTK) / element_data (GMSH)")
92  .add_value(OutputTime::DiscreteSpace::CORNER_DATA, "element_node_data", "element_node_data (only for GMSH)")
93  .add_value(OutputTime::DiscreteSpace::NATIVE_DATA, "native_data", "native_data (only for VTK)")
94  .close();
95 }
96 
97 template <int spacedim, class Value>
99 {
100  return it::Selection("interpolation", "Specify interpolation of the input data from its input mesh to the computational mesh.")
101  .add_value(DataInterpolation::identic_msh, "identic_mesh", "Topology and indices of nodes and elements of"
102  "the input mesh and the computational mesh are identical. "
103  "This interpolation is typically used for GMSH input files containing only the field values without "
104  "explicit mesh specification.")
105  .add_value(DataInterpolation::equivalent_msh, "equivalent_mesh", "Topologies of the input mesh and the computational mesh "
106  "are the same, the node and element numbering may differ. "
107  "This interpolation can be used also for VTK input data.") // default value
108  .add_value(DataInterpolation::gauss_p0, "P0_gauss", "Topologies of the input mesh and the computational mesh may differ. "
109  "Constant values on the elements of the computational mesh are evaluated using the Gaussian quadrature of the fixed order 4, "
110  "where the quadrature points and their values are found in the input mesh and input data using the BIH tree search."
111  )
112  .add_value(DataInterpolation::interp_p0, "P0_intersection", "Topologies of the input mesh and the computational mesh may differ. "
113  "Can be applied only for boundary fields. For every (boundary) element of the computational mesh the "
114  "intersection with the input mesh is computed. Constant values on the elements of the computational mesh "
115  "are evaluated as the weighted average of the (constant) values on the intersecting elements of the input mesh.")
116  .close();
117 }
118 
119 template <int spacedim, class Value>
121  Input::register_class< FieldFE<spacedim, Value>, unsigned int >("FieldFE") +
123 
124 
125 
126 template <int spacedim, class Value>
128 : FieldAlgorithmBase<spacedim, Value>(n_comp),
129  data_vec_(nullptr),
130  field_name_("")
131 {
132  this->is_constant_in_space_ = false;
133 }
134 
135 
136 template <int spacedim, class Value>
137 VectorMPI * FieldFE<spacedim, Value>::set_fe_data(std::shared_ptr<DOFHandlerMultiDim> dh,
138  unsigned int component_index, VectorMPI *dof_values)
139 {
140  dh_ = dh;
141  if (dof_values==nullptr) { //create data vector according to dof handler - Warning not tested yet
142  data_vec_ = new VectorMPI(dh_->mesh()->n_elements());
144  } else {
145  data_vec_ = dof_values;
146  }
147 
148  unsigned int ndofs = dh_->max_elem_dofs();
149  dof_indices_.resize(ndofs);
150 
151  // initialization data of value handlers
152  FEValueInitData init_data;
153  init_data.dh = dh_;
154  init_data.data_vec = data_vec_;
155  init_data.ndofs = ndofs;
156  init_data.n_comp = this->n_comp();
157  init_data.comp_index = component_index;
158 
159  // initialize value handler objects
160  value_handler0_.initialize(init_data);
161  value_handler1_.initialize(init_data);
162  value_handler2_.initialize(init_data);
163  value_handler3_.initialize(init_data);
164 
165  // set discretization
166  discretization_ = OutputTime::DiscreteSpace::UNDEFINED;
167  interpolation_ = DataInterpolation::equivalent_msh;
168 
169  return data_vec_;
170 }
171 
172 
173 /**
174  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
175  */
176 template <int spacedim, class Value>
177 typename Value::return_type const & FieldFE<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
178 {
179  switch (elm.dim()) {
180  case 0:
181  return value_handler0_.value(p, elm);
182  case 1:
183  return value_handler1_.value(p, elm);
184  case 2:
185  return value_handler2_.value(p, elm);
186  case 3:
187  return value_handler3_.value(p, elm);
188  default:
189  ASSERT(false).error("Invalid element dimension!");
190  }
191 
192  return this->r_value_;
193 }
194 
195 
196 
197 /**
198  * Returns std::vector of scalar values in several points at once.
199  */
200 template <int spacedim, class Value>
203 {
204  ASSERT_EQ( point_list.size(), value_list.size() ).error();
205 
206  switch (elm.dim()) {
207  case 0:
208  value_handler0_.value_list(point_list, elm, value_list);
209  break;
210  case 1:
211  value_handler1_.value_list(point_list, elm, value_list);
212  break;
213  case 2:
214  value_handler2_.value_list(point_list, elm, value_list);
215  break;
216  case 3:
217  value_handler3_.value_list(point_list, elm, value_list);
218  break;
219  default:
220  ASSERT(false).error("Invalid element dimension!");
221  }
222 }
223 
224 
225 
226 template <int spacedim, class Value>
228  this->init_unit_conversion_coefficient(rec, init_data);
229  this->in_rec_ = rec;
230  flags_ = init_data.flags_;
231 
232 
233  // read data from input record
234  reader_file_ = FilePath( rec.val<FilePath>("mesh_data_file") );
235  field_name_ = rec.val<std::string>("field_name");
236  if (! rec.opt_val<OutputTime::DiscreteSpace>("input_discretization", discretization_) ) {
237  discretization_ = OutputTime::DiscreteSpace::UNDEFINED;
238  }
239  if (! rec.opt_val<DataInterpolation>("interpolation", interpolation_) ) {
240  interpolation_ = DataInterpolation::equivalent_msh;
241  }
242  if (! rec.opt_val("default_value", default_value_) ) {
243  default_value_ = numeric_limits<double>::signaling_NaN();
244  }
245 }
246 
247 
248 
249 template <int spacedim, class Value>
250 void FieldFE<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
251  // Mesh can be set only for field initialized from input.
253  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
254  this->boundary_domain_ = boundary_domain;
255  this->make_dof_handler(mesh);
256  switch (this->interpolation_) {
257  case DataInterpolation::identic_msh:
259  break;
260  case DataInterpolation::equivalent_msh:
261  if (!ReaderCache::check_compatible_mesh( reader_file_, const_cast<Mesh &>(*mesh) )) {
262  this->interpolation_ = DataInterpolation::gauss_p0;
263  WarningOut().fmt("Source mesh of FieldFE '{}' is not compatible with target mesh.\nInterpolation of input data will be changed to 'P0_gauss'.\n",
264  field_name_);
265  }
266  break;
267  case DataInterpolation::gauss_p0:
268  {
269  auto source_mesh = ReaderCache::get_mesh(reader_file_);
270  ReaderCache::get_element_ids(reader_file_, *(source_mesh.get()) );
271  break;
272  }
273  case DataInterpolation::interp_p0:
274  {
275  auto source_msh = ReaderCache::get_mesh(reader_file_);
276  ReaderCache::get_element_ids(reader_file_, *(source_msh.get()) );
277  if (!boundary_domain) {
278  this->interpolation_ = DataInterpolation::gauss_p0;
279  WarningOut().fmt("Interpolation 'P0_intersection' of FieldFE '{}' can't be used on bulk region.\nIt will be changed to 'P0_gauss'.\n", field_name_);
280  }
281  break;
282  }
283  }
284  if (boundary_domain) fill_boundary_dofs(); // temporary solution for boundary mesh
285  }
286 }
287 
288 
289 
290 template <int spacedim, class Value>
292  ASSERT(this->boundary_domain_);
293 
294  auto bc_mesh = dh_->mesh()->get_bc_mesh();
295  unsigned int n_comp = this->value_.n_rows() * this->value_.n_cols();
296  boundary_dofs_ = std::make_shared< std::vector<LongIdx> >( n_comp * bc_mesh->n_elements() );
297  std::vector<LongIdx> &in_vec = *( boundary_dofs_.get() );
298  unsigned int j = 0; // actual index to boundary_dofs_ vector
299 
300  for (auto ele : bc_mesh->elements_range()) {
301  LongIdx elm_shift = n_comp * ele.idx();
302  for (unsigned int i=0; i<n_comp; ++i, ++j) {
303  in_vec[j] = elm_shift + i;
304  }
305  }
306 
311 
312  data_vec_->resize(boundary_dofs_->size());
313 }
314 
315 
316 
317 template <int spacedim, class Value>
319  // temporary solution - these objects will be set through FieldCommon
320  switch (this->value_.n_rows() * this->value_.n_cols()) { // by number of components
321  case 1: { // scalar
322  fe0_ = new FE_P_disc<0>(0);
323  fe1_ = new FE_P_disc<1>(0);
324  fe2_ = new FE_P_disc<2>(0);
325  fe3_ = new FE_P_disc<3>(0);
326  break;
327  }
328  case 3: { // vector
329  std::shared_ptr< FiniteElement<0> > fe0_ptr = std::make_shared< FE_P_disc<0> >(0);
330  std::shared_ptr< FiniteElement<1> > fe1_ptr = std::make_shared< FE_P_disc<1> >(0);
331  std::shared_ptr< FiniteElement<2> > fe2_ptr = std::make_shared< FE_P_disc<2> >(0);
332  std::shared_ptr< FiniteElement<3> > fe3_ptr = std::make_shared< FE_P_disc<3> >(0);
333  fe0_ = new FESystem<0>(fe0_ptr, FEType::FEVector, 3);
334  fe1_ = new FESystem<1>(fe1_ptr, FEType::FEVector, 3);
335  fe2_ = new FESystem<2>(fe2_ptr, FEType::FEVector, 3);
336  fe3_ = new FESystem<3>(fe3_ptr, FEType::FEVector, 3);
337  break;
338  }
339  case 9: { // tensor
340  std::shared_ptr< FiniteElement<0> > fe0_ptr = std::make_shared< FE_P_disc<0> >(0);
341  std::shared_ptr< FiniteElement<1> > fe1_ptr = std::make_shared< FE_P_disc<1> >(0);
342  std::shared_ptr< FiniteElement<2> > fe2_ptr = std::make_shared< FE_P_disc<2> >(0);
343  std::shared_ptr< FiniteElement<3> > fe3_ptr = std::make_shared< FE_P_disc<3> >(0);
344  fe0_ = new FESystem<0>(fe0_ptr, FEType::FETensor, 9);
345  fe1_ = new FESystem<1>(fe1_ptr, FEType::FETensor, 9);
346  fe2_ = new FESystem<2>(fe2_ptr, FEType::FETensor, 9);
347  fe3_ = new FESystem<3>(fe3_ptr, FEType::FETensor, 9);
348  break;
349  }
350  default:
351  ASSERT(false).error("Should not happen!\n");
352  }
353 
354  DOFHandlerMultiDim dh_par( const_cast<Mesh &>(*mesh) );
355  std::shared_ptr<DiscreteSpace> ds = std::make_shared<EqualOrderDiscreteSpace>( &const_cast<Mesh &>(*mesh), fe0_, fe1_, fe2_, fe3_);
356  dh_par.distribute_dofs(ds);
357  dh_ = dh_par.sequential();
358  unsigned int ndofs = dh_->max_elem_dofs();
359  dof_indices_.resize(ndofs);
360 
361  // allocate data_vec_
362  data_vec_ = VectorMPI::sequential( dh_->n_global_dofs() );
363 
364  // initialization data of value handlers
365  FEValueInitData init_data;
366  init_data.dh = dh_;
367  init_data.data_vec = data_vec_;
368  init_data.ndofs = ndofs;
369  init_data.n_comp = this->n_comp();
370  init_data.comp_index = 0;
371 
372  // initialize value handler objects
373  value_handler0_.initialize(init_data);
374  value_handler1_.initialize(init_data);
375  value_handler2_.initialize(init_data);
376  value_handler3_.initialize(init_data);
377 }
378 
379 
380 
381 template <int spacedim, class Value>
383  // Time can be set only for field initialized from input.
385  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
386  ASSERT_PTR(dh_)(field_name_).error("Null target mesh pointer of finite element field, did you call set_mesh()?\n");
387  if ( reader_file_ == FilePath() ) return false;
388 
389  unsigned int n_components = this->value_.n_rows() * this->value_.n_cols();
390  double time_unit_coef = time.read_coef(in_rec_.find<string>("time_unit"));
391  double time_shift = time.read_time( in_rec_.find<Input::Tuple>("read_time_shift") );
392  double read_time = (time.end()+time_shift) / time_unit_coef;
393  BaseMeshReader::HeaderQuery header_query(field_name_, read_time, this->discretization_, dh_->hash());
394  ReaderCache::get_reader(reader_file_)->find_header(header_query);
395  // TODO: use default and check NaN values in data_vec
396 
397  unsigned int n_entities;
398  bool is_native = (header_query.discretization == OutputTime::DiscreteSpace::NATIVE_DATA);
399  bool boundary;
400  if (is_native || this->interpolation_==DataInterpolation::identic_msh || this->interpolation_==DataInterpolation::equivalent_msh) {
401  n_entities = dh_->mesh()->n_elements();
402  boundary = this->boundary_domain_;
403  } else {
404  n_entities = ReaderCache::get_mesh(reader_file_)->n_elements();
405  boundary = false;
406  }
407  auto data_vec = ReaderCache::get_reader(reader_file_)->template get_element_data<double>(n_entities, n_components,
408  boundary, this->component_idx_);
409  CheckResult checked_data = ReaderCache::get_reader(reader_file_)->scale_and_check_limits(field_name_,
411 
412 
413  if (checked_data == CheckResult::not_a_number) {
414  THROW( ExcUndefElementValue() << EI_Field(field_name_) );
415  }
416 
417  if (is_native || this->interpolation_==DataInterpolation::identic_msh || this->interpolation_==DataInterpolation::equivalent_msh) {
418  this->calculate_native_values(data_vec);
419  } else if (this->interpolation_==DataInterpolation::gauss_p0) {
420  this->interpolate_gauss(data_vec);
421  } else { // DataInterpolation::interp_p0
422  this->interpolate_intersection(data_vec);
423  }
424 
425  return true;
426  } else return false;
427 
428 }
429 
430 
431 template <int spacedim, class Value>
433 {
434  static const unsigned int quadrature_order = 4; // parameter of quadrature
435  std::shared_ptr<Mesh> source_mesh = ReaderCache::get_mesh(reader_file_);
436  std::vector<unsigned int> searched_elements; // stored suspect elements in calculating the intersection
437  std::vector<arma::vec::fixed<3>> q_points; // real coordinates of quadrature points
438  std::vector<double> q_weights; // weights of quadrature points
439  unsigned int quadrature_size; // size of quadrature point and weight vector
440  std::vector<double> sum_val(dh_->max_elem_dofs()); // sum of value of one quadrature point
441  unsigned int elem_count; // count of intersect (source) elements of one quadrature point
442  std::vector<double> elem_value(dh_->max_elem_dofs()); // computed value of one (target) element
443  bool contains; // sign if source element contains quadrature point
444 
445  {
446  // set size of vectors to maximal count of quadrature points
447  QGauss<3> quad(quadrature_order);
448  q_points.resize(quad.size());
449  q_weights.resize(quad.size());
450  }
451 
452  Mesh *mesh;
453  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
454  else mesh = dh_->mesh();
455  for (auto ele : mesh->elements_range()) {
456  std::fill(elem_value.begin(), elem_value.end(), 0.0);
457  switch (ele->dim()) {
458  case 0:
459  quadrature_size = 1;
460  q_points[0] = ele.node(0)->point();
461  q_weights[0] = 1.0;
462  break;
463  case 1:
464  quadrature_size = value_handler1_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
465  break;
466  case 2:
467  quadrature_size = value_handler2_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
468  break;
469  case 3:
470  quadrature_size = value_handler3_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
471  break;
472  }
473  searched_elements.clear();
474  source_mesh->get_bih_tree().find_bounding_box(ele.bounding_box(), searched_elements);
475 
476  for (unsigned int i=0; i<quadrature_size; ++i) {
477  std::fill(sum_val.begin(), sum_val.end(), 0.0);
478  elem_count = 0;
479  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++) {
480  ElementAccessor<3> elm = source_mesh->element_accessor(*it);
481  contains=false;
482  switch (elm->dim()) {
483  case 0:
484  contains = arma::norm(elm.node(0)->point()-q_points[i], 2) < 4*std::numeric_limits<double>::epsilon();
485  break;
486  case 1:
487  contains = value_handler1_.get_mapping()->contains_point(q_points[i], elm);
488  break;
489  case 2:
490  contains = value_handler2_.get_mapping()->contains_point(q_points[i], elm);
491  break;
492  case 3:
493  contains = value_handler3_.get_mapping()->contains_point(q_points[i], elm);
494  break;
495  default:
496  ASSERT(false).error("Invalid element dimension!");
497  }
498  if ( contains ) {
499  // projection point in element
500  unsigned int index = sum_val.size() * (*it);
501  for (unsigned int j=0; j < sum_val.size(); j++) {
502  sum_val[j] += (*data_vec)[index+j];
503  }
504  ++elem_count;
505  }
506  }
507 
508  if (elem_count > 0) {
509  for (unsigned int j=0; j < sum_val.size(); j++) {
510  elem_value[j] += (sum_val[j] / elem_count) * q_weights[i];
511  }
512  }
513  }
514 
516  else dh_->get_dof_indices( ele, dof_indices_);
517  for (unsigned int i=0; i < elem_value.size(); i++) {
519  (*data_vec_)[dof_indices_[i]] = elem_value[i] * this->unit_conversion_coefficient_;
520  }
521  }
522 }
523 
524 
525 template <int spacedim, class Value>
527 {
528  std::shared_ptr<Mesh> source_mesh = ReaderCache::get_mesh(reader_file_);
529  std::vector<unsigned int> searched_elements; // stored suspect elements in calculating the intersection
530  std::vector<double> value(dh_->max_elem_dofs());
531  double total_measure, measure;
532 
533  Mesh *mesh;
534  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
535  else mesh = dh_->mesh();
536  for (auto elm : mesh->elements_range()) {
537  if (elm.dim() == 3) {
538  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
539  }
540 
541  double epsilon = 4* numeric_limits<double>::epsilon() * elm.measure();
542 
543  // gets suspect elements
544  if (elm.dim() == 0) {
545  searched_elements.clear();
546  source_mesh->get_bih_tree().find_point(elm.node(0)->point(), searched_elements);
547  } else {
548  BoundingBox bb = elm.bounding_box();
549  searched_elements.clear();
550  source_mesh->get_bih_tree().find_bounding_box(bb, searched_elements);
551  }
552 
553  // set zero values of value object
554  std::fill(value.begin(), value.end(), 0.0);
555  total_measure=0.0;
556 
557  START_TIMER("compute_pressure");
558  ADD_CALLS(searched_elements.size());
559 
560 
561  MappingP1<3,3> mapping;
562 
563  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++)
564  {
565  ElementAccessor<3> ele = source_mesh->element_accessor(*it);
566  if (ele->dim() == 3) {
567  // get intersection (set measure = 0 if intersection doesn't exist)
568  switch (elm.dim()) {
569  case 0: {
570  arma::vec::fixed<3> real_point = elm.node(0)->point();
571  arma::mat::fixed<3, 4> elm_map = mapping.element_map(ele);
572  arma::vec::fixed<4> unit_point = mapping.project_real_to_unit(real_point, elm_map);
573 
574  measure = (std::fabs(arma::sum( unit_point )-1) <= 1e-14
575  && arma::min( unit_point ) >= 0)
576  ? 1.0 : 0.0;
577  break;
578  }
579  case 1: {
581  ComputeIntersection<1,3> CI(elm, ele, source_mesh.get());
582  CI.init();
583  CI.compute(is);
584 
585  IntersectionLocal<1,3> ilc(is);
586  measure = ilc.compute_measure() * elm.measure();
587  break;
588  }
589  case 2: {
591  ComputeIntersection<2,3> CI(elm, ele, source_mesh.get());
592  CI.init();
593  CI.compute(is);
594 
595  IntersectionLocal<2,3> ilc(is);
596  measure = 2 * ilc.compute_measure() * elm.measure();
597  break;
598  }
599  }
600 
601  //adds values to value_ object if intersection exists
602  if (measure > epsilon) {
603  unsigned int index = value.size() * (*it);
604  std::vector<double> &vec = *( data_vec.get() );
605  for (unsigned int i=0; i < value.size(); i++) {
606  value[i] += vec[index+i] * measure;
607  }
608  total_measure += measure;
609  }
610  }
611  }
612 
613  // computes weighted average, store it to data vector
614  if (total_measure > epsilon) {
617  else dh_->get_dof_indices( elm, dof_indices_ );
618  for (unsigned int i=0; i < value.size(); i++) {
619  (*data_vector)[ dof_indices_[i] ] = value[i] / total_measure;
620  }
621  } else {
622  WarningOut().fmt("Processed element with idx {} is out of source mesh!\n", elm.idx());
623  }
624  END_TIMER("compute_pressure");
625 
626  }
627 }
628 
629 
630 template <int spacedim, class Value>
632 {
633  // Same algorithm as in output of Node_data. Possibly code reuse.
634  unsigned int dof_size, data_vec_i;
635  std::vector<unsigned int> count_vector(data_vec_->size(), 0);
638 
639  // iterate through elements, assembly global vector and count number of writes
640  Mesh *mesh;
641  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
642  else mesh = dh_->mesh();
643  for (auto ele : mesh->elements_range()) { // remove special case for rank == 0 - necessary for correct output
644  if (this->boundary_domain_) dof_size = value_handler1_.get_dof_indices( ele, dof_indices_ );
645  else dof_size = dh_->get_dof_indices( ele, dof_indices_ );
646  data_vec_i = ele.idx() * dof_indices_.size();
647  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
648  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
649  ++count_vector[ dof_indices_[i] ];
650  }
651  }
652 
653  // iterate through cells, assembly global vector and count number of writes - prepared solution for further development
654  /*for (auto cell : dh_->own_range()) {
655  dof_size = cell.get_dof_indices(dof_indices_);
656  data_vec_i = cell.elm_idx() * dof_indices_.size();
657  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
658  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
659  ++count_vector[ dof_indices_[i] ];
660  }
661  }*/
662 
663  // compute averages of values
664  for (unsigned int i=0; i<data_vec_->size(); ++i) {
665  if (count_vector[i]>0) (*data_vector)[i] /= count_vector[i];
666  }
667 }
668 
669 
670 template <int spacedim, class Value>
672  ASSERT_EQ(output_data_cache.n_values() * output_data_cache.n_elem(), dh_->n_global_dofs()).error();
673  ASSERT_EQ(output_data_cache.n_elem(), dof_indices_.size()).error();
674  double loc_values[output_data_cache.n_elem()];
675  unsigned int i, dof_filled_size;
676 
678  for (auto ele : dh_->mesh()->elements_range()) {
679  dof_filled_size = dh_->get_dof_indices( ele, dof_indices_);
680  for (i=0; i<dof_filled_size; ++i) loc_values[i] = (*data_vec)[ dof_indices_[0] ];
681  for ( ; i<output_data_cache.n_elem(); ++i) loc_values[i] = numeric_limits<double>::signaling_NaN();
682  output_data_cache.store_value( ele.idx(), loc_values );
683  }
684 
685  output_data_cache.set_dof_handler_hash( dh_->hash() );
686 }
687 
688 
689 
690 template <int spacedim, class Value>
691 inline unsigned int FieldFE<spacedim, Value>::data_size() const {
692  return data_vec_->size();
693 }
694 
695 
696 
697 template <int spacedim, class Value>
699 {}
700 
701 
702 // Instantiations of FieldFE
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
Definition: long_idx.hh:22
unsigned int comp_index
index of component (of vector_value/tensor_value)
std::shared_ptr< DOFHandlerMultiDim > sequential()
Returns sequential version of the current dof handler.
Definition: dofhandler.cc:88
virtual ~FieldFE()
Destructor.
Definition: field_fe.cc:698
void init_unit_conversion_coefficient(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Init value of unit_conversion_coefficient_ from input.
Bounding box in 3d ambient space.
Definition: bounding_box.hh:54
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Definition: field_fe.cc:201
void set_boundary_dofs_vector(std::shared_ptr< std::vector< LongIdx > > boundary_dofs)
TODO: Temporary solution. Fix problem with merge new DOF handler and boundary Mesh. Will be removed in future.
void set_dof_handler_hash(std::size_t hash)
void interpolate_gauss(ElementDataCache< double >::ComponentDataPtr data_vec)
Interpolate data (use Gaussian distribution) over all elements of target mesh.
Definition: field_fe.cc:432
FEValueHandler< 0, spacedim, Value > value_handler0_
Value handler that allows get value of 0D elements.
Definition: field_fe.hh:178
std::shared_ptr< std::vector< T > > ComponentDataPtr
double read_coef(Input::Iterator< std::string > unit_it) const
Classes with algorithms for computation of intersections of meshes.
Some value(s) is set to NaN.
void initialize(FEValueInitData init_data)
Initialize data members.
VectorMPI * data_vec
Store data of Field.
unsigned int component_idx_
Specify if the field is part of a MultiField and which component it is.
static void get_element_ids(const FilePath &file_path, const Mesh &mesh)
Definition: reader_cache.cc:80
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
std::string field_name_
field name read from input
Definition: field_fe.hh:203
double compute_measure() const override
Computes the relative measure of intersection object.
void zero_entries()
Definition: vector_mpi.hh:102
void fill_data_to_cache(ElementDataCache< double > &output_data_cache)
Definition: field_fe.cc:671
Abstract linear system class.
Definition: balance.hh:35
FieldFlag::Flags flags_
static VectorMPI * sequential(unsigned int size)
Definition: vector_mpi.hh:60
FEValueHandler< 2, spacedim, Value > value_handler2_
Value handler that allows get value of 2D elements.
Definition: field_fe.hh:182
void store_value(unsigned int idx, const T *value)
Fundamental simplicial intersections.
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
void distribute_dofs(std::shared_ptr< DiscreteSpace > ds)
Distributes degrees of freedom on the mesh needed for the given discrete space.
Definition: dofhandler.cc:266
FilePath reader_file_
mesh reader file
Definition: field_fe.hh:200
#define INSTANCE_ALL(field)
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
Definition: mesh.h:80
Iterator< Ret > find(const string &key) const
void initialize(FEValueInitData init_data)
Initialize data members.
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Returns one value in one given point.
Class FESystem for compound finite elements.
VectorDataPtr data_ptr()
Getter for shared pointer of output data.
Definition: vector_mpi.hh:91
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Definition: field_fe.cc:250
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
double default_value_
Default value of element if not set in mesh data file.
Definition: field_fe.hh:215
FEValueHandler< 3, spacedim, Value > value_handler3_
Value handler that allows get value of 3D elements.
Definition: field_fe.hh:184
bool set_time(const TimeStep &time) override
Definition: field_fe.cc:382
FiniteElement< 3 > * fe3_
Same as previous, but represents 3D element.
Definition: field_fe.hh:197
static const Input::Type::Selection & get_interp_selection_input_type()
Definition: field_fe.cc:98
Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Returns one value in one given point.
std::shared_ptr< std::vector< LongIdx > > boundary_dofs_
Definition: field_fe.hh:228
Value::return_type r_value_
void fill_boundary_dofs()
Definition: field_fe.cc:291
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
Symmetric Gauss-Legendre quadrature formulae on simplices.
unsigned int data_size() const
Definition: field_fe.cc:691
constexpr bool match(Mask mask) const
Definition: flag_array.hh:163
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
double unit_conversion_coefficient_
Coeficient of conversion of user-defined unit.
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
unsigned int dim() const
Definition: elements.h:124
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
bool boundary_domain_
Is set in set_mesh method. Value true means, that we accept only boundary element accessors in the va...
Definition: field_fe.hh:221
bool opt_val(const string &key, Ret &value) const
OutputTime::DiscreteSpace discretization_
Specify section where to find the field data in input mesh file.
Definition: field_fe.hh:206
std::shared_ptr< DOFHandlerMultiDim > dh_
DOF handler object.
Definition: field_fe.hh:171
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:541
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())
void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Returns std::vector of scalar values in several points at once.
DataInterpolation interpolation_
Specify type of FE data interpolation.
Definition: field_fe.hh:209
Compound finite element on dim dimensional simplex.
Definition: fe_system.hh:99
Definitions of basic Lagrangean finite elements with polynomial shape functions.
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:526
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:92
void resize(unsigned int local_size)
Definition: vector_mpi.hh:69
#define START_TIMER(tag)
Starts a timer with specified tag.
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:156
Selection & add_value(const int value, const std::string &key, const std::string &description="", TypeBase::attribute_map attributes=TypeBase::attribute_map())
Adds one new value with name given by key to the Selection.
void interpolate_intersection(ElementDataCache< double >::ComponentDataPtr data_vec)
Interpolate data (use intersection library) over all elements of target mesh.
Definition: field_fe.cc:526
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
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_fe.cc:177
virtual Range< ElementAccessor< 3 > > elements_range() const
Returns range of bulk elements.
Definition: mesh.cc:1033
static bool check_compatible_mesh(const FilePath &file_path, Mesh &mesh)
Definition: reader_cache.cc:73
double end() const
unsigned int ndofs
number of dofs
Space< spacedim >::Point Point
unsigned int compute_quadrature(std::vector< arma::vec::fixed< 3 >> &q_points, std::vector< double > &q_weights, const ElementAccessor< spacedim > &elm, unsigned int order=3)
Compute real coordinates and weights (use QGauss) for given element.
CheckResult
Return type of method that checked data stored in ElementDataCache (NaN values, limits) ...
std::shared_ptr< DOFHandlerMultiDim > dh
DOF handler object.
unsigned int get_dof_indices(const ElementAccessor< 3 > &cell, std::vector< LongIdx > &indices) const
TODO: Temporary solution. Fix problem with merge new DOF handler and boundary Mesh. Will be removed in future.
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
FEValueHandler< 1, spacedim, Value > value_handler1_
Value handler that allows get value of 1D elements.
Definition: field_fe.hh:180
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:215
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
MappingP1< elemdim, 3 > * get_mapping()
Return mapping object.
FiniteElement< 1 > * fe1_
Same as previous, but represents 1D element.
Definition: field_fe.hh:193
static const Input::Type::Selection & get_disc_selection_input_type()
Definition: field_fe.cc:86
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
FiniteElement< 2 > * fe2_
Same as previous, but represents 2D element.
Definition: field_fe.hh:195
bool is_constant_in_space_
Flag detects that field is only dependent on time.
Value value_
Last value, prevents passing large values (vectors) by value.
VectorMPI * data_vec_
Store data of Field.
Definition: field_fe.hh:173
Input::Record in_rec_
Accessor to Input::Record.
Definition: field_fe.hh:218
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
const Selection & close() const
Close the Selection, no more values can be added.
FieldFE(unsigned int n_comp=0)
Definition: field_fe.cc:127
const unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:139
void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Returns std::vector of scalar values in several points at once.
std::vector< LongIdx > dof_indices_
Array of indexes to data_vec_, used for get/set values.
Definition: field_fe.hh:175
Definitions of particular quadrature rules on simplices.
Class for 2D-2D intersections.
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:246
void set_boundary_dofs_vector(std::shared_ptr< std::vector< LongIdx > > boundary_dofs)
TODO: Temporary solution. Fix problem with merge new DOF handler and boundary Mesh. Will be removed in future.
#define END_TIMER(tag)
Ends a timer with specified tag.
FiniteElement< 0 > * fe0_
Definition: field_fe.hh:191
DataInterpolation
Definition: field_fe.hh:59
Definition: system.hh:64
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Definition: field_fe.cc:227
static std::shared_ptr< Mesh > get_mesh(const FilePath &file_path)
Definition: reader_cache.cc:40
Record type proxy class.
Definition: type_record.hh:182
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:33
unsigned int dim() const
Definition: accessors.hh:87
bool contains_point(arma::vec point, ElementAccessor< 3 > elm)
Test if element contains given point.
Definition: mapping_p1.cc:302
Internal auxiliary class representing intersection object of simplex<dimA> and simplex<dimB>.
static std::shared_ptr< BaseMeshReader > get_reader(const FilePath &file_path)
Definition: reader_cache.cc:36
std::shared_ptr< VectorData > VectorDataPtr
Definition: vector_mpi.hh:44
unsigned int n_comp
number of components
void calculate_native_values(ElementDataCache< double >::ComponentDataPtr data_cache)
Calculate native data over all elements of target mesh.
Definition: field_fe.cc:631
FieldFlag::Flags flags_
Field flags.
Definition: field_fe.hh:212
arma::vec3 & point()
Definition: nodes.hh:67
VectorMPI * set_fe_data(std::shared_ptr< DOFHandlerMultiDim > dh, unsigned int component_index=0, VectorMPI *dof_values=nullptr)
Definition: field_fe.cc:137
Initialization structure of FEValueHandler class.
Class for declaration of the input data that are in string format.
Definition: type_base.hh:589
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
Representation of one time step..
Template for classes storing finite set of named values.
void make_dof_handler(const Mesh *mesh)
Create DofHandler object.
Definition: field_fe.cc:318
Implementation of range helper class.
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:327
static constexpr Mask declare_input
The field can be set from input. The key in input field descriptor is declared. (default on) ...
Definition: field_flag.hh:35
unsigned int size()
Return size of output data.
Definition: vector_mpi.hh:136
Definition: field.hh:56
unsigned int n_comp() const
Internal class representing intersection object.
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:299
const Node * node(unsigned int ni) const
Definition: accessors.hh:145