19 #include "exact_solution.h"
24 static const int default_allocation_multiplier_vertices = 10;
25 static const int default_allocation_multiplier_triangles = 15;
26 static const int default_allocation_multiplier_edges = 10;
28 static const int default_allocation_minsize_vertices = 10000;
29 static const int default_allocation_minsize_triangles = 15000;
30 static const int default_allocation_minsize_edges = 10000;
32 static const double vertex_relative_tolerance = 0.01;
40 template<
typename LinearizerDataDimensions>
41 ThreadLinearizerMultidimensional<LinearizerDataDimensions>::ThreadLinearizerMultidimensional(LinearizerMultidimensional<LinearizerDataDimensions>* linearizer) : criterion(linearizer->criterion)
50 edge_markers =
nullptr;
53 triangle_indices =
nullptr;
57 triangle_markers =
nullptr;
62 template<
typename LinearizerDataDimensions>
63 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::init_linearizer_data(LinearizerMultidimensional<LinearizerDataDimensions>* linearizer)
65 this->criterion = linearizer->criterion;
66 this->curvature_epsilon = linearizer->curvature_epsilon;
67 this->user_xdisp = linearizer->user_xdisp;
68 this->user_ydisp = linearizer->user_ydisp;
69 this->dmult = linearizer->dmult;
70 this->linearizerOutputType = linearizer->linearizerOutputType;
72 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
74 this->component[k] = linearizer->component[k];
75 this->item[k] = linearizer->item[k];
76 this->value_type[k] = linearizer->value_type[k];
80 template<
typename LinearizerDataDimensions>
84 free_with_check(this->triangles,
true);
85 free_with_check(this->edges,
true);
86 free_with_check(this->edge_markers,
true);
88 free_with_check(this->triangle_indices,
true);
90 free_with_check(this->vertices,
true);
91 free_with_check(this->triangle_markers,
true);
92 free_with_check(this->hash_table,
true);
93 free_with_check(this->info,
true);
96 template<
typename LinearizerDataDimensions>
102 template<
typename LinearizerDataDimensions>
103 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::init_processing(
MeshFunctionSharedPtr<double>* sln, LinearizerMultidimensional<LinearizerDataDimensions>* linearizer)
105 this->init_linearizer_data(linearizer);
108 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
111 if (solution && solution->
get_type() == HERMES_SLN)
114 fns[k]->
copy(solution);
117 fns[k] = sln[k]->clone();
118 fns[k]->set_quad_2d(&g_quad_lin);
122 Solution<double>* xdisp_solution =
dynamic_cast<Solution<double>*
>(linearizer->xdisp.get());
123 if (xdisp_solution && xdisp_solution->get_type() == HERMES_SLN)
125 fns[LinearizerDataDimensions::dimension] =
new Solution<double>();
126 fns[LinearizerDataDimensions::dimension]->copy(linearizer->xdisp);
129 fns[LinearizerDataDimensions::dimension] = linearizer->xdisp->clone();
131 fns[LinearizerDataDimensions::dimension]->set_quad_2d(&g_quad_lin);
135 Solution<double>* ydisp_solution =
dynamic_cast<Solution<double>*
>(linearizer->ydisp.get());
136 if (ydisp_solution && ydisp_solution->get_type() == HERMES_SLN)
138 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)] =
new Solution<double>();
139 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->copy(linearizer->ydisp);
142 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)] = linearizer->ydisp->clone();
144 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->set_quad_2d(&g_quad_lin);
148 this->reallocate(sln[0]->get_mesh());
151 template<
typename LinearizerDataDimensions>
152 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::reallocate(MeshSharedPtr mesh)
154 int number_of_elements = mesh->get_num_elements();
156 this->vertex_size = std::max(default_allocation_multiplier_vertices * number_of_elements, std::max(this->vertex_size, default_allocation_minsize_vertices));
157 this->triangle_size = std::max(default_allocation_multiplier_triangles * number_of_elements, std::max(this->triangle_size, default_allocation_minsize_triangles));
158 this->edges_size = std::max(default_allocation_multiplier_edges * number_of_elements, std::max(this->edges_size, default_allocation_minsize_edges));
161 this->vertex_count = 0;
162 this->triangle_count = 0;
163 this->edges_count = 0;
165 if (this->linearizerOutputType == OpenGL)
167 this->triangles = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::triangle_t>(this->triangles, this->triangle_size,
this);
168 this->edges = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::edge_t>(this->edges, this->edges_size,
this);
169 this->edge_markers = realloc_with_check<ThreadLinearizerMultidimensional, int>(this->edge_markers, this->edges_size,
this);
172 this->triangle_indices = realloc_with_check<ThreadLinearizerMultidimensional, triangle_indices_t>(this->triangle_indices, this->triangle_size,
this);
174 this->vertices = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::vertex_t>(this->vertices, this->vertex_size,
this);
175 this->triangle_markers = realloc_with_check<ThreadLinearizerMultidimensional, int>(this->triangle_markers, this->triangle_size,
this);
177 this->hash_table = malloc_with_check<ThreadLinearizerMultidimensional<LinearizerDataDimensions>,
int>(this->vertex_size,
this,
true);
178 memset(this->hash_table, 0xff,
sizeof(
int)* this->vertex_size);
180 this->info = malloc_with_check<ThreadLinearizerMultidimensional<LinearizerDataDimensions>,
internal_vertex_info_t>(this->vertex_size,
this,
true);
183 template<
typename LinearizerDataDimensions>
184 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::deinit_processing()
186 for (
unsigned int j = 0; j < (LinearizerDataDimensions::dimension + (this->user_xdisp ? 1 : 0) + (this->user_ydisp ? 1 : 0)); j++)
189 free_with_check(this->hash_table,
true);
190 free_with_check(this->info,
true);
193 template<
typename LinearizerDataDimensions>
194 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::process_state(Traverse::State* current_state)
196 this->rep_element = current_state->e[0];
197 this->curved = this->rep_element->is_curved();
198 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
200 fns[k]->set_active_element(current_state->e[k]);
201 fns[k]->set_transform(current_state->sub_idx[k]);
202 fns[k]->set_quad_order(0, this->item[k]);
203 val[k] = fns[k]->get_values(component[k], value_type[k]);
206 const double *dx =
nullptr;
207 const double *dy =
nullptr;
211 fns[LinearizerDataDimensions::dimension]->set_active_element(current_state->e[LinearizerDataDimensions::dimension]);
212 fns[LinearizerDataDimensions::dimension]->set_transform(current_state->sub_idx[LinearizerDataDimensions::dimension]);
213 fns[LinearizerDataDimensions::dimension]->set_quad_order(0, H2D_FN_VAL);
214 dx = fns[LinearizerDataDimensions::dimension]->get_fn_values();
219 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->set_active_element(current_state->e[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]);
220 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->set_transform(current_state->sub_idx[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]);
221 fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->set_quad_order(0, H2D_FN_VAL);
222 dy = fns[LinearizerDataDimensions::dimension + (user_xdisp ? 1 : 0)]->get_fn_values();
226 for (
unsigned int i = 0; i < this->rep_element->get_nvert(); i++)
228 double x_disp = fns[0]->get_refmap()->get_phys_x(0)[i];
229 double y_disp = fns[0]->get_refmap()->get_phys_y(0)[i];
231 x_disp += dmult * dx[i];
233 y_disp += dmult * dy[i];
235 double value[LinearizerDataDimensions::dimension];
236 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
237 value[k] = val[k][i];
238 iv[i] = this->get_vertex(-this->rep_element->vn[i]->id, -this->rep_element->vn[i]->id, x_disp, y_disp, value);
242 if (current_state->e[0]->is_triangle())
243 process_triangle(iv[0], iv[1], iv[2], 0);
245 process_quad(iv[0], iv[1], iv[2], iv[3], 0);
247 #ifndef DEBUG_LINEARIZER
248 if (this->linearizerOutputType == OpenGL)
250 for (
unsigned int i = 0; i < this->rep_element->get_nvert(); i++)
251 process_edge(iv[i], iv[this->rep_element->next_vert(i)], this->rep_element->en[i]->marker);
256 template<
typename LinearizerDataDimensions>
257 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::process_triangle(
int iv0,
int iv1,
int iv2,
int level)
259 const double* values[LinearizerDataDimensions::dimension];
262 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
264 fns[k]->set_quad_order(1, item[k]);
265 values[k] = fns[k]->get_values(component[k], value_type[k]);
267 unsigned short* vertex_indices = tri_indices[0];
272 RefMap* refmap = fns[0]->get_refmap();
273 physical_x = refmap->get_phys_x(1);
274 physical_y = refmap->get_phys_y(1);
278 fns[LinearizerDataDimensions::dimension]->set_quad_order(1, H2D_FN_VAL);
279 const double* dx = fns[LinearizerDataDimensions::dimension]->get_fn_values();
280 for (
int i = 0; i < lin_np_tri[1]; i++)
281 physical_x[i] += dmult*dx[i];
285 fns[LinearizerDataDimensions::dimension + (this->user_xdisp ? 1 : 0)]->set_quad_order(1, H2D_FN_VAL);
286 const double* dy = fns[LinearizerDataDimensions::dimension + (this->user_xdisp ? 1 : 0)]->get_fn_values();
287 for (
int i = 0; i < lin_np_tri[1]; i++)
288 physical_y[i] += dmult*dy[i];
293 for (
int i = 0; i < 2 + LinearizerDataDimensions::dimension; i++)
295 midval[i][0] = (this->vertices[iv0][i] + this->vertices[iv1][i])*0.5;
296 midval[i][1] = (this->vertices[iv1][i] + this->vertices[iv2][i])*0.5;
297 midval[i][2] = (this->vertices[iv2][i] + this->vertices[iv0][i])*0.5;
306 if (this->criterion.adaptive)
307 this->split_decision(split, iv0, iv1, iv2, 0, rep_element->get_mode(), values, physical_x, physical_y, vertex_indices);
309 split = (level < this->criterion.refinement_level);
317 for (
int i = 0; i < 3; i++)
319 midval[0][i] = physical_x[vertex_indices[i]];
320 midval[1][i] = physical_y[vertex_indices[i]];
324 double values_vertices[5][LinearizerDataDimensions::dimension];
325 for (
int v = 0; v < 3; v++)
327 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
328 values_vertices[v][k] = values[k][vertex_indices[v]];
332 int mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], values_vertices[0]);
333 int mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], values_vertices[1]);
334 int mid2 = get_vertex(iv2, iv0, midval[0][2], midval[1][2], values_vertices[2]);
337 this->push_transforms(0);
338 process_triangle(iv0, mid0, mid2, level + 1);
339 this->pop_transforms();
341 this->push_transforms(1);
342 process_triangle(mid0, iv1, mid1, level + 1);
343 this->pop_transforms();
345 this->push_transforms(2);
346 process_triangle(mid2, mid1, iv2, level + 1);
347 this->pop_transforms();
349 this->push_transforms(3);
350 process_triangle(mid1, mid2, mid0, level + 1);
351 this->pop_transforms();
354 add_triangle(iv0, iv1, iv2, this->rep_element->marker);
356 #ifdef DEBUG_LINEARIZER
357 if (this->linearizerOutputType == OpenGL)
359 process_edge(iv0, iv1, this->rep_element->en[0]->marker);
360 process_edge(iv1, iv2, this->rep_element->en[1]->marker);
361 process_edge(iv2, iv0, this->rep_element->en[2]->marker);
366 template<
typename LinearizerDataDimensions>
367 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::process_quad(
int iv0,
int iv1,
int iv2,
int iv3,
int level)
369 const double* values[LinearizerDataDimensions::dimension];
372 unsigned short* vertex_indices = quad_indices[0];
373 bool flip = this->quad_flip(iv0, iv1, iv2, iv3);
374 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
376 fns[k]->set_quad_order(1, item[k]);
377 values[k] = fns[k]->get_values(component[k], value_type[k]);
383 RefMap* refmap = fns[0]->get_refmap();
384 physical_x = refmap->get_phys_x(1);
385 physical_y = refmap->get_phys_y(1);
389 fns[LinearizerDataDimensions::dimension]->set_quad_order(1, H2D_FN_VAL);
390 const double* dx = fns[LinearizerDataDimensions::dimension]->get_fn_values();
391 for (
int i = 0; i < lin_np_tri[1]; i++)
392 physical_x[i] += dmult*dx[i];
396 fns[LinearizerDataDimensions::dimension + (this->user_xdisp ? 1 : 0)]->set_quad_order(1, H2D_FN_VAL);
397 const double* dy = fns[LinearizerDataDimensions::dimension + (this->user_xdisp ? 1 : 0)]->get_fn_values();
398 for (
int i = 0; i < lin_np_tri[1]; i++)
399 physical_y[i] += dmult*dy[i];
404 for (
int i = 0; i < 2 + LinearizerDataDimensions::dimension; i++)
406 midval[i][0] = (this->vertices[iv0][i] + this->vertices[iv1][i]) * 0.5;
407 midval[i][1] = (this->vertices[iv1][i] + this->vertices[iv2][i]) * 0.5;
408 midval[i][2] = (this->vertices[iv2][i] + this->vertices[iv3][i]) * 0.5;
409 midval[i][3] = (this->vertices[iv3][i] + this->vertices[iv0][i]) * 0.5;
410 midval[i][4] = (midval[i][0] + midval[i][2]) * 0.5;
414 midval[LinearizerDataDimensions::dimension + 1][4] = flip ?
415 (this->vertices[iv0][LinearizerDataDimensions::dimension + 1] + this->vertices[iv2][LinearizerDataDimensions::dimension + 1]) * 0.5
417 (this->vertices[iv1][LinearizerDataDimensions::dimension + 1] + this->vertices[iv3][LinearizerDataDimensions::dimension + 1]) * 0.5;
425 if (this->criterion.adaptive)
426 this->split_decision(split, iv0, iv1, iv2, 0, rep_element->get_mode(), values, physical_x, physical_y, vertex_indices);
428 split = (level < this->criterion.refinement_level ? 3 : 0);
436 for (
int i = 0; i < 5; i++)
438 midval[0][i] = physical_x[vertex_indices[i]];
439 midval[1][i] = physical_y[vertex_indices[i]];
444 int mid0, mid1, mid2, mid3, mid4;
445 double values_vertices[5][LinearizerDataDimensions::dimension];
446 for (
int v = 0; v < 5; v++)
448 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
449 values_vertices[v][k] = values[k][vertex_indices[v]];
451 if (split != 1) mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], values_vertices[0]);
452 if (split != 2) mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], values_vertices[1]);
453 if (split != 1) mid2 = get_vertex(iv2, iv3, midval[0][2], midval[1][2], values_vertices[2]);
454 if (split != 2) mid3 = get_vertex(iv3, iv0, midval[0][3], midval[1][3], values_vertices[3]);
455 if (split == 3) mid4 = get_vertex(mid0, mid2, midval[0][4], midval[1][4], values_vertices[4]);
460 this->push_transforms(0);
461 process_quad(iv0, mid0, mid4, mid3, level + 1);
462 this->pop_transforms();
464 this->push_transforms(1);
465 process_quad(mid0, iv1, mid1, mid4, level + 1);
466 this->pop_transforms();
468 this->push_transforms(2);
469 process_quad(mid4, mid1, iv2, mid2, level + 1);
470 this->pop_transforms();
472 this->push_transforms(3);
473 process_quad(mid3, mid4, mid2, iv3, level + 1);
474 this->pop_transforms();
479 this->push_transforms(4);
480 process_quad(iv0, iv1, mid1, mid3, level + 1);
481 this->pop_transforms();
483 this->push_transforms(5);
484 process_quad(mid3, mid1, iv2, iv3, level + 1);
485 this->pop_transforms();
489 this->push_transforms(6);
490 process_quad(iv0, mid0, mid2, iv3, level + 1);
491 this->pop_transforms();
493 this->push_transforms(7);
494 process_quad(mid0, iv1, iv2, mid2, level + 1);
495 this->pop_transforms();
503 add_triangle(iv3, iv0, iv1, rep_element->marker);
504 add_triangle(iv1, iv2, iv3, rep_element->marker);
508 add_triangle(iv0, iv1, iv2, rep_element->marker);
509 add_triangle(iv2, iv3, iv0, rep_element->marker);
511 #ifdef DEBUG_LINEARIZER
512 if (this->linearizerOutputType == OpenGL)
514 process_edge(iv0, iv1, this->rep_element->en[0]->marker);
515 process_edge(iv1, iv2, this->rep_element->en[1]->marker);
516 process_edge(iv2, iv3, this->rep_element->en[2]->marker);
517 process_edge(iv3, iv0, this->rep_element->en[3]->marker);
523 template<
typename LinearizerDataDimensions>
524 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::split_decision(
int& split,
int iv0,
int iv1,
int iv2,
int iv3,
ElementMode2D mode,
const double** values,
double* physical_x,
double* physical_y,
unsigned short* vertex_indices)
const
531 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
534 double error = fabs(values[k][vertex_indices[0]] - midval[2 + k][0])
535 + fabs(values[k][vertex_indices[1]] - midval[2 + k][1])
536 + fabs(values[k][vertex_indices[2]] - midval[2 + k][2]);
539 if (mode == HERMES_MODE_QUAD)
540 error += fabs(values[k][vertex_indices[3]] - midval[2 + k][3]);
547 double relative_error = error / this->max_value_approx;
552 split = (relative_error > this->criterion.error_tolerance) ? 3 : 0;
555 if (mode == HERMES_MODE_QUAD && split)
557 double horizontal_error = fabs(values[k][vertex_indices[1]] - midval[2 + k][1]) + fabs(values[k][vertex_indices[3]] - midval[2 + k][3]);
558 double vertical_error = fabs(values[k][vertex_indices[0]] - midval[2 + k][0]) + fabs(values[k][vertex_indices[2]] - midval[2 + k][2]);
574 if (curved && split != 3)
576 for (
int i = 0; i < 3 + mode; i++)
578 double error = sqr(physical_x[vertex_indices[i]] - midval[0][i])
579 + sqr(physical_y[vertex_indices[i]] - midval[1][i]);
581 double diameter = sqr(fns[0]->get_active_element()->diameter);
583 split = (error / diameter) > this->curvature_epsilon ? 3 : split;
588 template<
typename LinearizerDataDimensions>
589 double ThreadLinearizerMultidimensional<LinearizerDataDimensions>::get_max_value(Traverse::State* current_state)
591 double local_max = 0.;
592 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
594 fns[k]->set_active_element(current_state->e[k]);
595 fns[k]->set_transform(current_state->sub_idx[k]);
596 fns[k]->set_quad_order(0, this->item[k]);
597 const double* val = fns[k]->get_values(component[k], value_type[k]);
599 for (
unsigned int i = 0; i < current_state->e[k]->get_nvert(); i++)
601 double f = fabs(val[i]);
609 template<
typename LinearizerDataDimensions>
610 bool ThreadLinearizerMultidimensional<LinearizerDataDimensions>::quad_flip(
int iv0,
int iv1,
int iv2,
int iv3)
const
612 int a = (this->vertices[iv0][2] > this->vertices[iv1][2]) ? iv0 : iv1;
613 int b = (this->vertices[iv2][2] > this->vertices[iv3][2]) ? iv2 : iv3;
614 a = (this->vertices[a][2] > this->vertices[b][2]) ? a : b;
615 return (a == iv1 || a == iv3);
618 template<
typename LinearizerDataDimensions>
619 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::push_transforms(
int transform)
621 fns[0]->push_transform(transform);
625 if (fns[1] != fns[0])
626 fns[1]->push_transform(transform);
630 if (fns[this->user_xdisp ? 1 : 2] != fns[0])
632 if (user_xdisp && fns[2] == fns[1])
634 fns[this->user_xdisp ? 1 : 2]->push_transform(transform);
639 template<
typename LinearizerDataDimensions>
640 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::pop_transforms()
642 fns[0]->pop_transform();
646 if (fns[1] != fns[0])
647 fns[1]->pop_transform();
651 if (fns[this->user_xdisp ? 1 : 2] != fns[0])
653 if (user_xdisp && fns[2] == fns[1])
655 fns[this->user_xdisp ? 1 : 2]->pop_transform();
660 template<
typename LinearizerDataDimensions>
661 int ThreadLinearizerMultidimensional<LinearizerDataDimensions>::peek_vertex(
int p1,
int p2)
664 int index = hash(p1 > p2 ? p2 : p1, p1 > p2 ? p1 : p2);
665 int i = hash_table[index];
668 if (info[i][0] == p1 && info[i][1] == p2)
675 template<
typename LinearizerDataDimensions>
676 int ThreadLinearizerMultidimensional<LinearizerDataDimensions>::hash(
int p1,
int p2)
679 return (984120265 * p1 + 125965121 * p2) & (vertex_size - 1);
682 template<
typename LinearizerDataDimensions>
683 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::process_edge(
int iv1,
int iv2,
int marker)
685 int mid = peek_vertex(iv1, iv2);
688 process_edge(iv1, mid, marker);
689 process_edge(mid, iv2, marker);
692 add_edge(iv1, iv2, marker);
695 template<
typename LinearizerDataDimensions>
696 int ThreadLinearizerMultidimensional<LinearizerDataDimensions>::get_vertex(
int p1,
int p2,
double x,
double y,
double* value)
701 int index = this->hash(p1, p2);
703 if (index < this->vertex_count)
705 i = this->hash_table[index];
706 while (i >= 0 && i < this->vertex_count)
708 if ((this->info[i][0] == p1 && this->info[i][1] == p2)
709 && (fabs(x - this->vertices[i][0]) < Hermes::HermesEpsilon)
710 && (fabs(y - this->vertices[i][1]) < Hermes::HermesEpsilon))
712 bool check_value =
true;
713 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
715 if (fabs(value[k] - this->vertices[i][2 + k] / value[k]) > vertex_relative_tolerance)
731 this->vertices[i][0] = x;
732 this->vertices[i][1] = y;
733 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
734 this->vertices[i][2 + k] = value[k];
735 this->info[i][0] = p1;
736 this->info[i][1] = p2;
737 this->info[i][2] = hash_table[index];
738 this->hash_table[index] = i;
742 template<
typename LinearizerDataDimensions>
743 int ThreadLinearizerMultidimensional<LinearizerDataDimensions>::add_vertex()
745 if (this->vertex_count >= this->vertex_size)
747 int new_vertex_size = std::ceil(this->vertex_size * 1.5);
749 this->vertices = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::vertex_t>(this->vertices, new_vertex_size,
this);
750 this->info = realloc_with_check<ThreadLinearizerMultidimensional, internal_vertex_info_t>(this->info, new_vertex_size,
this);
751 this->hash_table = realloc_with_check<ThreadLinearizerMultidimensional, int>(this->hash_table, new_vertex_size,
this);
752 memset(this->hash_table + this->vertex_size, 0xff,
sizeof(
int)* (new_vertex_size - this->vertex_size));
754 this->vertex_size = new_vertex_size;
756 return this->vertex_count++;
759 template<
typename LinearizerDataDimensions>
760 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::add_edge(
int iv1,
int iv2,
int marker)
762 if (edges_count >= edges_size)
764 this->edges_size = std::ceil(this->edges_size * 1.5);
765 this->edges = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::edge_t>(this->edges, this->edges_size,
this);
766 this->edge_markers = realloc_with_check<ThreadLinearizerMultidimensional, int>(this->edge_markers, this->edges_size,
this);
769 this->edges[edges_count][0][0] = this->vertices[iv1][0];
770 this->edges[edges_count][0][1] = this->vertices[iv1][1];
771 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
772 this->edges[edges_count][0][2 + k] = this->vertices[iv1][2 + k];
773 this->edges[edges_count][1][0] = this->vertices[iv2][0];
774 this->edges[edges_count][1][1] = this->vertices[iv2][1];
775 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
776 this->edges[edges_count][1][2 + k] = this->vertices[iv2][2 + k];
777 this->edge_markers[edges_count++] = marker;
780 template<
typename LinearizerDataDimensions>
781 void ThreadLinearizerMultidimensional<LinearizerDataDimensions>::add_triangle(
int iv0,
int iv1,
int iv2,
int marker)
783 if (triangle_count >= triangle_size)
785 this->triangle_size = std::ceil(this->triangle_size * 1.5);
786 if (this->linearizerOutputType == OpenGL)
787 this->triangles = realloc_with_check<ThreadLinearizerMultidimensional, typename LinearizerDataDimensions::triangle_t>(this->triangles, this->triangle_size,
this);
789 this->triangle_indices = realloc_with_check<ThreadLinearizerMultidimensional, triangle_indices_t>(this->triangle_indices, this->triangle_size,
this);
790 this->triangle_markers = realloc_with_check<ThreadLinearizerMultidimensional, int>(this->triangle_markers, this->triangle_size,
this);
793 if (this->linearizerOutputType == OpenGL)
795 this->triangles[triangle_count][0][0] = this->vertices[iv0][0];
796 this->triangles[triangle_count][0][1] = this->vertices[iv0][1];
797 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
798 this->triangles[triangle_count][0][2 + k] = this->vertices[iv0][2 + k];
799 this->triangles[triangle_count][1][0] = this->vertices[iv1][0];
800 this->triangles[triangle_count][1][1] = this->vertices[iv1][1];
801 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
802 this->triangles[triangle_count][1][2 + k] = this->vertices[iv1][2 + k];
803 this->triangles[triangle_count][2][0] = this->vertices[iv2][0];
804 this->triangles[triangle_count][2][1] = this->vertices[iv2][1];
805 for (
int k = 0; k < LinearizerDataDimensions::dimension; k++)
806 this->triangles[triangle_count][2][2 + k] = this->vertices[iv2][2 + k];
810 this->triangle_indices[triangle_count][0] = iv0;
811 this->triangle_indices[triangle_count][1] = iv1;
812 this->triangle_indices[triangle_count][2] = iv2;
815 this->triangle_markers[triangle_count++] = marker;
818 template class HERMES_API ThreadLinearizerMultidimensional < ScalarLinearizerDataDimensions<double> > ;
819 template class HERMES_API ThreadLinearizerMultidimensional < VectorLinearizerDataDimensions<double> > ;
820 template class HERMES_API ThreadLinearizerMultidimensional < ScalarLinearizerDataDimensions<float> > ;
821 template class HERMES_API ThreadLinearizerMultidimensional < VectorLinearizerDataDimensions<float> > ;
virtual void copy(const MeshFunction< Scalar > *sln)
Copy from sln to this instance.
int3 internal_vertex_info_t
Typedefs used throughout the Linearizer functionality.
#define LINEARIZER_DIRECTIONAL_QUAD_REFINEMENT_REQUIREMENT
We refine a quad directionally (horizontally, vertically) only if the error in one direction is this ...
File containing ThreadLinearizerMultidimensional class.
#define H2D_MAX_NUMBER_VERTICES
A maximum number of vertices of an element.
SolutionType get_type() const
Returns solution type.
::xsd::cxx::tree::error< char > error
Error condition.
#define MAX_LINEARIZER_DIVISION_LEVEL
Very important constant putting an upper bound on the maximum number of successive element division (...