Flow123d  release_3.0.0-1264-g45bfb2a
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  field_name_("")
130 {
131  this->is_constant_in_space_ = false;
132 }
133 
134 
135 template <int spacedim, class Value>
136 VectorMPI FieldFE<spacedim, Value>::set_fe_data(std::shared_ptr<DOFHandlerMultiDim> dh,
137  unsigned int component_index, VectorMPI dof_values)
138 {
139  dh_ = dh;
140  if (dof_values.size()==0) { //create data vector according to dof handler - Warning not tested yet
141  data_vec_ = dh_->create_vector();
143  } else {
144  data_vec_ = dof_values;
145  }
146 
147  unsigned int ndofs = dh_->max_elem_dofs();
148  dof_indices_.resize(ndofs);
149 
150  // initialization data of value handlers
151  FEValueInitData init_data;
152  init_data.dh = dh_;
153  init_data.data_vec = data_vec_;
154  init_data.ndofs = ndofs;
155  init_data.n_comp = this->n_comp();
156  init_data.comp_index = component_index;
157 
158  // initialize value handler objects
159  value_handler0_.initialize(init_data);
160  value_handler1_.initialize(init_data);
161  value_handler2_.initialize(init_data);
162  value_handler3_.initialize(init_data);
163 
164  // set discretization
165  discretization_ = OutputTime::DiscreteSpace::UNDEFINED;
166  interpolation_ = DataInterpolation::equivalent_msh;
167 
168  return data_vec_;
169 }
170 
171 
172 /**
173  * Returns one value in one given point. ResultType can be used to avoid some costly calculation if the result is trivial.
174  */
175 template <int spacedim, class Value>
176 typename Value::return_type const & FieldFE<spacedim, Value>::value(const Point &p, const ElementAccessor<spacedim> &elm)
177 {
178  switch (elm.dim()) {
179  case 0:
180  return value_handler0_.value(p, elm);
181  case 1:
182  return value_handler1_.value(p, elm);
183  case 2:
184  return value_handler2_.value(p, elm);
185  case 3:
186  return value_handler3_.value(p, elm);
187  default:
188  ASSERT(false).error("Invalid element dimension!");
189  }
190 
191  return this->r_value_;
192 }
193 
194 
195 
196 /**
197  * Returns std::vector of scalar values in several points at once.
198  */
199 template <int spacedim, class Value>
202 {
203  ASSERT_EQ( point_list.size(), value_list.size() ).error();
204 
205  switch (elm.dim()) {
206  case 0:
207  value_handler0_.value_list(point_list, elm, value_list);
208  break;
209  case 1:
210  value_handler1_.value_list(point_list, elm, value_list);
211  break;
212  case 2:
213  value_handler2_.value_list(point_list, elm, value_list);
214  break;
215  case 3:
216  value_handler3_.value_list(point_list, elm, value_list);
217  break;
218  default:
219  ASSERT(false).error("Invalid element dimension!");
220  }
221 }
222 
223 
224 
225 template <int spacedim, class Value>
227  this->init_unit_conversion_coefficient(rec, init_data);
228  this->in_rec_ = rec;
229  flags_ = init_data.flags_;
230 
231 
232  // read data from input record
233  reader_file_ = FilePath( rec.val<FilePath>("mesh_data_file") );
234  field_name_ = rec.val<std::string>("field_name");
235  if (! rec.opt_val<OutputTime::DiscreteSpace>("input_discretization", discretization_) ) {
236  discretization_ = OutputTime::DiscreteSpace::UNDEFINED;
237  }
238  if (! rec.opt_val<DataInterpolation>("interpolation", interpolation_) ) {
239  interpolation_ = DataInterpolation::equivalent_msh;
240  }
241  if (! rec.opt_val("default_value", default_value_) ) {
242  default_value_ = numeric_limits<double>::signaling_NaN();
243  }
244 }
245 
246 
247 
248 template <int spacedim, class Value>
249 void FieldFE<spacedim, Value>::set_mesh(const Mesh *mesh, bool boundary_domain) {
250  // Mesh can be set only for field initialized from input.
252  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
253  this->boundary_domain_ = boundary_domain;
254  this->make_dof_handler(mesh);
255  switch (this->interpolation_) {
256  case DataInterpolation::identic_msh:
258  break;
259  case DataInterpolation::equivalent_msh:
260  if (!ReaderCache::check_compatible_mesh( reader_file_, const_cast<Mesh &>(*mesh) )) {
261  this->interpolation_ = DataInterpolation::gauss_p0;
262  WarningOut().fmt("Source mesh of FieldFE '{}' is not compatible with target mesh.\nInterpolation of input data will be changed to 'P0_gauss'.\n",
263  field_name_);
264  }
265  break;
266  case DataInterpolation::gauss_p0:
267  {
268  auto source_mesh = ReaderCache::get_mesh(reader_file_);
269  ReaderCache::get_element_ids(reader_file_, *(source_mesh.get()) );
270  break;
271  }
272  case DataInterpolation::interp_p0:
273  {
274  auto source_msh = ReaderCache::get_mesh(reader_file_);
275  ReaderCache::get_element_ids(reader_file_, *(source_msh.get()) );
276  if (!boundary_domain) {
277  this->interpolation_ = DataInterpolation::gauss_p0;
278  WarningOut().fmt("Interpolation 'P0_intersection' of FieldFE '{}' can't be used on bulk region.\nIt will be changed to 'P0_gauss'.\n", field_name_);
279  }
280  break;
281  }
282  }
283  }
284 }
285 
286 
287 
288 template <int spacedim, class Value>
290  ASSERT(this->boundary_domain_);
291 
292  auto bc_mesh = dh_->mesh()->get_bc_mesh();
293  unsigned int n_comp = this->value_.n_rows() * this->value_.n_cols();
294  boundary_dofs_ = std::make_shared< std::vector<LongIdx> >( n_comp * bc_mesh->n_elements() );
295  std::vector<LongIdx> &in_vec = *( boundary_dofs_.get() );
296  unsigned int j = 0; // actual index to boundary_dofs_ vector
297 
298  for (auto ele : bc_mesh->elements_range()) {
299  LongIdx elm_shift = n_comp * ele.idx();
300  for (unsigned int i=0; i<n_comp; ++i, ++j) {
301  in_vec[j] = elm_shift + i;
302  }
303  }
304 
309 
311 }
312 
313 
314 
315 template <int spacedim, class Value>
317  // temporary solution - these objects will be set through FieldCommon
318  switch (this->value_.n_rows() * this->value_.n_cols()) { // by number of components
319  case 1: { // scalar
320  fe0_ = new FE_P_disc<0>(0);
321  fe1_ = new FE_P_disc<1>(0);
322  fe2_ = new FE_P_disc<2>(0);
323  fe3_ = new FE_P_disc<3>(0);
324  break;
325  }
326  case 3: { // vector
327  std::shared_ptr< FiniteElement<0> > fe0_ptr = std::make_shared< FE_P_disc<0> >(0);
328  std::shared_ptr< FiniteElement<1> > fe1_ptr = std::make_shared< FE_P_disc<1> >(0);
329  std::shared_ptr< FiniteElement<2> > fe2_ptr = std::make_shared< FE_P_disc<2> >(0);
330  std::shared_ptr< FiniteElement<3> > fe3_ptr = std::make_shared< FE_P_disc<3> >(0);
331  fe0_ = new FESystem<0>(fe0_ptr, FEType::FEVector, 3);
332  fe1_ = new FESystem<1>(fe1_ptr, FEType::FEVector, 3);
333  fe2_ = new FESystem<2>(fe2_ptr, FEType::FEVector, 3);
334  fe3_ = new FESystem<3>(fe3_ptr, FEType::FEVector, 3);
335  break;
336  }
337  case 9: { // tensor
338  std::shared_ptr< FiniteElement<0> > fe0_ptr = std::make_shared< FE_P_disc<0> >(0);
339  std::shared_ptr< FiniteElement<1> > fe1_ptr = std::make_shared< FE_P_disc<1> >(0);
340  std::shared_ptr< FiniteElement<2> > fe2_ptr = std::make_shared< FE_P_disc<2> >(0);
341  std::shared_ptr< FiniteElement<3> > fe3_ptr = std::make_shared< FE_P_disc<3> >(0);
342  fe0_ = new FESystem<0>(fe0_ptr, FEType::FETensor, 9);
343  fe1_ = new FESystem<1>(fe1_ptr, FEType::FETensor, 9);
344  fe2_ = new FESystem<2>(fe2_ptr, FEType::FETensor, 9);
345  fe3_ = new FESystem<3>(fe3_ptr, FEType::FETensor, 9);
346  break;
347  }
348  default:
349  ASSERT(false).error("Should not happen!\n");
350  }
351 
352  DOFHandlerMultiDim dh_par( const_cast<Mesh &>(*mesh) );
353  std::shared_ptr<DiscreteSpace> ds = std::make_shared<EqualOrderDiscreteSpace>( &const_cast<Mesh &>(*mesh), fe0_, fe1_, fe2_, fe3_);
354  dh_par.distribute_dofs(ds);
355  dh_ = dh_par.sequential();
356  unsigned int ndofs = dh_->max_elem_dofs();
357  dof_indices_.resize(ndofs);
358 
359  if (this->boundary_domain_) fill_boundary_dofs(); // temporary solution for boundary mesh
360  else data_vec_ = VectorMPI::sequential( dh_->n_global_dofs() ); // allocate data_vec_
361 
362  // initialization data of value handlers
363  FEValueInitData init_data;
364  init_data.dh = dh_;
365  init_data.data_vec = data_vec_;
366  init_data.ndofs = ndofs;
367  init_data.n_comp = this->n_comp();
368  init_data.comp_index = 0;
369 
370  // initialize value handler objects
371  value_handler0_.initialize(init_data);
372  value_handler1_.initialize(init_data);
373  value_handler2_.initialize(init_data);
374  value_handler3_.initialize(init_data);
375 }
376 
377 
378 
379 template <int spacedim, class Value>
381  // Time can be set only for field initialized from input.
383  ASSERT(field_name_ != "").error("Uninitialized FieldFE, did you call init_from_input()?\n");
384  ASSERT_PTR(dh_)(field_name_).error("Null target mesh pointer of finite element field, did you call set_mesh()?\n");
385  if ( reader_file_ == FilePath() ) return false;
386 
387  unsigned int n_components = this->value_.n_rows() * this->value_.n_cols();
388  double time_unit_coef = time.read_coef(in_rec_.find<string>("time_unit"));
389  double time_shift = time.read_time( in_rec_.find<Input::Tuple>("read_time_shift") );
390  double read_time = (time.end()+time_shift) / time_unit_coef;
391  BaseMeshReader::HeaderQuery header_query(field_name_, read_time, this->discretization_, dh_->hash());
392  ReaderCache::get_reader(reader_file_)->find_header(header_query);
393  // TODO: use default and check NaN values in data_vec
394 
395  unsigned int n_entities;
396  bool is_native = (header_query.discretization == OutputTime::DiscreteSpace::NATIVE_DATA);
397  bool boundary;
398  if (is_native || this->interpolation_==DataInterpolation::identic_msh || this->interpolation_==DataInterpolation::equivalent_msh) {
399  n_entities = dh_->mesh()->n_elements();
400  boundary = this->boundary_domain_;
401  } else {
402  n_entities = ReaderCache::get_mesh(reader_file_)->n_elements();
403  boundary = false;
404  }
405  auto input_data_cache = ReaderCache::get_reader(reader_file_)->template get_element_data<double>(n_entities, n_components,
406  boundary, this->component_idx_);
407  CheckResult checked_data = ReaderCache::get_reader(reader_file_)->scale_and_check_limits(field_name_,
409 
410 
411  if (checked_data == CheckResult::not_a_number) {
412  THROW( ExcUndefElementValue() << EI_Field(field_name_) );
413  }
414 
415  if (is_native || this->interpolation_==DataInterpolation::identic_msh || this->interpolation_==DataInterpolation::equivalent_msh) {
416  this->calculate_native_values(input_data_cache);
417  } else if (this->interpolation_==DataInterpolation::gauss_p0) {
418  this->interpolate_gauss(input_data_cache);
419  } else { // DataInterpolation::interp_p0
420  this->interpolate_intersection(input_data_cache);
421  }
422 
423  return true;
424  } else return false;
425 
426 }
427 
428 
429 template <int spacedim, class Value>
431 {
432  static const unsigned int quadrature_order = 4; // parameter of quadrature
433  std::shared_ptr<Mesh> source_mesh = ReaderCache::get_mesh(reader_file_);
434  std::vector<unsigned int> searched_elements; // stored suspect elements in calculating the intersection
435  std::vector<arma::vec::fixed<3>> q_points; // real coordinates of quadrature points
436  std::vector<double> q_weights; // weights of quadrature points
437  unsigned int quadrature_size=0; // size of quadrature point and weight vector
438  std::vector<double> sum_val(dh_->max_elem_dofs()); // sum of value of one quadrature point
439  unsigned int elem_count; // count of intersect (source) elements of one quadrature point
440  std::vector<double> elem_value(dh_->max_elem_dofs()); // computed value of one (target) element
441  bool contains; // sign if source element contains quadrature point
442 
443  {
444  // set size of vectors to maximal count of quadrature points
445  QGauss quad(3, quadrature_order);
446  q_points.resize(quad.size());
447  q_weights.resize(quad.size());
448  }
449 
450  Mesh *mesh;
451  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
452  else mesh = dh_->mesh();
453  for (auto ele : mesh->elements_range()) {
454  std::fill(elem_value.begin(), elem_value.end(), 0.0);
455  switch (ele->dim()) {
456  case 0:
457  quadrature_size = 1;
458  q_points[0] = ele.node(0)->point();
459  q_weights[0] = 1.0;
460  break;
461  case 1:
462  quadrature_size = value_handler1_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
463  break;
464  case 2:
465  quadrature_size = value_handler2_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
466  break;
467  case 3:
468  quadrature_size = value_handler3_.compute_quadrature(q_points, q_weights, ele, quadrature_order);
469  break;
470  }
471  searched_elements.clear();
472  source_mesh->get_bih_tree().find_bounding_box(ele.bounding_box(), searched_elements);
473 
474  for (unsigned int i=0; i<quadrature_size; ++i) {
475  std::fill(sum_val.begin(), sum_val.end(), 0.0);
476  elem_count = 0;
477  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++) {
478  ElementAccessor<3> elm = source_mesh->element_accessor(*it);
479  contains=false;
480  switch (elm->dim()) {
481  case 0:
482  contains = arma::norm(elm.node(0)->point()-q_points[i], 2) < 4*std::numeric_limits<double>::epsilon();
483  break;
484  case 1:
485  contains = value_handler1_.get_mapping()->contains_point(q_points[i], elm);
486  break;
487  case 2:
488  contains = value_handler2_.get_mapping()->contains_point(q_points[i], elm);
489  break;
490  case 3:
491  contains = value_handler3_.get_mapping()->contains_point(q_points[i], elm);
492  break;
493  default:
494  ASSERT(false).error("Invalid element dimension!");
495  }
496  if ( contains ) {
497  // projection point in element
498  unsigned int index = sum_val.size() * (*it);
499  for (unsigned int j=0; j < sum_val.size(); j++) {
500  sum_val[j] += (*data_vec)[index+j];
501  }
502  ++elem_count;
503  }
504  }
505 
506  if (elem_count > 0) {
507  for (unsigned int j=0; j < sum_val.size(); j++) {
508  elem_value[j] += (sum_val[j] / elem_count) * q_weights[i];
509  }
510  }
511  }
512 
514  else {
515  DHCellAccessor cell = dh_->cell_accessor_from_element(ele.idx());
517  }
518  for (unsigned int i=0; i < elem_value.size(); i++) {
520  data_vec_[dof_indices_[i]] = elem_value[i] * this->unit_conversion_coefficient_;
521  }
522  }
523 }
524 
525 
526 template <int spacedim, class Value>
528 {
529  std::shared_ptr<Mesh> source_mesh = ReaderCache::get_mesh(reader_file_);
530  std::vector<unsigned int> searched_elements; // stored suspect elements in calculating the intersection
531  std::vector<double> value(dh_->max_elem_dofs());
532  double total_measure;
533  double measure = 0;
534 
535  Mesh *mesh;
536  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
537  else mesh = dh_->mesh();
538  for (auto elm : mesh->elements_range()) {
539  if (elm.dim() == 3) {
540  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
541  }
542 
543  double epsilon = 4* numeric_limits<double>::epsilon() * elm.measure();
544 
545  // gets suspect elements
546  if (elm.dim() == 0) {
547  searched_elements.clear();
548  source_mesh->get_bih_tree().find_point(elm.node(0)->point(), searched_elements);
549  } else {
550  BoundingBox bb = elm.bounding_box();
551  searched_elements.clear();
552  source_mesh->get_bih_tree().find_bounding_box(bb, searched_elements);
553  }
554 
555  // set zero values of value object
556  std::fill(value.begin(), value.end(), 0.0);
557  total_measure=0.0;
558 
559  START_TIMER("compute_pressure");
560  ADD_CALLS(searched_elements.size());
561 
562 
563  MappingP1<3,3> mapping;
564 
565  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++)
566  {
567  ElementAccessor<3> ele = source_mesh->element_accessor(*it);
568  if (ele->dim() == 3) {
569  // get intersection (set measure = 0 if intersection doesn't exist)
570  switch (elm.dim()) {
571  case 0: {
572  arma::vec::fixed<3> real_point = elm.node(0)->point();
573  arma::mat::fixed<3, 4> elm_map = mapping.element_map(ele);
574  arma::vec::fixed<4> unit_point = mapping.project_real_to_unit(real_point, elm_map);
575 
576  measure = (std::fabs(arma::sum( unit_point )-1) <= 1e-14
577  && arma::min( unit_point ) >= 0)
578  ? 1.0 : 0.0;
579  break;
580  }
581  case 1: {
583  ComputeIntersection<1,3> CI(elm, ele, source_mesh.get());
584  CI.init();
585  CI.compute(is);
586 
587  IntersectionLocal<1,3> ilc(is);
588  measure = ilc.compute_measure() * elm.measure();
589  break;
590  }
591  case 2: {
593  ComputeIntersection<2,3> CI(elm, ele, source_mesh.get());
594  CI.init();
595  CI.compute(is);
596 
597  IntersectionLocal<2,3> ilc(is);
598  measure = 2 * ilc.compute_measure() * elm.measure();
599  break;
600  }
601  }
602 
603  //adds values to value_ object if intersection exists
604  if (measure > epsilon) {
605  unsigned int index = value.size() * (*it);
606  std::vector<double> &vec = *( data_vec.get() );
607  for (unsigned int i=0; i < value.size(); i++) {
608  value[i] += vec[index+i] * measure;
609  }
610  total_measure += measure;
611  }
612  }
613  }
614 
615  // computes weighted average, store it to data vector
616  if (total_measure > epsilon) {
619  else {
620  DHCellAccessor cell = dh_->cell_accessor_from_element(elm.idx());
622  }
623  for (unsigned int i=0; i < value.size(); i++) {
624  (*data_vector)[ dof_indices_[i] ] = value[i] / total_measure;
625  }
626  } else {
627  WarningOut().fmt("Processed element with idx {} is out of source mesh!\n", elm.idx());
628  }
629  END_TIMER("compute_pressure");
630 
631  }
632 }
633 
634 
635 template <int spacedim, class Value>
637 {
638  // Same algorithm as in output of Node_data. Possibly code reuse.
639  unsigned int dof_size, data_vec_i;
640  std::vector<unsigned int> count_vector(data_vec_.size(), 0);
643 
644  // iterate through elements, assembly global vector and count number of writes
645  Mesh *mesh;
646  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
647  else mesh = dh_->mesh();
648  for (auto ele : mesh->elements_range()) { // remove special case for rank == 0 - necessary for correct output
649  if (this->boundary_domain_) dof_size = value_handler1_.get_dof_indices( ele, dof_indices_ );
650  else dof_size = dh_->cell_accessor_from_element(ele.idx()).get_loc_dof_indices( dof_indices_ );
651  data_vec_i = ele.idx() * dof_indices_.size();
652  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
653  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
654  ++count_vector[ dof_indices_[i] ];
655  }
656  }
657 
658  // iterate through cells, assembly global vector and count number of writes - prepared solution for further development
659  /*for (auto cell : dh_->own_range()) {
660  dof_size = cell.get_loc_dof_indices(dof_indices_);
661  data_vec_i = cell.elm_idx() * dof_indices_.size();
662  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
663  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
664  ++count_vector[ dof_indices_[i] ];
665  }
666  }*/
667 
668  // compute averages of values
669  for (unsigned int i=0; i<data_vec_.size(); ++i) {
670  if (count_vector[i]>0) (*data_vector)[i] /= count_vector[i];
671  }
672 }
673 
674 
675 template <int spacedim, class Value>
677  ASSERT_EQ(output_data_cache.n_values() * output_data_cache.n_comp(), dh_->distr()->lsize()).error();
678  ASSERT_EQ(output_data_cache.n_comp(), dof_indices_.size()).error();
679  double loc_values[output_data_cache.n_comp()];
680  unsigned int i, dof_filled_size;
681 
683  for (auto dh_cell : dh_->own_range()) {
684  dof_filled_size = dh_cell.get_loc_dof_indices(dof_indices_);
685  for (i=0; i<dof_filled_size; ++i) loc_values[i] = (*data_vec)[ dof_indices_[i] ];
686  for ( ; i<output_data_cache.n_comp(); ++i) loc_values[i] = numeric_limits<double>::signaling_NaN();
687  output_data_cache.store_value( dh_cell.local_idx(), loc_values );
688  }
689 
690  output_data_cache.set_dof_handler_hash( dh_->hash() );
691 }
692 
693 
694 
695 template <int spacedim, class Value>
696 inline unsigned int FieldFE<spacedim, Value>::data_size() const {
697  return data_vec_.size();
698 }
699 
700 
701 
702 template <int spacedim, class Value>
704 {}
705 
706 
707 // 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:61
virtual ~FieldFE()
Destructor.
Definition: field_fe.cc:703
void init_unit_conversion_coefficient(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Init value of unit_conversion_coefficient_ from input.
unsigned int size() const
Return size of output data.
Definition: vector_mpi.hh:186
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:200
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:430
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.
unsigned int n_values() const
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:125
Abstract linear system class.
Definition: balance.hh:37
unsigned int get_loc_dof_indices(std::vector< LongIdx > &indices) const
Returns the indices of dofs associated to the cell on the local process.
FieldFlag::Flags flags_
FEValueHandler< 2, spacedim, Value > value_handler2_
Value handler that allows get value of 2D elements.
Definition: field_fe.hh:182
VectorMPI data_vec_
Store data of Field.
Definition: field_fe.hh:173
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:303
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:76
Iterator< Ret > find(const string &key) const
void initialize(FEValueInitData init_data)
Initialize data members.
Cell accessor allow iterate over DOF handler cells.
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.
Mat< double, N, 1 > vec
Definition: armor.hh:211
Class FESystem for compound finite elements.
VectorDataPtr data_ptr()
Getter for shared pointer of output data.
Definition: vector_mpi.hh:114
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Definition: field_fe.cc:249
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
#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:380
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:289
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:304
Symmetric Gauss-Legendre quadrature formulae on simplices.
unsigned int data_size() const
Definition: field_fe.cc:696
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:196
unsigned int dim() const
Definition: elements.h:123
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:101
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:93
void resize(unsigned int local_size)
Definition: vector_mpi.hh:76
#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:151
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:527
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:503
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_fe.cc:176
virtual Range< ElementAccessor< 3 > > elements_range() const
Returns range of bulk elements.
Definition: mesh.cc:1053
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.
VectorMPI set_fe_data(std::shared_ptr< DOFHandlerMultiDim > dh, unsigned int component_index=0, VectorMPI dof_values=VectorMPI::sequential(0))
Definition: field_fe.cc:136
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:216
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.
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:336
const Selection & close() const
Close the Selection, no more values can be added.
static VectorMPI sequential(unsigned int size)
Definition: vector_mpi.hh:67
FieldFE(unsigned int n_comp=0)
Definition: field_fe.cc:127
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:65
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Definition: field_fe.cc:226
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
VectorMPI data_vec
Store data of Field.
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:412
unsigned int n_comp() const
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:156
bool contains_point(arma::vec point, ElementAccessor< 3 > elm)
Test if element contains given point.
Definition: mapping_p1.cc:305
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:45
unsigned int n_comp
number of components
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:85
void calculate_native_values(ElementDataCache< double >::ComponentDataPtr data_cache)
Calculate native data over all elements of target mesh.
Definition: field_fe.cc:636
FieldFlag::Flags flags_
Field flags.
Definition: field_fe.hh:212
arma::vec3 & point()
Definition: nodes.hh:67
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:316
Implementation of range helper class.
void native_data_to_cache(ElementDataCache< double > &output_data_cache)
Definition: field_fe.cc:676
#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:328
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
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:300
const Node * node(unsigned int ni) const
Definition: accessors.hh:198