Flow123d  release_3.0.0-973-g92f55e826
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>
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();
142  data_vec_.zero_entries();
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.
251  if ( flags_.match(FieldFlag::equation_input) && flags_.match(FieldFlag::declare_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:
257  ReaderCache::get_element_ids(reader_file_, *mesh);
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 
305  value_handler0_.set_boundary_dofs_vector(boundary_dofs_);
306  value_handler1_.set_boundary_dofs_vector(boundary_dofs_);
307  value_handler2_.set_boundary_dofs_vector(boundary_dofs_);
308  value_handler3_.set_boundary_dofs_vector(boundary_dofs_);
309 
310  data_vec_.resize(boundary_dofs_->size());
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.
382  if ( flags_.match(FieldFlag::equation_input) && flags_.match(FieldFlag::declare_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_,
408  this->unit_conversion_coefficient_, default_value_);
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 
513  if (this->boundary_domain_) value_handler1_.get_dof_indices( ele, dof_indices_);
514  else {
515  DHCellAccessor cell = dh_->cell_accessor_from_element(ele.idx());
516  cell.get_loc_dof_indices(dof_indices_);
517  }
518  for (unsigned int i=0; i < elem_value.size(); i++) {
519  ASSERT_LT_DBG( dof_indices_[i], (int)data_vec_.size());
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) {
616  VectorMPI::VectorDataPtr data_vector = data_vec_.data_ptr();
617  if (this->boundary_domain_) value_handler1_.get_dof_indices( elm, dof_indices_ );
618  else {
619  DHCellAccessor cell = dh_->cell_accessor_from_element(elm.idx());
620  cell.get_loc_dof_indices( dof_indices_ );
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);
640  data_vec_.zero_entries();
641  VectorMPI::VectorDataPtr data_vector = data_vec_.data_ptr();
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_->get_loc_dof_indices( ele, 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 
681  VectorMPI::VectorDataPtr data_vec = data_vec_.data_ptr();
682  for (auto dh_cell : dh_->own_range()) {
683  dof_filled_size = dh_->get_loc_dof_indices(dh_cell.elm(), 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
FieldFE::data_size
unsigned int data_size() const
Definition: field_fe.cc:695
ElementAccessor::dim
unsigned int dim() const
Definition: accessors.hh:87
FieldFE::make_dof_handler
void make_dof_handler(const Mesh *mesh)
Create DofHandler object.
Definition: field_fe.cc:316
FieldFE::FieldFE
FieldFE(unsigned int n_comp=0)
Definition: field_fe.cc:127
vector_mpi.hh
ComputeIntersection< 2, 3 >
Class for 2D-2D intersections.
Definition: compute_intersection.hh:462
Quadrature::size
const unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:139
FieldFE::interpolate_gauss
void interpolate_gauss(ElementDataCache< double >::ComponentDataPtr data_vec)
Interpolate data (use Gaussian distribution) over all elements of target mesh.
Definition: field_fe.cc:430
ElementDataCache
Definition: element_data_cache.hh:44
ASSERT
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library.
Definition: asserts.hh:346
DHCellAccessor::get_loc_dof_indices
unsigned int get_loc_dof_indices(std::vector< LongIdx > &indices) const
Returns the indices of dofs associated to the cell on the local process.
Definition: dh_cell_accessor.hh:321
FieldFE::DataInterpolation
DataInterpolation
Definition: field_fe.hh:59
LongIdx
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
Definition: long_idx.hh:22
Element::dim
unsigned int dim() const
Definition: elements.h:124
Mesh::elements_range
virtual Range< ElementAccessor< 3 > > elements_range() const
Returns range of bulk elements.
Definition: mesh.cc:1116
VectorMPI::sequential
static VectorMPI sequential(unsigned int size)
Definition: vector_mpi.hh:67
bc_mesh.hh
VectorMPI::zero_entries
void zero_entries()
Definition: vector_mpi.hh:125
ComputeIntersection< 1, 3 >
Definition: compute_intersection.hh:345
Input::Record::val
const Ret val(const string &key) const
Definition: accessors_impl.hh:31
ReaderCache::get_element_ids
static void get_element_ids(const FilePath &file_path, const Mesh &mesh)
Definition: reader_cache.cc:80
Input::Type::Selection::close
const Selection & close() const
Close the Selection, no more values can be added.
Definition: type_selection.cc:65
value
static constexpr bool value
Definition: json.hpp:87
IntersectionLocal::compute_measure
double compute_measure() const override
Computes the relative measure of intersection object.
Definition: intersection_local.cc:53
FilePath
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
VectorMPI::resize
void resize(unsigned int local_size)
Definition: vector_mpi.hh:76
ElementDataCacheBase::n_comp
unsigned int n_comp() const
Definition: element_data_cache_base.hh:145
Input::Type::Double
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:534
FLOW123D_FORCE_LINK_IN_CHILD
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
Definition: global_defs.h:180
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
std::vector
Definition: doxy_dummy_defs.hh:7
Input::Type::Default::read_time
static Default read_time(const std::string &description)
The factory function to make an default value that will be specified at the time when a key will be r...
Definition: type_record.hh:97
ElementAccessor
Definition: fe_value_handler.hh:29
reader_cache.hh
ElementAccessor::node
const Node * node(unsigned int ni) const
Definition: accessors.hh:145
field_fe.hh
TimeStep::read_time
double read_time(Input::Iterator< Input::Tuple > time_it, double default_time=std::numeric_limits< double >::quiet_NaN()) const
Definition: time_governor.cc:238
ElementDataCacheBase::set_dof_handler_hash
void set_dof_handler_hash(std::size_t hash)
Definition: element_data_cache_base.hh:164
msh_gmshreader.h
fe_system.hh
Class FESystem for compound finite elements.
fe_p.hh
Definitions of basic Lagrangean finite elements with polynomial shape functions.
BoundingBox
Bounding box in 3d ambient space.
Definition: bounding_box.hh:54
ComputeIntersection< 2, 3 >::init
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
Definition: compute_intersection.cc:1056
FieldFE::init_from_input
virtual void init_from_input(const Input::Record &rec, const struct FieldAlgoBaseInitData &init_data)
Definition: field_fe.cc:226
Input::Type::Default
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
Input::Type::Record::derive_from
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:195
FieldFE::value
virtual const Value::return_type & value(const Point &p, const ElementAccessor< spacedim > &elm)
Definition: field_fe.cc:176
dh_cell_accessor.hh
FieldFE::get_interp_selection_input_type
static const Input::Type::Selection & get_interp_selection_input_type()
Definition: field_fe.cc:98
accessors.hh
FieldFE::set_mesh
void set_mesh(const Mesh *mesh, bool boundary_domain) override
Definition: field_fe.cc:249
TimeStep::end
double end() const
Definition: time_governor.hh:151
Input::Record
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
MappingP1::project_real_to_unit
BaryPoint project_real_to_unit(const RealPoint &point, const ElementMap &map) const
Definition: mapping_p1.cc:275
sys_profiler.hh
FEValueInitData::dh
std::shared_ptr< DOFHandlerMultiDim > dh
DOF handler object.
Definition: fe_value_handler.hh:36
quadrature_lib.hh
Definitions of particular quadrature rules on simplices.
DOFHandlerMultiDim
Provides the numbering of the finite element degrees of freedom on the computational mesh.
Definition: dofhandler.hh:152
Mesh::get_bc_mesh
BCMesh * get_bc_mesh()
Create boundary mesh if doesn't exist and return it.
Definition: mesh.cc:1269
FieldAlgoBaseInitData
Helper struct stores data for initizalize descentants of FieldAlgorithmBase.
Definition: field_algo_base.hh:79
xprintf
#define xprintf(...)
Definition: system.hh:92
FieldFE::interpolate_intersection
void interpolate_intersection(ElementDataCache< double >::ComponentDataPtr data_vec)
Interpolate data (use intersection library) over all elements of target mesh.
Definition: field_fe.cc:527
TimeStep
Representation of one time step..
Definition: time_governor.hh:113
CheckResult
CheckResult
Return type of method that checked data stored in ElementDataCache (NaN values, limits)
Definition: element_data_cache.hh:36
VectorMPI::VectorDataPtr
std::shared_ptr< VectorData > VectorDataPtr
Definition: vector_mpi.hh:45
DOFHandlerMultiDim::distribute_dofs
void distribute_dofs(std::shared_ptr< DiscreteSpace > ds)
Distributes degrees of freedom on the mesh needed for the given discrete space.
Definition: dofhandler.cc:242
MappingP1::element_map
ElementMap element_map(ElementAccessor< 3 > elm) const
Definition: mapping_p1.cc:265
Input::Type::Default::obligatory
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:110
FETensor
@ FETensor
Definition: finite_element.hh:208
FEValueInitData::ndofs
unsigned int ndofs
number of dofs
Definition: fe_value_handler.hh:40
ASSERT_EQ
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
Definition: asserts.hh:327
Input::Record::opt_val
bool opt_val(const string &key, Ret &value) const
Definition: accessors_impl.hh:107
DOFHandlerMultiDim::sequential
std::shared_ptr< DOFHandlerMultiDim > sequential()
Returns sequential version of the current dof handler.
Definition: dofhandler.cc:54
Input::Type::Record::declare_key
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:501
Node::point
arma::vec3 & point()
Definition: nodes.hh:67
ComputeIntersection< 1, 3 >::init
void init()
Initializes lower dimensional objects. Sets correctly the pointers to Plucker coordinates and product...
Definition: compute_intersection.cc:812
FEVector
@ FEVector
Definition: finite_element.hh:205
Input::Type::Selection
Template for classes storing finite set of named values.
Definition: type_selection.hh:65
Input::Type::FileName::input
static FileName input()
The factory function for declaring type FileName for input files.
Definition: type_base.cc:525
Input::Type::Record::close
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
Input::Type
Definition: balance.hh:38
Input::Type::Record
Record type proxy class.
Definition: type_record.hh:182
FEValueInitData
Initialization structure of FEValueHandler class.
Definition: fe_value_handler.hh:33
ComputeIntersection< 1, 3 >::compute
unsigned int compute(std::vector< IPAux > &IP13s)
Computes intersection points for 1D-3D intersection. Computes lower dimensional CIs abscissa vs tetra...
Definition: compute_intersection.cc:833
QGauss
Symmetric Gauss-Legendre quadrature formulae on simplices.
Definition: quadrature_lib.hh:33
Value
@ Value
Definition: finite_element.hh:47
FieldAlgoBaseInitData::flags_
FieldFlag::Flags flags_
Definition: field_algo_base.hh:93
Err
@ Err
Definition: system.hh:64
not_a_number
@ not_a_number
Some value(s) is set to NaN.
Definition: element_data_cache.hh:39
intersection_aux.hh
Internal class representing intersection object.
FieldFE::native_data_to_cache
void native_data_to_cache(ElementDataCache< double > &output_data_cache)
Definition: field_fe.cc:675
input_type.hh
FieldFE
Definition: field.hh:56
Mesh
Definition: mesh.h:80
Input::Type::Record::copy_keys
Record & copy_keys(const Record &other)
Copy keys from other record.
Definition: type_record.cc:215
FieldAlgorithmBase
Definition: field_algo_base.hh:110
ElementDataCache::ComponentDataPtr
std::shared_ptr< std::vector< T > > ComponentDataPtr
Definition: element_data_cache.hh:46
Input::Type::String
Class for declaration of the input data that are in string format.
Definition: type_base.hh:582
DHCellAccessor
Definition: dh_cell_accessor.hh:36
BaseMeshReader::HeaderQuery::discretization
OutputTime::DiscreteSpace discretization
Flag determinate type of discrete of Field (typically is used for native data of VTK)
Definition: msh_basereader.hh:139
WarningOut
#define WarningOut()
Macro defining 'warning' record of log.
Definition: logger.hh:246
IntersectionAux
Internal auxiliary class representing intersection object of simplex<dimA> and simplex<dimB>.
Definition: compute_intersection.hh:49
INSTANCE_ALL
#define INSTANCE_ALL(field)
Definition: field_instances.hh:43
Input::Tuple
Accessor to the data with type Type::Tuple.
Definition: accessors.hh:411
FieldFE::Point
FieldAlgorithmBase< spacedim, Value >::Point Point
Definition: field_fe.hh:53
ReaderCache::check_compatible_mesh
static bool check_compatible_mesh(const FilePath &file_path, Mesh &mesh)
Definition: reader_cache.cc:73
fe_value_handler.hh
FieldFE::value_list
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
Definition: field_fe.cc:200
compute_intersection.hh
Fundamental simplicial intersections.
MappingP1< 3, 3 >
field_instances.hh
FieldFlag::equation_input
static constexpr Mask equation_input
The field is data parameter of the owning equation. (default on)
Definition: field_flag.hh:33
FieldFE::set_fe_data
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
IntersectionLocal< 1, 3 >
FieldFE::get_input_type
static const Input::Type::Record & get_input_type()
Implementation.
Definition: field_fe.cc:55
ASSERT_LT_DBG
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:299
FieldFE::calculate_native_values
void calculate_native_values(ElementDataCache< double >::ComponentDataPtr data_cache)
Calculate native data over all elements of target mesh.
Definition: field_fe.cc:635
ReaderCache::get_mesh
static std::shared_ptr< Mesh > get_mesh(const FilePath &file_path)
Definition: reader_cache.cc:40
ADD_CALLS
#define ADD_CALLS(n_calls)
Increase number of calls in actual timer.
Definition: sys_profiler.hh:190
FEValueInitData::data_vec
VectorMPI data_vec
Store data of Field.
Definition: fe_value_handler.hh:38
FieldFlag::declare_input
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
FieldFE::get_disc_selection_input_type
static const Input::Type::Selection & get_disc_selection_input_type()
Definition: field_fe.cc:86
FieldFE::set_time
bool set_time(const TimeStep &time) override
Definition: field_fe.cc:380
OutputTime::DiscreteSpace
DiscreteSpace
Definition: output_time.hh:104
FEValueInitData::comp_index
unsigned int comp_index
index of component (of vector_value/tensor_value)
Definition: fe_value_handler.hh:44
ReaderCache::get_reader
static std::shared_ptr< BaseMeshReader > get_reader(const FilePath &file_path)
Definition: reader_cache.cc:36
TimeGovernor::get_input_time_type
static const Input::Type::Tuple & get_input_time_type(double lower_bound=-std::numeric_limits< double >::max(), double upper_bound=std::numeric_limits< double >::max())
Definition: time_governor.cc:46
FieldFE::fill_boundary_dofs
void fill_boundary_dofs()
Definition: field_fe.cc:289
VectorMPI
Definition: vector_mpi.hh:42
Input::Type::Selection::add_value
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.
Definition: type_selection.cc:50
FieldFE::~FieldFE
virtual ~FieldFE()
Destructor.
Definition: field_fe.cc:702
ASSERT_PTR
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
ElementDataCacheBase::n_values
unsigned int n_values() const
Definition: element_data_cache_base.hh:131
Input::Type::Default::optional
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
START_TIMER
#define START_TIMER(tag)
Starts a timer with specified tag.
Definition: sys_profiler.hh:119
ComputeIntersection< 2, 3 >::compute
void compute(IntersectionAux< 2, 3 > &intersection)
Computes intersection points for 2D-3D intersection. Computes lower dimensional CIs: 1) 3x triangle s...
Definition: compute_intersection.cc:1116
FESystem
Compound finite element on dim dimensional simplex.
Definition: fe_system.hh:99
BaseMeshReader::HeaderQuery
Definition: msh_basereader.hh:132
ElementDataCache::store_value
void store_value(unsigned int idx, const T *value)
Definition: element_data_cache.cc:218
FE_P_disc< 0 >
VectorMPI::size
unsigned int size() const
Return size of output data.
Definition: vector_mpi.hh:179
END_TIMER
#define END_TIMER(tag)
Ends a timer with specified tag.
Definition: sys_profiler.hh:153
TimeStep::read_coef
double read_coef(Input::Iterator< std::string > unit_it) const
Definition: time_governor.cc:244
FEValueInitData::n_comp
unsigned int n_comp
number of components
Definition: fe_value_handler.hh:42
range_wrapper.hh
Implementation of range helper class.
intersection_local.hh
Classes with algorithms for computation of intersections of meshes.