16 #include "orderizer.h"
19 #include "linear_data.cpp"
28 static int* 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 int* 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 int* 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 };
45 static class Quad2DOrd :
public Quad2D
51 max_order[0] = max_order[1] = 1;
52 num_tables[0] = num_tables[1] = 2;
57 virtual void dummy_fn() {}
60 Orderizer::Orderizer() : LinearizerBase()
69 label_count = cl1 = cl2 = cl3 = 0;
71 for (
int i = 0, p = 0; i <= 10; i++)
73 for (
int j = 0; j <= 10; j++)
75 assert((
unsigned) p <
sizeof(
buffer)-5);
77 sprintf(
buffer + p,
"%d", i);
79 sprintf(
buffer + p,
"%d|%d", i, j);
81 p += strlen(
buffer + p) + 1;
86 int Orderizer::add_vertex()
88 if(this->vertex_count >= this->vertex_size)
90 this->vertex_size *= 2;
91 verts = (double3*) realloc(
verts,
sizeof(double3) * vertex_size);
92 this->
info = (int4*) realloc(
info,
sizeof(int4) * vertex_size);
94 return this->vertex_count++;
97 void Orderizer::make_vert(
int & index,
double x,
double y,
double val)
102 verts[index][2] = val;
105 template<
typename Scalar>
106 void Orderizer::process_space(
const Space<Scalar>* space)
109 if(space == NULL)
throw Hermes::Exceptions::Exception(
"Space is NULL in Orderizer:process_space().");
111 if(!space->is_up_to_date())
112 throw Hermes::Exceptions::Exception(
"The space is not up to date.");
121 Mesh* mesh = space->get_mesh();
124 throw Hermes::Exceptions::Exception(
"Mesh is NULL in Orderizer:process_space().");
126 int nn = mesh->get_num_active_elements();
127 this->vertex_size = std::max(this->vertex_size, 77 * nn);
128 this->triangle_size = std::max(this->triangle_size, 64 * nn);
130 this->label_size = std::max(this->label_size, nn + 10);
131 cl1 = cl2 = cl3 = label_size;
134 verts = (double3*) realloc(
verts,
sizeof(double3) * vertex_size);
135 this->
tris = (int3*) realloc(this->
tris,
sizeof(int3) * this->triangle_size);
139 tris_orders = (
int*) realloc(tris_orders,
sizeof(
int) * triangle_size);
142 lvert = (
int*) realloc(lvert,
sizeof(
int) * label_size);
143 ltext = (
char**) realloc(ltext,
sizeof(
char*) * label_size);
144 lbox = (double2*) realloc(lbox,
sizeof(double2) * label_size);
149 refmap.set_quad_2d(&quad_ord);
153 for_all_active_elements(e, mesh)
155 oo = o[4] = o[5] = space->get_element_order(e->id);
156 for (
unsigned int k = 0; k < e->get_nvert(); k++)
157 o[k] = space->get_edge_order(e, k);
159 refmap.set_active_element(e);
160 double* x = refmap.get_phys_x(type);
161 double* y = refmap.get_phys_y(type);
163 double3* pt = quad_ord.get_points(type, e->get_mode());
164 int np = quad_ord.get_num_points(type, e->get_mode());
168 int mode = e->get_mode();
172 o[5] = H2D_GET_V_ORDER(oo);
174 make_vert(lvert[label_count], x[0], y[0], o[4]);
176 for (
int i = 1; i < np; i++)
177 make_vert(
id[i-1], x[i], y[i], o[(
int) pt[i][2]]);
179 for (
int i = 0; i < num_elem[mode][
type]; i++)
180 this->add_triangle(
id[ord_elem[mode][type][i][0]],
id[ord_elem[mode][type][i][1]],
id[ord_elem[mode][type][i][2]], o[4], e->marker);
182 for (
int i = 0; i < num_edge[mode][
type]; i++)
184 if(e->en[ord_edge[mode][type][i][2]]->bnd || (y[ord_edge[mode][type][i][0] + 1] < y[ord_edge[mode][type][i][1] + 1]) ||
185 ((y[ord_edge[mode][type][i][0] + 1] == y[ord_edge[mode][type][i][1] + 1]) &&
186 (x[ord_edge[mode][type][i][0] + 1] < x[ord_edge[mode][type][i][1] + 1])))
188 LinearizerBase::add_edge(
id[ord_edge[mode][type][i][0]],
id[ord_edge[mode][type][i][1]], e->en[ord_edge[mode][type][i][2]]->marker);
192 double xmin = 1e100, ymin = 1e100, xmax = -1e100, ymax = -1e100;
193 for (
unsigned int k = 0; k < e->get_nvert(); k++)
195 if(e->vn[k]->x < xmin) xmin = e->vn[k]->x;
196 if(e->vn[k]->x > xmax) xmax = e->vn[k]->x;
197 if(e->vn[k]->y < ymin) ymin = e->vn[k]->y;
198 if(e->vn[k]->y > ymax) ymax = e->vn[k]->y;
200 lbox[label_count][0] = xmax - xmin;
201 lbox[label_count][1] = ymax - ymin;
202 ltext[label_count++] = labels[o[4]][o[5]];
205 refmap.set_quad_2d(&g_quad_2d_std);
208 void Orderizer::add_triangle(
int iv0,
int iv1,
int iv2,
int order,
int marker)
211 #pragma omp critical(realloc_triangles)
219 if(triangle_count >= triangle_size)
222 tris = (int3*) realloc(
tris,
sizeof(int3) * (triangle_size * 2));
223 tris_orders = (
int*) realloc(tris_orders,
sizeof(
int) * (triangle_size = triangle_size * 2));
225 index = triangle_count++;
227 tris[index][0] = iv0;
228 tris[index][1] = iv1;
229 tris[index][2] = iv2;
230 tris_orders[index] = order;
236 void Orderizer::free()
258 if(tris_orders != NULL)
267 Orderizer::~Orderizer()
272 template<
typename Scalar>
275 process_space(space);
277 FILE* f = fopen(file_name,
"wb");
278 if(f == NULL)
throw Hermes::Exceptions::Exception(
"Could not open %s for writing.", file_name);
282 fprintf(f,
"# vtk DataFile Version 2.0\n");
284 fprintf(f,
"ASCII\n\n");
285 fprintf(f,
"DATASET UNSTRUCTURED_GRID\n");
288 fprintf(f,
"POINTS %d %s\n", this->vertex_count,
"float");
289 for (
int i = 0; i < this->vertex_count; i++)
291 fprintf(f,
"%g %g %g\n", this->
verts[i][0], this->
verts[i][1], 0.0);
296 fprintf(f,
"CELLS %d %d\n", this->triangle_count, 4 * this->triangle_count);
297 for (
int i = 0; i < this->triangle_count; i++)
299 fprintf(f,
"3 %d %d %d\n", this->
tris[i][0], this->
tris[i][1], this->
tris[i][2]);
304 fprintf(f,
"CELL_TYPES %d\n", this->triangle_count);
305 for (
int i = 0; i < this->triangle_count; i++)
313 fprintf(f,
"CELL_DATA %d\n", this->triangle_count);
314 fprintf(f,
"SCALARS %s %s %d\n",
"Mesh",
"float", 1);
315 fprintf(f,
"LOOKUP_TABLE %s\n",
"default");
316 for (
int i = 0; i < this->triangle_count; i++)
318 fprintf(f,
"%i\n", this->tris_orders[i]);
325 template<
typename Scalar>
326 void Orderizer::save_mesh_vtk(
const Space<Scalar>* space,
const char* file_name)
328 process_space(space);
330 FILE* f = fopen(file_name,
"wb");
331 if(f == NULL)
throw Hermes::Exceptions::Exception(
"Could not open %s for writing.", file_name);
335 fprintf(f,
"# vtk DataFile Version 2.0\n");
337 fprintf(f,
"ASCII\n\n");
338 fprintf(f,
"DATASET UNSTRUCTURED_GRID\n");
341 fprintf(f,
"POINTS %d %s\n", this->vertex_count,
"float");
342 for (
int i = 0; i < this->vertex_count; i++)
343 fprintf(f,
"%g %g %g\n", this->
verts[i][0], this->
verts[i][1], 0.0);
349 fprintf(f,
"2 %d %d\n", this->
edges[i][0], this->
edges[i][1]);
353 fprintf(f,
"CELL_TYPES %d\n", this->edges_count);
361 fprintf(f,
"CELL_DATA %d\n", this->edges_count);
362 fprintf(f,
"SCALARS %s %s %d\n",
"Mesh",
"float", 1);
363 fprintf(f,
"LOOKUP_TABLE %s\n",
"default");
370 int Orderizer::get_labels(
int*& lvert,
char**& ltext, double2*& lbox)
const
381 throw Exceptions::Exception(
"Cannot calculate AABB from NULL vertices");
382 calc_aabb(&
verts[0][0], &
verts[0][1],
sizeof(double3), vertex_count, min_x, max_x, min_y, max_y);
385 double3* Orderizer::get_vertices()
389 int Orderizer::get_num_vertices()
391 return this->vertex_count;
394 template HERMES_API
void Orderizer::save_orders_vtk<double>(
const Space<double>* space,
const char* file_name);
395 template HERMES_API
void Orderizer::save_orders_vtk<std::complex<double> >(
const Space<std::complex<double> >* space,
const char* file_name);
396 template HERMES_API
void Orderizer::save_mesh_vtk<double>(
const Space<double>* space,
const char* file_name);
397 template HERMES_API
void Orderizer::save_mesh_vtk<std::complex<double> >(
const Space<std::complex<double> >* space,
const char* file_name);
398 template HERMES_API
void Orderizer::process_space<double>(
const Space<double>* space);
399 template HERMES_API
void Orderizer::process_space<std::complex<double> >(
const Space<std::complex<double> >* space);