Flow123d  release_3.0.0-916-g95df358
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; // 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<3> quad(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, measure;
533 
534  Mesh *mesh;
535  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
536  else mesh = dh_->mesh();
537  for (auto elm : mesh->elements_range()) {
538  if (elm.dim() == 3) {
539  xprintf(Err, "Dimension of element in target mesh must be 0, 1 or 2! elm.idx() = %d\n", elm.idx());
540  }
541 
542  double epsilon = 4* numeric_limits<double>::epsilon() * elm.measure();
543 
544  // gets suspect elements
545  if (elm.dim() == 0) {
546  searched_elements.clear();
547  source_mesh->get_bih_tree().find_point(elm.node(0)->point(), searched_elements);
548  } else {
549  BoundingBox bb = elm.bounding_box();
550  searched_elements.clear();
551  source_mesh->get_bih_tree().find_bounding_box(bb, searched_elements);
552  }
553 
554  // set zero values of value object
555  std::fill(value.begin(), value.end(), 0.0);
556  total_measure=0.0;
557 
558  START_TIMER("compute_pressure");
559  ADD_CALLS(searched_elements.size());
560 
561 
562  MappingP1<3,3> mapping;
563 
564  for (std::vector<unsigned int>::iterator it = searched_elements.begin(); it!=searched_elements.end(); it++)
565  {
566  ElementAccessor<3> ele = source_mesh->element_accessor(*it);
567  if (ele->dim() == 3) {
568  // get intersection (set measure = 0 if intersection doesn't exist)
569  switch (elm.dim()) {
570  case 0: {
571  arma::vec::fixed<3> real_point = elm.node(0)->point();
572  arma::mat::fixed<3, 4> elm_map = mapping.element_map(ele);
573  arma::vec::fixed<4> unit_point = mapping.project_real_to_unit(real_point, elm_map);
574 
575  measure = (std::fabs(arma::sum( unit_point )-1) <= 1e-14
576  && arma::min( unit_point ) >= 0)
577  ? 1.0 : 0.0;
578  break;
579  }
580  case 1: {
582  ComputeIntersection<1,3> CI(elm, ele, source_mesh.get());
583  CI.init();
584  CI.compute(is);
585 
586  IntersectionLocal<1,3> ilc(is);
587  measure = ilc.compute_measure() * elm.measure();
588  break;
589  }
590  case 2: {
592  ComputeIntersection<2,3> CI(elm, ele, source_mesh.get());
593  CI.init();
594  CI.compute(is);
595 
596  IntersectionLocal<2,3> ilc(is);
597  measure = 2 * ilc.compute_measure() * elm.measure();
598  break;
599  }
600  }
601 
602  //adds values to value_ object if intersection exists
603  if (measure > epsilon) {
604  unsigned int index = value.size() * (*it);
605  std::vector<double> &vec = *( data_vec.get() );
606  for (unsigned int i=0; i < value.size(); i++) {
607  value[i] += vec[index+i] * measure;
608  }
609  total_measure += measure;
610  }
611  }
612  }
613 
614  // computes weighted average, store it to data vector
615  if (total_measure > epsilon) {
618  else {
619  DHCellAccessor cell = dh_->cell_accessor_from_element(elm.idx());
621  }
622  for (unsigned int i=0; i < value.size(); i++) {
623  (*data_vector)[ dof_indices_[i] ] = value[i] / total_measure;
624  }
625  } else {
626  WarningOut().fmt("Processed element with idx {} is out of source mesh!\n", elm.idx());
627  }
628  END_TIMER("compute_pressure");
629 
630  }
631 }
632 
633 
634 template <int spacedim, class Value>
636 {
637  // Same algorithm as in output of Node_data. Possibly code reuse.
638  unsigned int dof_size, data_vec_i;
639  std::vector<unsigned int> count_vector(data_vec_.size(), 0);
642 
643  // iterate through elements, assembly global vector and count number of writes
644  Mesh *mesh;
645  if (this->boundary_domain_) mesh = dh_->mesh()->get_bc_mesh();
646  else mesh = dh_->mesh();
647  for (auto ele : mesh->elements_range()) { // remove special case for rank == 0 - necessary for correct output
648  if (this->boundary_domain_) dof_size = value_handler1_.get_dof_indices( ele, dof_indices_ );
649  else dof_size = dh_->cell_accessor_from_element(ele.idx()).get_loc_dof_indices( dof_indices_ );
650  data_vec_i = ele.idx() * dof_indices_.size();
651  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
652  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
653  ++count_vector[ dof_indices_[i] ];
654  }
655  }
656 
657  // iterate through cells, assembly global vector and count number of writes - prepared solution for further development
658  /*for (auto cell : dh_->own_range()) {
659  dof_size = cell.get_loc_dof_indices(dof_indices_);
660  data_vec_i = cell.elm_idx() * dof_indices_.size();
661  for (unsigned int i=0; i<dof_size; ++i, ++data_vec_i) {
662  (*data_vector)[ dof_indices_[i] ] += (*data_cache)[data_vec_i];
663  ++count_vector[ dof_indices_[i] ];
664  }
665  }*/
666 
667  // compute averages of values
668  for (unsigned int i=0; i<data_vec_.size(); ++i) {
669  if (count_vector[i]>0) (*data_vector)[i] /= count_vector[i];
670  }
671 }
672 
673 
674 template <int spacedim, class Value>
676  ASSERT_EQ(output_data_cache.n_values() * output_data_cache.n_comp(), dh_->distr()->lsize()).error();
677  ASSERT_EQ(output_data_cache.n_comp(), dof_indices_.size()).error();
678  double loc_values[output_data_cache.n_comp()];
679  unsigned int i, dof_filled_size;
680 
682  for (auto dh_cell : dh_->own_range()) {
683  dof_filled_size = dh_cell.get_loc_dof_indices(dof_indices_);
684  for (i=0; i<dof_filled_size; ++i) loc_values[i] = (*data_vec)[ dof_indices_[i] ];
685  for ( ; i<output_data_cache.n_comp(); ++i) loc_values[i] = numeric_limits<double>::signaling_NaN();
686  output_data_cache.store_value( dh_cell.local_idx(), loc_values );
687  }
688 
689  output_data_cache.set_dof_handler_hash( dh_->hash() );
690 }
691 
692 
693 
694 template <int spacedim, class Value>
695 inline unsigned int FieldFE<spacedim, Value>::data_size() const {
696  return data_vec_.size();
697 }
698 
699 
700 
701 template <int spacedim, class Value>
703 {}
704 
705 
706 // 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:54
virtual ~FieldFE()
Destructor.
Definition: field_fe.cc:702
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:179
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:35
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:296
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.
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: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: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:303
Symmetric Gauss-Legendre quadrature formulae on simplices.
unsigned int data_size() const
Definition: field_fe.cc:695
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: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:152
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:501
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:1040
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: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.
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.
static VectorMPI sequential(unsigned int size)
Definition: vector_mpi.hh:67
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: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: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:45
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:635
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:675
#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
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