Flow123d  release_2.2.0-914-gf1a3a4f
output_mesh.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 output_mesh.cc
15  * @brief Classes for auxiliary output mesh.
16  */
17 
18 #include "output_mesh.hh"
19 #include "output_element.hh"
20 #include "mesh/mesh.h"
21 #include "mesh/ref_element.hh"
22 #include "la/distribution.hh"
23 
24 
25 namespace IT=Input::Type;
26 
28  return IT::Record("OutputMesh", "Parameters of the refined output mesh.")
29  .declare_key("max_level", IT::Integer(1,20),IT::Default("3"),
30  "Maximal level of refinement of the output mesh.")
31  .declare_key("refine_by_error", IT::Bool(), IT::Default("false"),
32  "Set true for using error_control_field. Set false for global uniform refinement to max_level.")
33  .declare_key("error_control_field",IT::String(), IT::Default::optional(),
34  "Name of an output field, according to which the output mesh will be refined. The field must be a SCALAR one.")
35  .declare_key("refinement_error_tolerance",IT::Double(0.0), IT::Default("0.01"),
36  "Tolerance for element refinement by error. If tolerance is reached, refinement is stopped."
37  "Relative difference between error control field and its linear approximation on element is computed"
38  "and compared with tolerance.")
39  .close();
40 }
41 
43 :
44  orig_mesh_(&mesh),
45  max_level_(0),
47  refine_by_error_(false),
49 {
50 }
51 
52 
54 :
55  input_record_(in_rec),
56  orig_mesh_(&mesh),
57  max_level_(input_record_.val<int>("max_level")),
59  refine_by_error_(input_record_.val<bool>("refine_by_error")),
60  refinement_error_tolerance_(input_record_.val<double>("refinement_error_tolerance"))
61 {
62 }
63 
65 {
66 }
67 
69 {
71 // ASSERT_DBG(offsets_->n_values() > 0);
72  return OutputElementIterator(OutputElement(0, shared_from_this()));
73 }
74 
76 {
78 // ASSERT_DBG(offsets_->n_values() > 0);
79  return OutputElementIterator(OutputElement(offsets_->n_values(), shared_from_this()));
80 }
81 
82 
84 {
85  error_control_field_func_ = error_control_field_func;
86 }
87 
89 {
91  return offsets_->n_values();
92 }
93 
95 {
97  return nodes_->n_values();
98 }
99 
101 {
102  unsigned int elm_idx[1];
103  unsigned int node_idx[1];
104  unsigned int region_idx[1];
105  int partition[1];
106  elem_ids_ = std::make_shared< ElementDataCache<unsigned int> >("elements_ids", (unsigned int)1, 1, this->n_elements());
107  node_ids_ = std::make_shared< ElementDataCache<unsigned int> >("node_ids", (unsigned int)1, 1, this->n_nodes());
108  region_ids_ = std::make_shared< ElementDataCache<unsigned int> >("region_ids", (unsigned int)1, 1, this->n_elements());
109  partitions_ = std::make_shared< ElementDataCache<int> >("partitions", (unsigned int)1, 1, this->n_elements());
110  OutputElementIterator it = this->begin();
111  for (unsigned int i = 0; i < this->n_elements(); ++i, ++it) {
112  if (mesh_type_ == MeshType::orig) elm_idx[0] = orig_mesh_->element(it->idx()).id();
113  else elm_idx[0] = it->idx();
114  elem_ids_->store_value( i, elm_idx );
115 
116  region_idx[0] = orig_mesh_->element(it->idx())->region().id();
117  region_ids_->store_value( i, region_idx );
118 
119  partition[0] = orig_mesh_->element(it->idx())->pid;
120  partitions_->store_value( i, partition );
121 
122  std::vector< unsigned int > node_list = it->node_list();
123  for (unsigned int j = 0; j < it->n_nodes(); ++j) {
124  if (mesh_type_ == MeshType::orig) node_idx[0] = orig_mesh_->node_vector(node_list[j]).id();
125  else node_idx[0] = node_list[j];
126  node_ids_->store_value( node_list[j], node_idx );
127  }
128  }
129 }
130 
131 
133 {
134  return (nodes_ && connectivity_ && offsets_);
135 }
136 
137 
138 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
139 
140 
142 : OutputMeshBase(mesh)
143 {
144 }
145 
147 : OutputMeshBase(mesh, in_rec)
148 {
149 }
150 
151 
153 {
154 }
155 
156 
158 {
159  ASSERT( !is_created() ).error("Multiple initialization of OutputMesh!\n");
160 
161  DebugOut() << "Create outputmesh identical to computational one.";
162 
163  const unsigned int n_elements = orig_mesh_->n_elements(),
165 
166  nodes_ = std::make_shared<ElementDataCache<double>>("", (unsigned int)ElementDataCacheBase::N_VECTOR, 1, n_nodes);
167  unsigned int coord_id = 0, // coordinate id in vector
168  node_id = 0; // node id
169  auto &node_vec = *( nodes_->get_component_data(0).get() );
170  FOR_NODES(orig_mesh_, node) {
171  node->aux = node_id; // store node index in the auxiliary variable
172 
173  // use store value
174  node_vec[coord_id] = node->getX(); coord_id++;
175  node_vec[coord_id] = node->getY(); coord_id++;
176  node_vec[coord_id] = node->getZ(); coord_id++;
177  node_id++;
178  }
179 
180  orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_elements);
181 
182  offsets_ = std::make_shared<ElementDataCache<unsigned int>>("offsets", (unsigned int)ElementDataCacheBase::N_SCALAR, 1, n_elements);
183  Node* node;
184  unsigned int ele_id = 0,
185  connect_id = 0,
186  offset = 0, // offset of node indices of element in node vector
187  li; // local node index
188  auto &offset_vec = *( offsets_->get_component_data(0).get() );
189  FOR_ELEMENTS(orig_mesh_, ele) {
190  // increase offset by number of nodes of the simplicial element
191  offset += ele->dim() + 1;
192  offset_vec[ele_id] = offset;
193  (*orig_element_indices_)[ele_id] = ele_id;
194  ele_id++;
195  }
196 
197  const unsigned int n_connectivities = offset_vec[offset_vec.size()-1];
198  connectivity_ = std::make_shared<ElementDataCache<unsigned int>>("connectivity", (unsigned int)ElementDataCacheBase::N_SCALAR,
199  1, n_connectivities);
200  auto &connect_vec = *( connectivity_->get_component_data(0).get() );
201  FOR_ELEMENTS(orig_mesh_, ele) {
202  FOR_ELEMENT_NODES(ele, li) {
203  node = ele->node[li];
204  connect_vec[connect_id] = node->aux;
205  connect_id++;
206  }
207 
208  }
209 }
210 
212 {
213  ASSERT(0).error("Not implemented yet.");
214 }
215 
216 
218 {
219  ASSERT(0).error("Not implemented yet.");
220  return false;
221 }
222 
223 
225 {
226  ASSERT(0).error("Not implemented yet.");
227 }
228 
229 
230 
231 //////////////////////////////////////////////////////////////////////////////////////////////////////////////
232 
234 : OutputMeshBase(mesh)
235 {
236 }
237 
239 : OutputMeshBase(mesh, in_rec)
240 {
241 }
242 
243 
245 {
246 }
247 
248 
250 {
251  ASSERT( !is_created() ).error("Multiple initialization of OutputMesh!\n");
252 
253  ASSERT_DBG(orig_mesh_->n_nodes() > 0); //continuous data already computed
254 
255  if (nodes_) return; //already computed
256 
257  DebugOut() << "Create discontinuous outputmesh.";
258 
259  const unsigned int n_elements = orig_mesh_->n_elements();
260 
261  orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_elements);
262  offsets_ = std::make_shared<ElementDataCache<unsigned int>>("offsets", (unsigned int)ElementDataCacheBase::N_SCALAR, 1, n_elements);
263 
264  unsigned int ele_id = 0,
265  offset = 0, // offset of node indices of element in node vector
266  coord_id = 0, // coordinate id in vector
267  corner_id = 0, // corner index (discontinous node)
268  li = 0; // local node index
269 
270  auto &offset_vec = *( offsets_->get_component_data(0).get() );
271  FOR_ELEMENTS(orig_mesh_, ele) {
272  // increase offset by number of nodes of the simplicial element
273  offset += ele->dim() + 1;
274  offset_vec[ele_id] = offset;
275  (*orig_element_indices_)[ele_id] = ele_id;
276  ele_id++;
277  }
278 
279  // connectivity = for every element list the nodes => its length corresponds to discontinuous data
280  const unsigned int n_corners = offset_vec[offset_vec.size()-1];
281 
282  nodes_ = std::make_shared<ElementDataCache<double>>("", (unsigned int)ElementDataCacheBase::N_VECTOR, 1, n_corners);
283  connectivity_ = std::make_shared<ElementDataCache<unsigned int>>("connectivity", (unsigned int)ElementDataCacheBase::N_SCALAR,
284  1, n_corners);
285 
286  auto &node_vec = *( nodes_->get_component_data(0).get() );
287  auto &conn_vec = *( connectivity_->get_component_data(0).get() );
288  Node* node;
290  {
291  FOR_ELEMENT_NODES(ele, li)
292  {
293  node = ele->node[li];
294  node_vec[coord_id] = node->getX(); ++coord_id;
295  node_vec[coord_id] = node->getY(); ++coord_id;
296  node_vec[coord_id] = node->getZ(); ++coord_id;
297 
298  conn_vec[corner_id] = corner_id;
299  corner_id++;
300  }
301  }
302 
303  mesh_type_ = MeshType::discont;
304 }
305 
306 
308 {
309  DebugOut() << "Create refined discontinuous outputmesh.\n";
310  // initial guess of size: n_elements
311  nodes_ = std::make_shared<ElementDataCache<double>>("",(unsigned int)ElementDataCacheBase::N_VECTOR,1,0);
312  connectivity_ = std::make_shared<ElementDataCache<unsigned int>>("connectivity",(unsigned int)ElementDataCacheBase::N_SCALAR,1,0);
313  offsets_ = std::make_shared<ElementDataCache<unsigned int>>("offsets",(unsigned int)ElementDataCacheBase::N_SCALAR,1,0);
314  orig_element_indices_ = std::make_shared<std::vector<unsigned int>>();
315 
316  // index of last node added; set at the end of original ones
317  unsigned int last_offset = 0;
318 
319  auto &node_vec = *( nodes_->get_component_data(0).get() );
320  auto &conn_vec = *( connectivity_->get_component_data(0).get() );
321  auto &offset_vec = *( offsets_->get_component_data(0).get() );
322 
323  node_vec.reserve(4*orig_mesh_->n_nodes());
324  conn_vec.reserve(4*4*orig_mesh_->n_elements());
325  offset_vec.reserve(4*orig_mesh_->n_elements());
326 
327 // DebugOut() << "start refinement\n";
328  FOR_ELEMENTS(orig_mesh_, ele) {
329  const unsigned int
330  dim = ele->dim(),
331  ele_idx = ele->index();
332 // DebugOut() << "ele index " << ele_idx << "\n";
333 
334  AuxElement aux_ele;
335  aux_ele.nodes.resize(ele->n_nodes());
336  aux_ele.level = 0;
337 
338  Node* node; unsigned int li;
339  FOR_ELEMENT_NODES(ele, li) {
340  node = ele->node[li];
341  aux_ele.nodes[li] = node->point();
342  }
343 
344  std::vector<AuxElement> refinement;
345 
346  switch(dim){
347  case 1: this->refine_aux_element<1>(aux_ele, refinement, ele->element_accessor()); break;
348  case 2: this->refine_aux_element<2>(aux_ele, refinement, ele->element_accessor()); break;
349  case 3: this->refine_aux_element<3>(aux_ele, refinement, ele->element_accessor()); break;
350  default: ASSERT(0 < dim && dim < 4);
351  }
352 
353  //skip unrefined element
354 // if(refinement.size() < 2) continue;
355  unsigned int node_offset = node_vec.size(),
356  con_offset = conn_vec.size();
357  node_vec.resize(node_vec.size() + (refinement.size() * (dim+1))*spacedim);
358  conn_vec.resize(conn_vec.size() + refinement.size()*(dim+1));
359 // orig_element_indices_->resize(orig_element_indices_->size() + refinement.size()*(dim+1));
360 
361 // DebugOut() << "ref size = " << refinement.size() << "\n";
362  //gather coords and connectivity (in a continous way inside element)
363  for(unsigned int i=0; i < refinement.size(); i++)
364  {
365  last_offset += dim+1;
366  offset_vec.push_back(last_offset);
367  (*orig_element_indices_).push_back(ele_idx);
368  for(unsigned int j=0; j < dim+1; j++)
369  {
370  unsigned int con = i*(dim+1) + j;
371  conn_vec[con_offset + con] = con_offset + con;
372 
373  for(unsigned int k=0; k < spacedim; k++) {
374  node_vec[node_offset + con*spacedim + k] = refinement[i].nodes[j][k];
375  }
376  }
377  }
378  }
379 
380  conn_vec.shrink_to_fit();
381  node_vec.shrink_to_fit();
382  offset_vec.shrink_to_fit();
383 
384  connectivity_->set_n_values(conn_vec.size());
385  nodes_->set_n_values(node_vec.size() / spacedim);
386  offsets_->set_n_values(offset_vec.size());
387 
388  mesh_type_ = MeshType::refined;
389 // for(unsigned int i=0; i< nodes_->n_values; i++)
390 // {
391 // cout << i << " ";
392 // for(unsigned int k=0; k<spacedim; k++){
393 // nodes_->print(cout, i*spacedim+k);
394 // cout << " ";
395 // }
396 // cout << endl;
397 // }
398 // cout << "\n\n";
399 // // nodes_->print_all(cout);
400 // // cout << "\n\n";
401 // connectivity_->print_all(cout);
402 // cout << "\n\n";
403 // offsets_->print_all(cout);
404 }
405 
406 template<int dim>
409  const ElementAccessor<spacedim> &ele_acc)
410 {
411  static const unsigned int n_subelements = 1 << dim; //2^dim
412 
413 // The refinement of elements for the output mesh is done using edge splitting
414 // technique (so called red refinement). Since we use this only for better output
415 // visualization of non-polynomial solutions, we do not care for existence of hanging
416 // nodes.
417 // In 2D case, it is straightforward process: find the midpoints of all sides,
418 // connect them and generate 4 triangles. These triangles are congruent and have
419 // equal surface areas.
420 // On the other hand, the 3D case is more complicated. After splitting the
421 // edges, we obtain 4 tetrahedra at the vertices of the original one. The octahedron
422 // that remains in the middle can be subdivided according to one of its three
423 // diagonals. Only the choice of the shortest octahedron diagonal leads to a regular
424 // tetrahedra decomposition. This algorithm originally comes from Bey.
425 // Bey's algorithm (red refinement of tetrahedron):
426 // p.29 https://www5.in.tum.de/pub/Joshi2016_Thesis.pdf
427 // p.108 http://www.bcamath.org/documentos_public/archivos/publicaciones/sergey_book.pdf
428 // https://www.math.uci.edu/~chenlong/iFEM/doc/html/uniformrefine3doc.html#1
429 // J. Bey. Simplicial grid refinement: on Freudenthal's algorithm and the optimal number of congruence classes.
430 // Numer. Math. 85(1):1--29, 2000. p11 Algorithm: RedRefinement3D.
431 // p.4 http://www.vis.uni-stuttgart.de/uploads/tx_vispublications/vis97-grosso.pdf
432 
433  // connectivity of refined element
434  // these arrays are hardwired to the current reference element
435  static const std::vector<unsigned int> conn[] = {
436  {}, //0D
437 
438  //1D:
439  // 0,1 original nodes, 2 is in the middle
440  // get 2 elements
441  {0, 2,
442  2, 1},
443 
444  //2D:
445  // 0,1,2 original nodes
446  // 3,4,5 nodes are in the middle of sides 0,1,2 in the respective order
447  // get 4 elements
448  {0, 3, 4,
449  3, 1, 5,
450  4, 5, 2,
451  3, 5, 4},
452 
453  //3D:
454  // 0,1,2,3 original nodes
455  // 4,5,6,7,8,9 are nodes in the middle of edges 0,1,2,3,4,5 in the respective order
456  // first 4 tetrahedra are at the original nodes
457  // next 4 tetrahedra are from the inner octahedron - 4 choices according to the diagonal
458  {1, 7, 4, 8,
459  7, 2, 5, 9,
460  4, 5, 0, 6,
461  8, 9, 6, 3,
462  7, 4, 8, 9, // 4-9 octahedron diagonal
463  7, 4, 5, 9,
464  4, 8, 9, 6,
465  4, 5, 9, 6},
466 
467  {1, 7, 4, 8,
468  7, 2, 5, 9,
469  4, 5, 0, 6,
470  8, 9, 6, 3,
471  8, 5, 4, 6, // 5-8 octahedron diagonal
472  5, 8, 9, 6,
473  5, 8, 4, 7,
474  8, 5, 9, 7},
475 
476  {1, 7, 4, 8,
477  7, 2, 5, 9,
478  4, 5, 0, 6,
479  8, 9, 6, 3,
480  6, 8, 7, 9, // 6-7 octahedron diagonal
481  8, 6, 7, 4,
482  6, 5, 7, 4,
483  5, 6, 7, 9}
484  };
485 // DBGMSG("level = %d, %d\n", aux_element.level, max_refinement_level_);
486 
487  ASSERT_DBG(dim == aux_element.nodes.size()-1);
488 
489  // if not refining any further, push into final vector
490  if( ! refinement_criterion(aux_element, ele_acc) ) {
491  refinement.push_back(aux_element);
492  return;
493  }
494 
495  std::vector<AuxElement> subelements(n_subelements);
496 
497  const unsigned int n_old_nodes = RefElement<dim>::n_nodes,
498  n_new_nodes = RefElement<dim>::n_lines; // new points are in the center of lines
499 
500  // auxiliary vectors
501  std::vector<Space<spacedim>::Point> nodes = aux_element.nodes;
502 
503  nodes.reserve(n_old_nodes+n_new_nodes);
504 
505  // create new points in the element
506  for(unsigned int e=0; e < n_new_nodes; e++)
507  {
510  nodes.push_back( p / 2.0);
511  //nodes.back().print();
512  }
513 
514  unsigned int diagonal = 0;
515  // find shortest diagonal: [0]:4-9, [1]:5-8 or [2]:6-7
516  if(dim == 3){
517  double min_diagonal = arma::norm(nodes[4]-nodes[9],2);
518  double d = arma::norm(nodes[5]-nodes[8],2);
519  if(d < min_diagonal){
520  min_diagonal = d;
521  diagonal = 1;
522  }
523  d = arma::norm(nodes[6]-nodes[7],2);
524  if(d < min_diagonal){
525  min_diagonal = d;
526  diagonal = 2;
527  }
528  }
529 
530  for(unsigned int i=0; i < n_subelements; i++)
531  {
532  AuxElement& sub_ele = subelements[i];
533  sub_ele.nodes.resize(n_old_nodes);
534  sub_ele.level = aux_element.level+1;
535 
536  // over nodes
537  for(unsigned int j=0; j < n_old_nodes; j++)
538  {
539  unsigned int conn_id = (n_old_nodes)*i + j;
540  sub_ele.nodes[j] = nodes[conn[dim+diagonal][conn_id]];
541  }
542  refine_aux_element<dim>(sub_ele, refinement, ele_acc);
543  }
544 }
545 
547 {
548  ASSERT( !is_created() ).error("Multiple initialization of OutputMesh!\n");
549 
550  DebugOut() << "Create output submesh containing only local elements.";
551 
553  IdxInt *el_4_loc = orig_mesh_->get_el_4_loc();
554  Distribution *el_ds = orig_mesh_->get_el_ds();
555  const unsigned int n_local_elements = el_ds->lsize();
556 
557  orig_element_indices_ = std::make_shared<std::vector<unsigned int>>(n_local_elements);
558  offsets_ = std::make_shared<ElementDataCache<unsigned int>>("offsets", (unsigned int)ElementDataCacheBase::N_SCALAR, 1, n_local_elements);
559 
560  unsigned int ele_id = 0,
561  offset = 0, // offset of node indices of element in node vector
562  coord_id = 0, // coordinate id in vector
563  corner_id = 0, // corner index (discontinous node)
564  li = 0; // local node index
565  auto &offset_vec = *( offsets_->get_component_data(0).get() );
566  for (unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
567  ele = orig_mesh_->element(el_4_loc[loc_el]);
568  // increase offset by number of nodes of the simplicial element
569  offset += ele->dim() + 1;
570  offset_vec[ele_id] = offset;
571  (*orig_element_indices_)[ele_id] = el_4_loc[loc_el];
572  ele_id++;
573  }
574 
575  // connectivity = for every element list the nodes => its length corresponds to discontinuous data
576  const unsigned int n_corners = offset_vec[offset_vec.size()-1];
577 
578  nodes_ = std::make_shared<ElementDataCache<double>>("", (unsigned int)ElementDataCacheBase::N_VECTOR, 1, n_corners);
579  connectivity_ = std::make_shared<ElementDataCache<unsigned int>>("connectivity", (unsigned int)ElementDataCacheBase::N_SCALAR,
580  1, n_corners);
581 
582  auto &node_vec = *( nodes_->get_component_data(0).get() );
583  auto &conn_vec = *( connectivity_->get_component_data(0).get() );
584  Node* node;
585  for (unsigned int loc_el = 0; loc_el < n_local_elements; loc_el++) {
586  ele = orig_mesh_->element(el_4_loc[loc_el]);
587  FOR_ELEMENT_NODES(ele, li)
588  {
589  node = ele->node[li];
590  node_vec[coord_id] = node->getX(); ++coord_id;
591  node_vec[coord_id] = node->getY(); ++coord_id;
592  node_vec[coord_id] = node->getZ(); ++coord_id;
593 
594  conn_vec[corner_id] = corner_id;
595  corner_id++;
596  }
597  }
598 }
599 
600 
601 template void OutputMeshDiscontinuous::refine_aux_element<1>(const OutputMeshDiscontinuous::AuxElement&,std::vector< OutputMeshDiscontinuous::AuxElement >&, const ElementAccessor<spacedim> &);
602 template void OutputMeshDiscontinuous::refine_aux_element<2>(const OutputMeshDiscontinuous::AuxElement&,std::vector< OutputMeshDiscontinuous::AuxElement >&, const ElementAccessor<spacedim> &);
603 template void OutputMeshDiscontinuous::refine_aux_element<3>(const OutputMeshDiscontinuous::AuxElement&,std::vector< OutputMeshDiscontinuous::AuxElement >&, const ElementAccessor<spacedim> &);
604 
605 
607  const ElementAccessor<spacedim> &ele_acc)
608 {
609  // check refinement criteria:
610 
611  //first check max. level
612  bool refine = refinement_criterion_uniform(aux_ele);
613 
614  //if max. level not reached and refinement by error is set
615  if(refine && refine_by_error_)
616  {
617  // compute centre of aux element
618  Space<spacedim>::Point centre({0,0,0});
619  for(auto& v : aux_ele.nodes ) centre += v;
620  centre = centre/aux_ele.nodes.size();
621  return refinement_criterion_error(aux_ele, centre, ele_acc);
622  }
623 
624  return refine;
625 }
626 
628 {
629  return (ele.level < max_level_);
630 }
631 
633  const Space<spacedim>::Point &centre,
634  const ElementAccessor<spacedim> &ele_acc
635  )
636 {
637  ASSERT_DBG(error_control_field_func_).error("Error control field not set!");
638 
639  // evaluate at nodes and center in a single call
640  std::vector<double> val_list(ele.nodes.size()+1);
642  point_list.push_back(centre);
643  point_list.insert(point_list.end(), ele.nodes.begin(), ele.nodes.end());
644  error_control_field_func_(point_list, ele_acc, val_list);
645 
646  //TODO: compute L1 or L2 error using standard quadrature
647 
648  //compare average value at nodes with value at center
649 
650  double average_val = 0.0;
651  for(unsigned int i=1; i<ele.nodes.size()+1; ++i)//(double& v: nodes_val)
652  average_val += val_list[i];
653  average_val = average_val / ele.nodes.size();
654 
655  double diff = std::abs((average_val - val_list[0])/val_list[0]);
656 // DebugOut().fmt("diff: {} {} {}\n", diff, average_val, val_list[0]);
657  return ( diff > refinement_error_tolerance_);
658 
659 }
Classes for auxiliary output mesh.
void create_refined_mesh() override
Creates refined mesh.
Definition: output_mesh.cc:211
int IdxInt
Define integers that are indices into large arrays (elements, nodes, dofs etc.)
Definition: mesh.h:85
static const unsigned int spacedim
Shortcut instead of spacedim template. We suppose only spacedim=3 at the moment.
Definition: output_mesh.hh:71
#define FOR_ELEMENT_NODES(i, j)
Definition: elements.h:156
Base class for Output mesh.
Definition: output_mesh.hh:67
double getY() const
Definition: nodes.hh:59
GeneralIterator< OutputElement > OutputElementIterator
Definition: output_mesh.hh:34
Definition: nodes.hh:32
std::function< void(const std::vector< Space< spacedim >::Point > &, const ElementAccessor< spacedim > &, std::vector< double > &)> ErrorControlFieldFunc
Definition: output_mesh.hh:74
bool refinement_criterion_error(const AuxElement &ele, const Space< spacedim >::Point &centre, const ElementAccessor< spacedim > &ele_acc)
Refinement flag - measures discretisation error according to error control field. ...
Definition: output_mesh.cc:632
unsigned int n_elements()
Returns number of element.
Definition: output_mesh.cc:88
Mesh * orig_mesh_
Pointer to the computational mesh.
Definition: output_mesh.hh:132
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:61
#define FOR_ELEMENTS(_mesh_, __i)
Definition: mesh.h:480
Class for declaration of the input of type Bool.
Definition: type_base.hh:458
void create_mesh() override
Creates the output mesh identical to the orig mesh.
Definition: output_mesh.cc:249
IdxInt * get_el_4_loc() const
Definition: mesh.h:195
void create_mesh() override
Creates the output mesh identical to the orig mesh.
Definition: output_mesh.cc:157
static const Input::Type::Record & get_input_type()
The specification of output mesh.
Definition: output_mesh.cc:27
const unsigned int max_level_
Maximal level of refinement.
Definition: output_mesh.hh:135
Definition: mesh.h:99
double refinement_error_tolerance_
Tolerance for error criterion refinement.
Definition: output_mesh.hh:142
std::shared_ptr< ElementDataCache< unsigned int > > connectivity_
Vector maps the nodes to their coordinates in vector nodes_.
Definition: output_mesh.hh:150
bool refinement_criterion(const AuxElement &ele, const ElementAccessor< spacedim > &ele_acc)
Collects different refinement criteria results.
Definition: output_mesh.cc:606
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
std::shared_ptr< ElementDataCache< unsigned int > > node_ids_
Vector gets ids of nodes. Data is used in GMSH output.
Definition: output_mesh.hh:155
Class for declaration of the integral input data.
Definition: type_base.hh:489
std::shared_ptr< ElementDataCache< unsigned int > > offsets_
Vector of offsets of node indices of elements. Maps elements to their nodes in connectivity_.
Definition: output_mesh.hh:152
Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:303
unsigned int n_nodes()
Returns number of nodes.
Definition: output_mesh.cc:94
std::shared_ptr< ElementDataCache< double > > nodes_
Vector of node coordinates. [spacedim x n_nodes].
Definition: output_mesh.hh:148
OutputMesh(Mesh &mesh)
Definition: output_mesh.cc:141
double getZ() const
Definition: nodes.hh:61
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:124
unsigned int n_elements() const
Definition: mesh.h:156
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:540
ErrorControlFieldFunc error_control_field_func_
Refinement error control field function (hold value_list function of field).
Definition: output_mesh.hh:138
arma::vec::fixed< spacedim > Point
Definition: point.hh:33
Accessor to the data with type Type::Record.
Definition: accessors.hh:292
static const IdxVector< (InDim >OutDim?InDim+1:dim-InDim) > interact(TInteraction< OutDim, InDim > interaction)
double getX() const
Definition: nodes.hh:57
Auxiliary structure defining element of refined output mesh.
Definition: output_mesh.hh:215
void refine_aux_element(const AuxElement &aux_element, std::vector< AuxElement > &refinement, const ElementAccessor< spacedim > &ele_acc)
Performs the actual refinement of AuxElement. Recurrent.
Definition: output_mesh.cc:407
void set_error_control_field(ErrorControlFieldFunc error_control_field_func)
Selects the error control field computing function of output field set according to input record...
Definition: output_mesh.cc:83
std::shared_ptr< ElementDataCache< unsigned int > > region_ids_
Vector gets ids of regions. Data is used in GMSH output.
Definition: output_mesh.hh:159
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:490
bool refinement_criterion()
Definition: output_mesh.cc:217
int aux
Definition: nodes.hh:93
virtual ~OutputMeshBase()
Definition: output_mesh.cc:64
void create_sub_mesh() override
Creates sub mesh.
Definition: output_mesh.cc:224
#define FOR_NODES(_mesh_, i)
Definition: mesh.h:56
Distribution * get_el_ds() const
Definition: mesh.h:189
OutputMeshDiscontinuous(Mesh &mesh)
Definition: output_mesh.cc:233
Input::Record input_record_
Input record for output mesh.
Definition: output_mesh.hh:129
bool refinement_criterion_uniform(const AuxElement &ele)
Refinement flag - checks only maximal level of refinement.
Definition: output_mesh.cc:627
OutputElementIterator end()
Gives iterator to the LAST element of the output mesh.
Definition: output_mesh.cc:75
Support classes for parallel programing.
friend class OutputElement
Friend provides access to vectors for element accessor class.
Definition: output_mesh.hh:164
std::shared_ptr< ElementDataCache< int > > partitions_
Vector gets partitions of elements. Data is used in GMSH output.
Definition: output_mesh.hh:161
#define ELEMENT_FULL_ITER_NULL(_mesh_)
Definition: mesh.h:494
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
bool refine_by_error_
True, if output mesh is to be refined by error criterion.
Definition: output_mesh.hh:141
Class OutputElement and its iterator OutputElementIterator on the output mesh.
#define ASSERT_DBG(expr)
Definition: asserts.hh:349
Class RefElement defines numbering of vertices, sides, calculation of normal vectors etc...
unsigned int n_nodes() const
Definition: mesh.h:152
MeshType mesh_type_
Type of OutputMesh.
Definition: output_mesh.hh:140
Record type proxy class.
Definition: type_record.hh:182
std::vector< Space< spacedim >::Point > nodes
Definition: output_mesh.hh:216
General iterator template. Provides iterator over objects in some container.
void create_id_caches()
Create nodes and elements data caches.
Definition: output_mesh.cc:100
bool is_created()
Check if nodes_, connectivity_ and offsets_ data caches are created.
Definition: output_mesh.cc:132
arma::vec3 & point()
Definition: nodes.hh:68
std::shared_ptr< ElementDataCache< unsigned int > > elem_ids_
Vector gets ids of elements. Data is used in GMSH output.
Definition: output_mesh.hh:157
#define DebugOut()
Macro defining &#39;debug&#39; record of log.
Definition: logger.hh:252
#define ASSERT_PTR_DBG(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:339
void create_refined_mesh() override
Creates discontinuous refined mesh.
Definition: output_mesh.cc:307
Class for declaration of the input data that are in string format.
Definition: type_base.hh:588
same as original (computational) mesh
Definition: output_mesh.hh:122
NodeVector node_vector
Vector of nodes of the mesh.
Definition: mesh.h:258
std::shared_ptr< std::vector< unsigned int > > orig_element_indices_
Vector of element indices in the computational mesh. (Important when refining.)
Definition: output_mesh.hh:145
OutputElementIterator begin()
Gives iterator to the FIRST element of the output mesh.
Definition: output_mesh.cc:68
void create_sub_mesh() override
Creates sub mesh.
Definition: output_mesh.cc:546
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:260
OutputMeshBase(Mesh &mesh)
Constructor. Takes computational mesh as a parameter.
Definition: output_mesh.cc:42
unsigned int lsize(int proc) const
get local size