16 #include "orderizer.h"
19 #include "orderizer_quad.cpp"
28 static unsigned char* ord_np[2] = { num_vert_tri, num_vert_quad };
29 static double3* ord_tables_tri[2] = { vert_tri0, vert_tri1 };
30 static double3* ord_tables_quad[2] = { vert_quad0, vert_quad1 };
31 static double3** ord_tables[2] = { ord_tables_tri, ord_tables_quad };
34 static unsigned short* num_elem[2] = { num_elem_tri, num_elem_quad };
35 static int3* ord_elem_tri[2] = { elem_tri0, elem_tri1 };
36 static int3* ord_elem_quad[2] = { elem_quad0, elem_quad1 };
37 static int3** ord_elem[2] = { ord_elem_tri, ord_elem_quad };
40 static unsigned short* num_edge[2] = { num_edge_tri, num_edge_quad };
41 static int3* ord_edge_tri[2] = { edge_tri0, edge_tri1 };
42 static int3* ord_edge_quad[2] = { edge_quad0, edge_quad1 };
43 static int3** ord_edge[2] = { ord_edge_tri, ord_edge_quad };
46 static unsigned char* ord_np_simple[2] = { num_vert_tri_simple, num_vert_quad_simple };
47 static double3* ord_tables_tri_simple[2] = { vert_tri_simple, vert_tri_simple };
48 static double3* ord_tables_quad_simple[2] = { vert_quad_simple, vert_quad_simple };
49 static double3** ord_tables_simple[2] = { ord_tables_tri_simple, ord_tables_quad_simple };
52 static unsigned short* num_elem_simple[2] = { num_elem_tri_simple, num_elem_quad_simple };
53 static int3* ord_elem_tri_simple[2] = { elem_tri_simple, elem_tri_simple };
54 static int3* ord_elem_quad_simple[2] = { elem_quad_simple, elem_quad_simple };
55 static int3** ord_elem_simple[2] = { ord_elem_tri_simple, ord_elem_quad_simple };
58 static unsigned short* num_edge_simple[2] = { num_edge_tri_simple, num_edge_quad_simple };
59 static int3* ord_edge_tri_simple[2] = { edge_tri_simple, edge_tri_simple };
60 static int3* ord_edge_quad_simple[2] = { edge_quad_simple, edge_quad_simple };
61 static int3** ord_edge_simple[2] = { ord_edge_tri_simple, ord_edge_quad_simple };
63 static class Quad2DOrd :
public Quad2D
69 max_order[0] = max_order[1] = 1;
70 num_tables[0] = num_tables[1] = 2;
75 virtual unsigned char get_id()
81 static class Quad2DOrdSimple :
public Quad2D
87 max_order[0] = max_order[1] = 1;
88 num_tables[0] = num_tables[1] = 2;
89 tables = ord_tables_simple;
93 virtual unsigned char get_id()
99 Orderizer::Orderizer()
103 this->label_size = 0;
117 for (
int i = 0, p = 0; i <= 10; i++)
119 for (
int j = 0; j <= 10; j++)
121 assert((
unsigned)p <
sizeof(buffer) - 5);
123 sprintf(buffer + p,
"%d", i);
125 sprintf(buffer + p,
"%d|%d", i, j);
126 labels[i][j] = buffer + p;
127 p += strlen(buffer + p) + 1;
131 pthread_mutexattr_t attr;
132 pthread_mutexattr_init(&attr);
133 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
134 pthread_mutex_init(&data_mutex, &attr);
135 pthread_mutexattr_destroy(&attr);
139 int Orderizer::add_vertex()
148 throw Exceptions::Exception(
"Orderizer out of memory!");
154 void Orderizer::make_vert(
int & index,
double x,
double y,
double val)
156 index = add_vertex();
159 verts[index][2] = val;
162 static const int default_allocation_multiplier_vertices = 10;
163 static const int default_allocation_multiplier_triangles = 15;
164 static const int default_allocation_multiplier_edges = 10;
166 static const int default_allocation_minsize_vertices = 10000;
167 static const int default_allocation_minsize_triangles = 15000;
168 static const int default_allocation_minsize_edges = 10000;
172 int number_of_elements = mesh->get_num_elements();
174 this->
vertex_size = std::max(default_allocation_multiplier_vertices * number_of_elements, std::max(this->
vertex_size, default_allocation_minsize_vertices));
175 this->triangle_size = std::max(default_allocation_multiplier_triangles * number_of_elements, std::max(this->triangle_size, default_allocation_minsize_triangles));
176 this->edges_size = std::max(default_allocation_multiplier_edges * number_of_elements, std::max(this->edges_size, default_allocation_minsize_edges));
180 this->triangle_count = 0;
181 this->edges_count = 0;
183 this->
tris = (int3*)realloc(this->
tris,
sizeof(int3)* this->triangle_size);
185 this->
edges = (int2*)realloc(this->
edges,
sizeof(int2)* this->edges_size);
189 throw Exceptions::Exception(
"Orderizer out of memory!");
191 this->label_size = std::max(this->label_size, number_of_elements + 10);
192 this->label_count = 0;
196 this->lvert = realloc_with_check<Orderizer, int>(this->lvert, label_size,
this);
198 ltext = realloc_with_check<Orderizer, char *>(this->ltext, label_size,
this);
200 lbox = realloc_with_check<Orderizer, double2>(this->lbox, label_size,
this);
203 Orderizer::~Orderizer()
207 pthread_mutex_destroy(&data_mutex);
211 void Orderizer::lock_data()
const
214 pthread_mutex_lock(&data_mutex);
218 void Orderizer::unlock_data()
const
221 pthread_mutex_unlock(&data_mutex);
224 template<
typename Scalar>
228 if (space ==
nullptr)
229 throw Hermes::Exceptions::Exception(
"Space is nullptr in Orderizer:process_space().");
231 if (!space->is_up_to_date())
232 throw Hermes::Exceptions::Exception(
"The space is not up to date.");
234 MeshSharedPtr mesh = space->get_mesh();
245 for_all_active_elements(e, mesh)
247 oo = o[4] = o[5] = space->get_element_order(e->
id);
248 if (show_edge_orders)
249 for (
unsigned int k = 0; k < e->get_nvert(); k++)
250 o[k] = space->get_edge_order(e, k);
251 else if (e->is_curved())
253 if (e->is_triangle())
254 for (
unsigned int k = 0; k < e->get_nvert(); k++)
257 for (
unsigned int k = 0; k < e->get_nvert(); k++)
265 if (show_edge_orders || e->is_curved())
272 pt = quad_ord.get_points(1, e->get_mode());
273 np = quad_ord.get_num_points(1, e->get_mode());
282 pt = quad_ord_simple.get_points(1, e->get_mode());
283 np = quad_ord_simple.get_num_points(1, e->get_mode());
289 int mode = e->get_mode();
293 o[5] = H2D_GET_V_ORDER(oo);
295 if (show_edge_orders || e->is_curved())
297 make_vert(lvert[label_count], x[0], y[0], o[4]);
299 for (
int i = 1; i < np; i++)
300 make_vert(
id[i - 1], x[i], y[i], o[(
int)pt[i][2]]);
302 for (
int i = 0; i < num_elem[mode][1]; i++)
303 this->add_triangle(
id[ord_elem[mode][1][i][0]],
id[ord_elem[mode][1][i][1]],
id[ord_elem[mode][1][i][2]], e->
marker);
305 for (
int i = 0; i < num_edge[mode][1]; i++)
307 if (e->
en[ord_edge[mode][1][i][2]]->
bnd || (y[ord_edge[mode][1][i][0] + 1] < y[ord_edge[mode][1][i][1] + 1]) ||
308 ((y[ord_edge[mode][1][i][0] + 1] == y[ord_edge[mode][1][i][1] + 1]) &&
309 (x[ord_edge[mode][1][i][0] + 1] < x[ord_edge[mode][1][i][1] + 1])))
311 add_edge(
id[ord_edge[mode][1][i][0]],
id[ord_edge[mode][1][i][1]], e->
en[ord_edge[mode][1][i][2]]->
marker);
317 make_vert(lvert[label_count], x[0], y[0], o[4]);
319 for (
int i = 1; i < np; i++)
320 make_vert(
id[i - 1], x[i], y[i], o[(
int)pt[i][2]]);
322 for (
int i = 0; i < num_elem_simple[mode][1]; i++)
323 this->add_triangle(
id[ord_elem_simple[mode][1][i][0]],
id[ord_elem_simple[mode][1][i][1]],
id[ord_elem_simple[mode][1][i][2]], e->
marker);
325 for (
int i = 0; i < num_edge_simple[mode][1]; i++)
326 add_edge(
id[ord_edge_simple[mode][1][i][0]],
id[ord_edge_simple[mode][1][i][1]], e->
en[ord_edge_simple[mode][1][i][2]]->
marker);
329 double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100;
330 for (
unsigned int k = 0; k < e->get_nvert(); k++)
332 if (e->
vn[k]->
x < xmin) xmin = e->
vn[k]->
x;
333 if (e->
vn[k]->
x > xmax) xmax = e->
vn[k]->
x;
334 if (e->
vn[k]->y < ymin) ymin = e->
vn[k]->y;
335 if (e->
vn[k]->y > ymax) ymax = e->
vn[k]->y;
337 lbox[label_count][0] = xmax - xmin;
338 lbox[label_count][1] = ymax - ymin;
339 ltext[label_count++] = labels[o[4]][o[5]];
345 void Orderizer::add_edge(
int iv1,
int iv2,
int marker)
347 #pragma omp critical(realloc_edges)
349 if (edges_count >= edges_size)
351 edges = (int2*)realloc(
edges,
sizeof(int2)* (edges_size * 1.5));
354 edges[edges_count][0] = iv1;
355 edges[edges_count][1] = iv2;
360 void Orderizer::add_triangle(
int iv0,
int iv1,
int iv2,
int marker)
363 #pragma omp critical(realloc_triangles)
365 if (triangle_count >= triangle_size)
367 this->triangle_size *= 2;
369 tris = (int3*)realloc(
tris,
sizeof(int3)* triangle_size);
373 throw Exceptions::Exception(
"Orderizer out of memory!");
376 index = triangle_count++;
378 tris[index][0] = iv0;
379 tris[index][1] = iv1;
380 tris[index][2] = iv2;
384 void Orderizer::free()
386 free_with_check(
verts,
true);
387 free_with_check(lvert,
true);
388 free_with_check(ltext,
true);
389 free_with_check(lbox,
true);
390 free_with_check(
tris,
true);
392 free_with_check(
edges,
true);
396 template<
typename Scalar>
401 FILE* f = fopen(file_name,
"wb");
402 if (f ==
nullptr)
throw Hermes::Exceptions::Exception(
"Could not open %s for writing.", file_name);
405 fprintf(f,
"# vtk DataFile Version 2.0\n");
407 fprintf(f,
"ASCII\n\n");
408 fprintf(f,
"DATASET UNSTRUCTURED_GRID\n");
411 fprintf(f,
"POINTS %d %s\n", this->
vertex_count,
"float");
414 fprintf(f,
"%g %g %g\n", this->
verts[i][0], this->
verts[i][1], 0.);
419 fprintf(f,
"CELLS %d %d\n", this->triangle_count, 4 * this->triangle_count);
420 for (
int i = 0; i < this->triangle_count; i++)
422 fprintf(f,
"3 %d %d %d\n", this->
tris[i][0], this->
tris[i][1], this->
tris[i][2]);
427 fprintf(f,
"CELL_TYPES %d\n", this->triangle_count);
429 for (
int i = 0; i < this->triangle_count; i++)
436 fprintf(f,
"POINT_DATA %d\n", this->vertex_count);
437 fprintf(f,
"SCALARS %s %s %d\n",
"Mesh",
"float", 1);
438 fprintf(f,
"LOOKUP_TABLE %s\n",
"default");
440 fprintf(f,
"%g \n", this->
verts[i][2]);
444 template<
typename Scalar>
449 FILE* f = fopen(file_name,
"wb");
450 if (f ==
nullptr)
throw Hermes::Exceptions::Exception(
"Could not open %s for writing.", file_name);
453 fprintf(f,
"# vtk DataFile Version 2.0\n");
455 fprintf(f,
"ASCII\n\n");
456 fprintf(f,
"DATASET UNSTRUCTURED_GRID\n");
459 fprintf(f,
"POINTS %d %s\n", this->
vertex_count,
"float");
462 fprintf(f,
"%g %g %g\n", this->
verts[i][0], this->
verts[i][1], 0.);
467 fprintf(f,
"CELLS %d %d\n", this->triangle_count, 4 * this->triangle_count);
468 for (
int i = 0; i < this->triangle_count; i++)
470 fprintf(f,
"3 %d %d %d\n", this->
tris[i][0], this->
tris[i][1], this->
tris[i][2]);
475 fprintf(f,
"CELL_TYPES %d\n", this->triangle_count);
477 for (
int i = 0; i < this->triangle_count; i++)
484 fprintf(f,
"CELL_DATA %d\n", this->triangle_count);
485 fprintf(f,
"SCALARS %s %s %d\n",
"Mesh",
"float", 1);
486 fprintf(f,
"LOOKUP_TABLE %s\n",
"default");
487 for (
int i = 0; i < this->triangle_count; i++)
492 template<
typename Scalar>
497 FILE* f = fopen(file_name,
"wb");
498 if (f ==
nullptr)
throw Hermes::Exceptions::Exception(
"Could not open %s for writing.", file_name);
501 fprintf(f,
"# vtk DataFile Version 2.0\n");
503 fprintf(f,
"ASCII\n\n");
504 fprintf(f,
"DATASET UNSTRUCTURED_GRID\n");
507 fprintf(f,
"POINTS %d %s\n", this->
vertex_count,
"float");
509 fprintf(f,
"%g %g %g\n", this->
verts[i][0], this->
verts[i][1], 0.0);
513 fprintf(f,
"CELLS %d %d\n", this->edges_count, +3 * this->edges_count);
514 for (
int i = 0; i < this->edges_count; i++)
515 fprintf(f,
"2 %d %d\n", this->
edges[i][0], this->
edges[i][1]);
519 fprintf(f,
"CELL_TYPES %d\n", this->edges_count);
521 for (
int i = 0; i < this->edges_count; i++)
528 fprintf(f,
"CELL_DATA %d\n", this->edges_count);
529 fprintf(f,
"SCALARS %s %s %d\n",
"Mesh",
"float", 1);
530 fprintf(f,
"LOOKUP_TABLE %s\n",
"default");
531 for (
int i = 0; i < this->edges_count; i++)
536 int Orderizer::get_labels(
int*& lvert,
char**& ltext, double2*& lbox)
const
546 if (
verts ==
nullptr)
547 throw Exceptions::Exception(
"Cannot calculate AABB from nullptr vertices");
551 void Orderizer::calc_aabb(
double* x,
double* y,
int stride,
int num,
double* min_x,
double* max_x,
double* min_y,
double* max_y)
553 *min_x = *max_x = *x;
554 *min_y = *max_y = *y;
556 uint8_t* ptr_x = (uint8_t*)x;
557 uint8_t* ptr_y = (uint8_t*)y;
558 for (
int i = 0; i < num; i++, ptr_x += stride, ptr_y += stride)
560 *min_x = std::min(*min_x, *((
double*)ptr_x));
561 *min_y = std::min(*min_y, *((
double*)ptr_y));
562 *max_x = std::max(*max_x, *((
double*)ptr_x));
563 *max_y = std::max(*max_y, *((
double*)ptr_y));
567 double3* Orderizer::get_vertices()
572 int Orderizer::get_num_vertices()
577 int3* Orderizer::get_triangles()
582 int* Orderizer::get_triangle_markers()
587 int Orderizer::get_num_triangles()
589 return this->triangle_count;
592 int2* Orderizer::get_edges()
597 int* Orderizer::get_edge_markers()
602 int Orderizer::get_num_edges()
604 return this->edges_count;
607 template HERMES_API
void Orderizer::save_orders_vtk<double>(
const SpaceSharedPtr<double> space,
const char* file_name);
608 template HERMES_API
void Orderizer::save_orders_vtk<std::complex<double> >(
const SpaceSharedPtr<std::complex<double> > space,
const char* file_name);
609 template HERMES_API
void Orderizer::save_markers_vtk<double>(
const SpaceSharedPtr<double> space,
const char* file_name);
610 template HERMES_API
void Orderizer::save_markers_vtk<std::complex<double> >(
const SpaceSharedPtr<std::complex<double> > space,
const char* file_name);
611 template HERMES_API
void Orderizer::save_mesh_vtk<double>(
const SpaceSharedPtr<double> space,
const char* file_name);
612 template HERMES_API
void Orderizer::save_mesh_vtk<std::complex<double> >(
const SpaceSharedPtr<std::complex<double> > space,
const char* file_name);
613 template HERMES_API
void Orderizer::process_space<double>(
const SpaceSharedPtr<double> space, bool);
614 template HERMES_API
void Orderizer::process_space<std::complex<double> >(
const SpaceSharedPtr<std::complex<double> > space, bool);
double x
vertex node coordinates
double * get_phys_y(int order)
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.
Stores one element of a mesh.
Used to pass the instances of Space around.
int3 * tris
triangles: vertex index triplets
double * get_phys_x(int order)
int * tri_markers
triangle_markers: triangle markers, ordering equal to tris
Node * en[H2D_MAX_NUMBER_EDGES]
edge node pointers
#define H2D_GET_H_ORDER(encoded_order)
Macros for combining quad horizontal and vertical encoded_orders.
void process_space(SpaceSharedPtr< Scalar > space, bool show_edge_orders=false)
Internal.
unsigned bnd
1 = boundary node; 0 = inner node
void set_quad_2d(Quad2D *quad_2d)
void save_mesh_vtk(SpaceSharedPtr< Scalar > space, const char *file_name)
Saves the mesh - edges.
void save_orders_vtk(SpaceSharedPtr< Scalar > space, const char *file_name)
Saves the polynomial orders.
Represents the reference mapping.
void reallocate(MeshSharedPtr mesh)
int vertex_count
Real numbers of vertices, triangles and edges.
int * edge_markers
edge_markers: edge markers, ordering equal to edges
int2 * edges
edges: pairs of vertex indices
void save_markers_vtk(SpaceSharedPtr< Scalar > space, const char *file_name)
Saves the mesh with markers.
int vertex_size
Size of arrays of vertices, triangles and edges.
virtual void set_active_element(Element *e)
Node * vn[H2D_MAX_NUMBER_VERTICES]
vertex node pointers
double3 * verts
vertices: (x, y, value) triplets