Hermes2D  3.0
linearizer.cpp
1 // This file is part of Hermes2D.
2 //
3 // Hermes2D is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, either version 2 of the License, or
6 // (at your option) any later version.
7 //
8 // Hermes2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Hermes2D. If not, see <http://www.gnu.org/licenses/>.
15 
16 #include "thread_linearizer.h"
17 #include "refmap.h"
18 #include "traverse.h"
19 #include "exact_solution.h"
20 #include "api2d.h"
21 
22 namespace Hermes
23 {
24  namespace Hermes2D
25  {
26  namespace Views
27  {
28  LinearizerCriterion::LinearizerCriterion(bool adaptive) : adaptive(adaptive)
29  {
30  }
31 
32  LinearizerCriterionAdaptive::LinearizerCriterionAdaptive(double error_tolerance) : LinearizerCriterion(true)
33  {
34  this->error_tolerance = error_tolerance;
35  }
36 
37  LinearizerCriterionFixed::LinearizerCriterionFixed(int refinement_level) : LinearizerCriterion(false)
38  {
39  this->refinement_level = refinement_level;
40  }
41 
42  template<typename LinearizerDataDimensions>
44  states(nullptr), num_states(0), dmult(1.0), curvature_epsilon(1e-5), linearizerOutputType(linearizerOutputType), criterion(LinearizerCriterionFixed(1))
45  {
46  xdisp = nullptr;
47  user_xdisp = false;
48  ydisp = nullptr;
49  user_ydisp = false;
50 
51  // Threads
52  // Local number of threads - to avoid calling it over and over again, and against faults caused by the
53  // value being changed while assembling.
54  this->threadLinearizerMultidimensional = malloc_with_check<LinearizerMultidimensional<LinearizerDataDimensions>, ThreadLinearizerMultidimensional<LinearizerDataDimensions>*>(this->num_threads_used, this);
55  for (int i = 0; i < this->num_threads_used; i++)
57 
58 #ifndef NOGLUT
59  pthread_mutexattr_t attr;
60  pthread_mutexattr_init(&attr);
61  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
62  pthread_mutex_init(&data_mutex, &attr);
63  pthread_mutexattr_destroy(&attr);
64 #endif
65  }
66 
67  template<typename LinearizerDataDimensions>
69  {
70  this->criterion = criterion;
71  }
72 
73  template<typename LinearizerDataDimensions>
75  {
76  this->curvature_epsilon = curvature_epsilon;
77  }
78 
79  template<typename LinearizerDataDimensions>
81  {
82  return this->curvature_epsilon;
83  }
84 
85  template<typename LinearizerDataDimensions>
87  {
88  if (xdisp)
89  {
90  this->xdisp = MeshFunctionSharedPtr<double>(xdisp);
91  this->user_xdisp = true;
92  }
93  if (ydisp)
94  {
95  this->ydisp = MeshFunctionSharedPtr<double>(ydisp);
96  this->user_ydisp = true;
97  }
98  if (xdisp || ydisp)
99  this->dmult = dmult;
100  }
101 
102  template<typename LinearizerDataDimensions>
104  {
105  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
106  if (!sln[k])
107  throw Exceptions::Exception("Linearizer: too few solutions, probably wrong template argument.");
108  }
109 
110  template<typename LinearizerDataDimensions>
112  {
113  // Check.
114  this->check_data(sln);
115 
116  // Basic storage.
117  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
118  {
119  this->item[k] = item_[k];
120  this->component[k] = 0;
121  this->value_type[k] = 0;
122 
123  // Get the component and desired value from item.
124  if (item[k] >= 0x40)
125  {
126  component[k] = 1;
127  this->item[k] >>= 6;
128  }
129  while (!(item[k] & 1))
130  {
131  this->item[k] >>= 1;
132  value_type[k]++;
133  }
134  // reset the item to the value before the circus with component, value_type.
135  this->item[k] = item_[k];
136  }
137 
138  // Store quads & handle meshes
139  meshes.clear();
140  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
141  {
142  old_quad[k] = sln[k]->get_quad_2d();
143  meshes.push_back(sln[k]->get_mesh());
144  }
145  if (this->user_xdisp)
146  {
147  old_quad_x = xdisp->get_quad_2d();
148  meshes.push_back(xdisp->get_mesh());
149  }
150  if (this->user_ydisp)
151  {
152  old_quad_y = ydisp->get_quad_2d();
153  meshes.push_back(ydisp->get_mesh());
154  }
155  }
156 
157  template<typename LinearizerDataDimensions>
158  void LinearizerMultidimensional<LinearizerDataDimensions>::process_solution(MeshFunctionSharedPtr<double>* sln, int* item_)
159  {
160  // Init the caught parallel exception message.
161  this->exceptionMessageCaughtInParallelBlock.clear();
162 
163  // lock data.
164  lock_data();
165 
166  // Initialization of 'global' stuff.
167  this->init(sln, item_);
168 
169  // Parallelization.
170  Traverse trav_master(ydisp == nullptr ? (xdisp == nullptr ? 1 : 2) : (xdisp == nullptr ? 2 : 3));
171  states = trav_master.get_states(this->meshes, this->num_states);
172 
173 #pragma omp parallel shared(trav_master) num_threads(num_threads_used)
174  {
175  int thread_number = omp_get_thread_num();
176  int start = (this->num_states / num_threads_used) * thread_number;
177  int end = (this->num_states / num_threads_used) * (thread_number + 1);
178  if (thread_number == num_threads_used - 1)
179  end = this->num_states;
180 
181  try
182  {
183  double max_value_for_adaptive_refinements = 0.;
184 
185  this->threadLinearizerMultidimensional[thread_number]->init_processing(sln, this);
186 
187  for (int state_i = start; state_i < end; state_i++)
188  max_value_for_adaptive_refinements = std::max(max_value_for_adaptive_refinements, this->threadLinearizerMultidimensional[thread_number]->get_max_value(states[state_i]));
189 
190  this->threadLinearizerMultidimensional[thread_number]->max_value_approx = max_value_for_adaptive_refinements;
191 
192  for (int state_i = start; state_i < end; state_i++)
193  {
194  // Exception already thrown -> exit the loop.
195  if (!this->exceptionMessageCaughtInParallelBlock.empty())
196  break;
197 
198  Traverse::State* current_state = states[state_i];
199 
200  this->threadLinearizerMultidimensional[thread_number]->process_state(current_state);
201  }
202  this->threadLinearizerMultidimensional[thread_number]->deinit_processing();
203  }
204  catch (Hermes::Exceptions::Exception& e)
205  {
206 #pragma omp critical (exceptionMessageCaughtInParallelBlock)
207  this->exceptionMessageCaughtInParallelBlock = e.info();
208  }
209  catch (std::exception& e)
210  {
211 #pragma omp critical (exceptionMessageCaughtInParallelBlock)
212  this->exceptionMessageCaughtInParallelBlock = e.what();
213  }
214  }
215 
216  // Free states.
217  if (this->states)
218  {
219  for (int i = 0; i < this->num_states; i++)
220  delete states[i];
221 
222  free_with_check(this->states);
223  this->states = nullptr;
224  this->num_states = 0;
225  }
226 
227  // Finish.
228  this->finish(sln);
229 
230  if (!this->exceptionMessageCaughtInParallelBlock.empty())
231  throw Hermes::Exceptions::Exception(this->exceptionMessageCaughtInParallelBlock.c_str());
232  }
233 
234  template<typename LinearizerDataDimensions>
236  {
237  MeshFunctionSharedPtr<double> slns[LinearizerDataDimensions::dimension];
238  int items[LinearizerDataDimensions::dimension];
239  slns[0] = sln;
240  items[0] = item_;
241  for (int k = 1; k < LinearizerDataDimensions::dimension; k++)
242  {
243  slns[k] = nullptr;
244  items[k] = 0;
245  }
246 
247  this->process_solution(slns, items);
248  }
249 
250  template<typename LinearizerDataDimensions>
252  {
253 #ifndef NOGLUT
254  pthread_mutex_lock(&data_mutex);
255 #endif
256  }
257 
258  template<typename LinearizerDataDimensions>
260  {
261 #ifndef NOGLUT
262  pthread_mutex_unlock(&data_mutex);
263 #endif
264  }
265 
266  template<typename LinearizerDataDimensions>
267  void LinearizerMultidimensional<LinearizerDataDimensions>::finish(MeshFunctionSharedPtr<double>* sln)
268  {
269  // regularize the linear mesh
270  if (this->exceptionMessageCaughtInParallelBlock.empty())
271  {
272  find_min_max();
273  // Polish triangle vertex indices for FileExport case.
274  if (this->linearizerOutputType == FileExport)
275  {
276  int running_count = 0;
277  for (int i = 0; i < this->num_threads_used; i++)
278  {
279  if (i > 0)
280  {
281  for (int j = 0; j < this->threadLinearizerMultidimensional[i]->triangle_count; j++)
282  {
283  for (int k = 0; k < 3; k++)
284  this->threadLinearizerMultidimensional[i]->triangle_indices[j][k] += running_count;
285  }
286  }
287  running_count += this->threadLinearizerMultidimensional[i]->vertex_count;
288  }
289  }
290  }
291 
292  // select old quadratrues
293  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
294  sln[k]->set_quad_2d(old_quad[k]);
295 
296  // Unlock data.
297  this->unlock_data();
298  }
299 
300  template<typename LinearizerDataDimensions>
301  void LinearizerMultidimensional<LinearizerDataDimensions>::find_min_max()
302  {
303  // find min & max vertex values
304  this->min_val = 1e100;
305  this->max_val = -1e100;
306  for (Iterator<typename LinearizerDataDimensions::vertex_t> it = this->vertices_begin(); !it.end; ++it)
307  {
308  typename LinearizerDataDimensions::vertex_t& vertex = it.get();
309 
310  double magnitude = 0.;
311  if (LinearizerDataDimensions::dimension == 1)
312  magnitude = vertex[2];
313  else
314  {
315  for (int j = 0; j < LinearizerDataDimensions::dimension; j++)
316  magnitude += vertex[2 + j] * vertex[2 + j];
317 
318  magnitude = std::sqrt(magnitude);
319  }
320 
321  if (finite(magnitude) && magnitude < min_val)
322  min_val = magnitude;
323  if (finite(magnitude) && magnitude > max_val)
324  max_val = magnitude;
325  }
326  }
327 
328  template<typename LinearizerDataDimensions>
330  {
331  for (int i = 0; i < this->num_threads_used; i++)
332  this->threadLinearizerMultidimensional[i]->free();
333  }
334 
335  template<typename LinearizerDataDimensions>
337  {
338 #ifndef NOGLUT
339  pthread_mutex_destroy(&data_mutex);
340 #endif
341  free();
342  for (int i = 0; i < this->num_threads_used; i++)
343  delete this->threadLinearizerMultidimensional[i];
344  free_with_check(this->threadLinearizerMultidimensional);
345  }
346 
347  template<typename LinearizerDataDimensions>
348  void LinearizerMultidimensional<LinearizerDataDimensions>::set_max_absolute_value(double max_abs)
349  {
350  if (max_abs < 0.0)
351  this->warn("Setting of maximum absolute value in LinearizerMultidimensional with a negative value");
352  else
353  {
354  this->max_val = max_abs;
355  }
356  return;
357  }
358 
359  template<typename LinearizerDataDimensions>
360  double LinearizerMultidimensional<LinearizerDataDimensions>::get_min_value() const
361  {
362  return min_val;
363  }
364 
365  template<typename LinearizerDataDimensions>
366  double LinearizerMultidimensional<LinearizerDataDimensions>::get_max_value() const
367  {
368  return max_val;
369  }
370 
371  template<typename LinearizerDataDimensions>
372  void LinearizerMultidimensional<LinearizerDataDimensions>::save_solution_vtk(std::vector<MeshFunctionSharedPtr<double> > slns, std::vector<int> items, const char* filename, const char *quantity_name,
373  bool mode_3D)
374  {
375  if (this->linearizerOutputType != FileExport)
376  throw Exceptions::Exception("This LinearizerMultidimensional is not meant to be used for file export, create a new one with appropriate linearizerOutputType.");
377 
378  process_solution(&slns[0], &items[0]);
379 
380  FILE* f = fopen(filename, "wb");
381  if (f == nullptr) throw Hermes::Exceptions::Exception("Could not open %s for writing.", filename);
382 
383  // Output header for vertices.
384  fprintf(f, "# vtk DataFile Version 2.0\n");
385  fprintf(f, "\n");
386  fprintf(f, "ASCII\n\n");
387  fprintf(f, "DATASET UNSTRUCTURED_GRID\n");
388 
389  // Output vertices.
390  fprintf(f, "POINTS %d %s\n", this->get_vertex_count(), "float");
391  for (Iterator<typename LinearizerDataDimensions::vertex_t> it = this->vertices_begin(); !it.end; ++it)
392  {
393  typename LinearizerDataDimensions::vertex_t& vertex = it.get();
394  if (mode_3D == true)
395  {
396  std::stringstream ss;
397  ss << vertex[0] << " " << vertex[1];
398  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
399  ss << " " << vertex[2 + k];
400  fprintf(f, "%s\n", ss.str().c_str());
401  }
402  else
403  fprintf(f, "%g %g %g\n", vertex[0], vertex[1], 0.0);
404  }
405 
406  // Output elements.
407  fprintf(f, "\n");
408  fprintf(f, "CELLS %d %d\n", this->get_triangle_count(), 4 * this->get_triangle_count());
409  for (Iterator<triangle_indices_t> it = this->triangle_indices_begin(); !it.end; ++it)
410  {
411  triangle_indices_t& triangle_indices = it.get();
412  fprintf(f, "3 %d %d %d\n", triangle_indices[0], triangle_indices[1], triangle_indices[2]);
413  }
414 
415  // Output cell types.
416  fprintf(f, "\n");
417  fprintf(f, "CELL_TYPES %d\n", this->get_triangle_count());
418  for (int i = 0; i < this->get_triangle_count(); i++)
419  {
420  // The "5" means triangle in VTK.
421  fprintf(f, "5\n");
422  }
423 
424  // This outputs double solution values.
425  fprintf(f, "\n");
426  fprintf(f, "POINT_DATA %d\n", this->get_vertex_count());
427  fprintf(f, "SCALARS %s %s %d\n", quantity_name, "float", LinearizerDataDimensions::dimension);
428  fprintf(f, "LOOKUP_TABLE %s\n", "default");
429  for (Iterator<typename LinearizerDataDimensions::vertex_t> it = this->vertices_begin(); !it.end; ++it)
430  {
431  typename LinearizerDataDimensions::vertex_t& vertex = it.get();
432 
433  std::stringstream ssi;
434  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
435  {
436  ssi << vertex[2 + k];
437  if (k < LinearizerDataDimensions::dimension - 1)
438  ssi << " ";
439  }
440  fprintf(f, "%s\n", ssi.str().c_str());
441  }
442 
443  fclose(f);
444  }
445 
446  template<typename LinearizerDataDimensions>
447  void LinearizerMultidimensional<LinearizerDataDimensions>::save_solution_vtk(MeshFunctionSharedPtr<double> sln, const char* filename, const char* quantity_name, bool mode_3D, int item)
448  {
449  std::vector<MeshFunctionSharedPtr<double> > slns;
450  std::vector<int> items;
451  slns.push_back(sln);
452  items.push_back(item);
453  LinearizerMultidimensional<LinearizerDataDimensions>::save_solution_vtk(slns, items, filename, quantity_name, mode_3D);
454  }
455 
456  template<typename LinearizerDataDimensions>
457  void LinearizerMultidimensional<LinearizerDataDimensions>::save_solution_tecplot(std::vector<MeshFunctionSharedPtr<double> > slns, std::vector<int> items, const char* filename, std::vector<std::string> quantity_names)
458  {
459  if (this->linearizerOutputType != FileExport)
460  throw Exceptions::Exception("This LinearizerMultidimensional is not meant to be used for file export, create a new one with appropriate linearizerOutputType.");
461 
462  process_solution(&slns[0], &items[0]);
463 
464  FILE* f = fopen(filename, "wb");
465  if (f == nullptr) throw Hermes::Exceptions::Exception("Could not open %s for writing.", filename);
466 
467  // Output header for vertices.
468  fprintf(f, "TITLE = \"%s created by Hermes.\"\n", filename);
469  std::stringstream ss;
470  ss << "VARIABLES = \"X\", \"Y\",";
471  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
472  ss << " \"" << quantity_names[k] << "\"";
473  fprintf(f, "%s\n", ss.str().c_str());
474  fprintf(f, "ZONE N = %d, E = %d, DATAPACKING = POINT, ZONETYPE = FETRIANGLE\n", this->get_vertex_count(), this->get_triangle_count());
475 
476  // Output vertices.
477  for (Iterator<typename LinearizerDataDimensions::vertex_t> it = this->vertices_begin(); !it.end; ++it)
478  {
479  typename LinearizerDataDimensions::vertex_t& vertex = it.get();
480 
481  std::stringstream ss;
482  ss << vertex[0] << " " << vertex[1];
483  for (int k = 0; k < LinearizerDataDimensions::dimension; k++)
484  ss << " " << vertex[2 + k];
485  fprintf(f, "%s\n", ss.str().c_str());
486  }
487 
488  // Output elements.
489  for (Iterator<triangle_indices_t> it = this->triangle_indices_begin(); !it.end; ++it)
490  {
491  triangle_indices_t& triangle_indices = it.get();
492  fprintf(f, "%d %d %d\n", triangle_indices[0] + 1, triangle_indices[1] + 1, triangle_indices[2] + 1);
493  }
494 
495  fclose(f);
496  }
497 
498  template<typename LinearizerDataDimensions>
499  void LinearizerMultidimensional<LinearizerDataDimensions>::save_solution_tecplot(MeshFunctionSharedPtr<double> sln, const char* filename, const char* quantity_name, int item)
500  {
501  std::vector<MeshFunctionSharedPtr<double> > slns;
502  std::vector<int> items;
503  slns.push_back(sln);
504  items.push_back(item);
505  std::vector<std::string> quantity_names;
506  quantity_names.push_back(quantity_name);
508  }
509 
510  template<typename LinearizerDataDimensions>
511  void LinearizerMultidimensional<LinearizerDataDimensions>::calc_vertices_aabb(double* min_x, double* max_x, double* min_y, double* max_y) const
512  {
513  *max_x = *max_y = std::numeric_limits<double>::min();
514  *min_x = *min_y = std::numeric_limits<double>::max();
515 
516  for (Iterator<typename LinearizerDataDimensions::vertex_t> it = this->vertices_begin(); !it.end; ++it)
517  {
518  typename LinearizerDataDimensions::vertex_t& vertex = it.get();
519  if (vertex[0] > *max_x)
520  *max_x = vertex[0];
521  else if (vertex[0] < *min_x)
522  *min_x = vertex[0];
523 
524  if (vertex[1] > *max_y)
525  *max_y = vertex[1];
526  else if (vertex[1] < *min_y)
527  *min_y = vertex[1];
528  }
529  }
530 
531  template<typename LinearizerDataDimensions>
532  template<typename T>
533  LinearizerMultidimensional<LinearizerDataDimensions>::Iterator<T>::Iterator(const LinearizerMultidimensional* linearizer) : current_thread_index(0), current_thread(0), end(false), linearizer(linearizer)
534  {
535  }
536 
537  template<typename LinearizerDataDimensions>
538  template<typename T>
540  {
541  if (this->current_thread_index >= this->current_thread_size - 1)
542  {
543  if (this->current_thread == this->thread_sizes.size() - 1)
544  this->end = true;
545  else
546  {
547  this->current_thread_index = 0;
548  this->current_thread_size = this->thread_sizes[++this->current_thread];
549  this->check_zero_lengths();
550  }
551  }
552  else
553  this->current_thread_index++;
554  }
555 
556  template<typename LinearizerDataDimensions>
557  template<typename T>
559  {
560  while (this->current_thread_size == 0)
561  {
562  if (this->current_thread_size == this->thread_sizes[this->thread_sizes.size() - 1])
563  {
564  this->end = true;
565  break;
566  }
567  this->current_thread_size = this->thread_sizes[++this->current_thread];
568  }
569  }
570 
571  template<>
572  template<>
573  typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t>::get() const
574  {
575  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangles[this->current_thread_index];
576  }
577 
578  template<>
579  template<>
580  int& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t>::get_marker() const
581  {
582  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_markers[this->current_thread_index];
583  }
584 
585  template<>
586  template<>
587  typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t>::get() const
588  {
589  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->edges[this->current_thread_index];
590  }
591 
592  template<>
593  template<>
594  int& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t>::get_marker() const
595  {
596  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->edge_markers[this->current_thread_index];
597  }
598 
599  template<>
600  template<>
601  typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t>::get() const
602  {
603  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->vertices[this->current_thread_index];
604  }
605 
606  template<>
607  template<>
608  triangle_indices_t& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<triangle_indices_t>::get() const
609  {
610  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_indices[this->current_thread_index];
611  }
612 
613  template<>
614  template<>
615  int& LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<triangle_indices_t>::get_marker() const
616  {
617  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_markers[this->current_thread_index];
618  }
619 
620  template<>
621  template<>
622  typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t>::get() const
623  {
624  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangles[this->current_thread_index];
625  }
626 
627  template<>
628  template<>
629  int& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t>::get_marker() const
630  {
631  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_markers[this->current_thread_index];
632  }
633 
634  template<>
635  template<>
636  typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t>::get() const
637  {
638  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->edges[this->current_thread_index];
639  }
640 
641  template<>
642  template<>
643  int& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t>::get_marker() const
644  {
645  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->edge_markers[this->current_thread_index];
646  }
647 
648  template<>
649  template<>
650  typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<typename VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t>::get() const
651  {
652  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->vertices[this->current_thread_index];
653  }
654 
655  template<>
656  template<>
657  triangle_indices_t& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<triangle_indices_t>::get() const
658  {
659  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_indices[this->current_thread_index];
660  }
661 
662  template<>
663  template<>
664  int& LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator<triangle_indices_t>::get_marker() const
665  {
666  return this->linearizer->threadLinearizerMultidimensional[this->current_thread]->triangle_markers[this->current_thread_index];
667  }
668 
669  template<typename LinearizerDataDimensions>
670 #ifdef _MSC_VER
671  typename LinearizerMultidimensional<LinearizerDataDimensions>::Iterator<typename LinearizerDataDimensions::vertex_t> LinearizerMultidimensional<LinearizerDataDimensions>::vertices_begin() const
672 #else
674 #endif
675  {
676  LinearizerMultidimensional<LinearizerDataDimensions>::Iterator<typename LinearizerDataDimensions::vertex_t> iterator(this);
677  for (int i = 0; i < this->num_threads_used; i++)
678  iterator.thread_sizes.push_back(this->threadLinearizerMultidimensional[i]->vertex_count);
679  iterator.current_thread_size = iterator.thread_sizes[0];
680  iterator.check_zero_lengths();
681  return iterator;
682  }
683  template<typename LinearizerDataDimensions>
684 #ifdef _MSC_VER
686 #else
688 #endif
689  {
690  LinearizerMultidimensional<LinearizerDataDimensions>::Iterator<typename LinearizerDataDimensions::triangle_t> iterator(this);
691  for (int i = 0; i < this->num_threads_used; i++)
692  iterator.thread_sizes.push_back(this->threadLinearizerMultidimensional[i]->triangle_count);
693  iterator.current_thread_size = iterator.thread_sizes[0];
694  iterator.check_zero_lengths();
695  return iterator;
696  }
697  template<typename LinearizerDataDimensions>
698 #ifdef _MSC_VER
700 #else
702 #endif
703  {
704  LinearizerMultidimensional<LinearizerDataDimensions>::Iterator<typename LinearizerDataDimensions::edge_t> iterator(this);
705  for (int i = 0; i < this->num_threads_used; i++)
706  iterator.thread_sizes.push_back(this->threadLinearizerMultidimensional[i]->edges_count);
707  iterator.current_thread_size = iterator.thread_sizes[0];
708  iterator.check_zero_lengths();
709  return iterator;
710  }
711  template<typename LinearizerDataDimensions>
712 #ifdef _MSC_VER
714 #else
716 #endif
717  {
719  for (int i = 0; i < this->num_threads_used; i++)
720  iterator.thread_sizes.push_back(this->threadLinearizerMultidimensional[i]->triangle_count);
721  iterator.current_thread_size = iterator.thread_sizes[0];
722  iterator.check_zero_lengths();
723  return iterator;
724  }
725 
726  template<typename LinearizerDataDimensions>
728  {
729  int count = 0;
730  for (int i = 0; i < this->num_threads_used; i++)
731  count += this->threadLinearizerMultidimensional[i]->vertex_count;
732  return count;
733  }
734 
735  template<typename LinearizerDataDimensions>
737  {
738  int count = 0;
739  for (int i = 0; i < this->num_threads_used; i++)
740  count += this->threadLinearizerMultidimensional[i]->triangle_count;
741  return count;
742  }
743 
744  template<typename LinearizerDataDimensions>
746  {
747  int count = 0;
748  for (int i = 0; i < this->num_threads_used; i++)
749  count += this->threadLinearizerMultidimensional[i]->edges_count;
750  return count;
751  }
752 
753  template<typename LinearizerDataDimensions>
755  {
756  int count = 0;
757  for (int i = 0; i < this->num_threads_used; i++)
758  count += this->threadLinearizerMultidimensional[i]->triangle_count;
759  return count;
760  }
761 
763  template class HERMES_API LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator < ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t > ;
764  template class HERMES_API LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator < ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t > ;
765  template class HERMES_API LinearizerMultidimensional<ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator < ScalarLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t > ;
766 
768  template class HERMES_API LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator < VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::triangle_t > ;
769  template class HERMES_API LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE> >::Iterator < VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::vertex_t > ;
770  template class HERMES_API LinearizerMultidimensional<VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE > >::Iterator < VectorLinearizerDataDimensions<LINEARIZER_DATA_TYPE>::edge_t > ;
771  }
772  }
773 }
Definition: adapt.h:24
int get_edge_count() const
Edge count per all threads.
Definition: linearizer.cpp:745
void check_data(MeshFunctionSharedPtr< double > *sln)
Before assembling.
Definition: linearizer.cpp:103
void process_solution(MeshFunctionSharedPtr< double > sln, int item=H2D_FN_VAL_0)
Definition: linearizer.cpp:235
int get_triangle_index_count() const
Triangle index count per all threads.
Definition: linearizer.cpp:754
void set_curvature_epsilon(double curvature_epsilon)
Definition: linearizer.cpp:74
::xsd::cxx::tree::exception< char > exception
Root of the C++/Tree exception hierarchy.
bool user_xdisp
Information if user-supplied displacement functions have been provided.
Definition: linearizer.h:172
Iterator< typename LinearizerDataDimensions::vertex_t > vertices_begin() const
Return the appropriate iterator pointing to the beginning.
Definition: linearizer.cpp:673
File containing ThreadLinearizerMultidimensional class.
void save_solution_tecplot(MeshFunctionSharedPtr< double > sln, const char *filename, const char *quantity_name, int item=H2D_FN_VAL_0)
Save a MeshFunction (Solution, Filter) in Tecplot format.
Definition: linearizer.cpp:499
void save_solution_vtk(MeshFunctionSharedPtr< double > sln, const char *filename, const char *quantity_name, bool mode_3D=true, int item=H2D_FN_VAL_0)
Save a MeshFunction (Solution, Filter) in VTK format.
Definition: linearizer.cpp:447
int get_vertex_count() const
Vertex count per all threads.
Definition: linearizer.cpp:727
ThreadLinearizerMultidimensional< LinearizerDataDimensions > ** threadLinearizerMultidimensional
Assembly data.
Definition: linearizer.h:162
int3 triangle_indices_t
Typedefs used throughout the Linearizer functionality.
MeshFunctionSharedPtr< double > xdisp
Displacement functions, default to ZeroFunctions, may be supplied by set_displacement();.
Definition: linearizer.h:179
double get_curvature_epsilon() const
Get the 'curvature' epsilon determining the tolerance of catching the shape of curved elements...
Definition: linearizer.cpp:80
void set_displacement(MeshFunctionSharedPtr< double > xdisp, MeshFunctionSharedPtr< double > ydisp, double dmult=1.0)
Set the displacement, i.e. set two functions that will deform the domain for visualization, in the x-direction, and the y-direction.
Definition: linearizer.cpp:86
int get_triangle_count() const
Triangle per all threads.
Definition: linearizer.cpp:736
void set_criterion(LinearizerCriterion criterion)
Definition: linearizer.cpp:68
Iterator< typename LinearizerDataDimensions::edge_t > edges_begin() const
Return the appropriate iterator pointing to the beginning.
Definition: linearizer.cpp:701
Iterator< triangle_indices_t > triangle_indices_begin() const
Return the appropriate iterator pointing to the beginning.
Definition: linearizer.cpp:715
Simple Linearizer criterion - every element is refined exactly the same number of times...
Iterator< typename LinearizerDataDimensions::triangle_t > triangles_begin() const
Return the appropriate iterator pointing to the beginning.
Definition: linearizer.cpp:687
void calc_vertices_aabb(double *min_x, double *max_x, double *min_y, double *max_y) const
Returns axis aligned bounding box (AABB) of vertices. Assumes lock.
Definition: linearizer.cpp:511
Abstract class for criterion according to which the linearizer stops dividing elements at some point ...
bool end
The iterator has reached the end of the data.
Definition: linearizer.h:94