20 #include "mesh_reader_h2d.h"
26 extern unsigned g_mesh_seq;
28 MeshReaderH2D::MeshReaderH2D()
32 MeshReaderH2D::~MeshReaderH2D()
36 Nurbs* MeshReaderH2D::load_nurbs(Mesh *mesh, MeshData *m,
int id, Node** en,
int &p1,
int &p2)
40 Nurbs* nurbs =
new Nurbs;
43 bool circle = (m->curv_nurbs[
id] ==
false);
47 p1 = m->curv_first[
id];
48 p2 = m->curv_second[
id];
50 *en = mesh->peek_edge_node(p1, p2);
52 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: edge %d-%d does not exist.",
id, p1, p2);
58 nurbs->degree = m->curv_third[
id];
62 std::vector<double> vCP;
67 for (
unsigned int i = 0; i < m->vars_[m->curv_inner_pts[
id]].size(); ++i)
69 std::istringstream istr(m->vars_[m->curv_inner_pts[
id]][i]);
71 if(!(istr >> dummy_dbl))
72 vCP.push_back(atof(m->vars_[m->vars_[m->curv_inner_pts[
id]][i]][0].c_str()));
74 vCP.push_back(atof(m->vars_[m->curv_inner_pts[
id]][i].c_str()));
78 nurbs->np = inner + 2;
81 nurbs->pt =
new double3[nurbs->np];
82 nurbs->pt[0][0] = mesh->nodes[p1].x;
83 nurbs->pt[0][1] = mesh->nodes[p1].y;
84 nurbs->pt[0][2] = 1.0;
85 nurbs->pt[inner+1][0] = mesh->nodes[p2].x;
86 nurbs->pt[inner+1][1] = mesh->nodes[p2].y;
87 nurbs->pt[inner+1][2] = 1.0;
92 for (
int i = 0; i < inner; i++)
94 for (
int j = 0; j < 3; ++j)
96 nurbs->pt[i + 1][j] = vCP[3*i + j];
103 nurbs->angle = m->curv_third[
id];
104 double a = (180.0 - nurbs->angle) / 180.0 * M_PI;
107 double x = 1.0 / tan(a * 0.5);
108 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
109 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
110 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
114 std::vector<double> vKnots;
119 for (
unsigned int i = 0; i < m->vars_[m->curv_knots[
id]].size(); ++i)
121 std::istringstream istr(m->vars_[m->curv_knots[
id]][i]);
123 if(!(istr >> dummy_dbl))
124 vKnots.push_back(atof(m->vars_[m->vars_[m->curv_knots[
id]][i]][0].c_str()));
126 vKnots.push_back(atof(m->vars_[m->curv_knots[
id]][i].c_str()));
128 inner = vKnots.size();
131 nurbs->nk = nurbs->degree + nurbs->np + 1;
132 outer = nurbs->nk - inner;
134 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: incorrect number of knot points.",
id);
137 nurbs->kv =
new double[nurbs->nk];
139 for (
int i = 0; i < outer/2; i++)
143 for (
int i = outer/2; i < inner + outer/2; i++) {
144 nurbs->kv[i] = vKnots[i - (outer/2)];
148 for (
int i = outer/2 + inner; i < nurbs->nk; i++)
159 std::ifstream s(filename);
161 throw Hermes::Exceptions::MeshLoadFailureException(
"Mesh file not found.");
177 if(n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'vertices' must be a list.", filename);
178 if(n < 2)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: invalid number of vertices.", filename);
181 int size = HashTable::H2D_DEFAULT_HASH_SIZE;
182 while (size < 8*n) size *= 2;
186 for (i = 0; i < n; i++)
189 assert(node->
id == i);
190 node->
ref = TOP_LEVEL_REF;
191 node->
type = HERMES_TYPE_VERTEX;
193 node->p1 = node->
p2 = -1;
203 if(n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'elements' must be a list.", filename);
204 if(n < 1)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: no elements defined.", filename);
208 for (i = 0; i < n; i++)
212 if(m.
en4[i] == -1) nv = 4;
215 int* idx =
new int[nv-1];
218 mesh->elements.skip_slot();
225 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: element #%d: wrong number of vertex indices.", filename, i);
233 el_marker = m.
e_mtl[i];
241 el_marker = m.
e_mtl[i];
243 for (j = 0; j < nv-1; j++)
244 if(idx[j] < 0 || idx[j] >= mesh->ntopvert)
247 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: error creating element #%d: vertex #%d does not exist.", filename, i, idx[j]);
256 mesh->element_markers_conversion.insert_marker(mesh->element_markers_conversion.min_marker_unused, el_marker);
257 marker = mesh->element_markers_conversion.get_internal_marker(el_marker).marker;
260 Mesh::check_triangle(i, v0, v1, v2);
261 mesh->create_triangle(marker, v0, v1, v2, NULL);
265 Mesh::check_quad(i, v0, v1, v2, v3);
266 mesh->create_quad(marker, v0, v1, v2, v3, NULL);
281 for (i = 0; i < n; i++)
289 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: boundary data #%d: edge %d-%d does not exist", filename, i, v1, v2);
296 mesh->boundary_markers_conversion.insert_marker(mesh->boundary_markers_conversion.min_marker_unused, bnd_marker);
297 marker = mesh->boundary_markers_conversion.get_internal_marker(bnd_marker).marker;
305 mesh->
nodes[v1].bnd = 1;
306 mesh->
nodes[v2].bnd = 1;
316 if(n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'curves' must be a list.", filename);
319 for (i = 0; i < n; i++)
325 Nurbs* nurbs = load_nurbs(mesh, &m, i, &en, p1, p2);
328 for (k = 0; k < 2; k++)
331 if(e == NULL)
continue;
342 for (
unsigned j = 0; j < e->get_nvert(); j++)
343 if(e->
en[j] == en) { idx = j;
break; }
346 if(e->
vn[idx]->
id == p1)
348 e->
cm->nurbs[idx] = nurbs;
353 Nurbs* nurbs_rev = mesh->reverse_nurbs(nurbs);
354 e->
cm->nurbs[idx] = nurbs_rev;
358 if(!nurbs->
ref)
delete nurbs;
364 for_all_elements(e, mesh)
366 e->
cm->update_refmap_coeffs(e);
372 if(n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'refinements' must be a list.", filename);
375 for (i = 0; i < n; i++)
383 mesh->ninitial = mesh->elements.get_num_items();
385 mesh->seq = g_mesh_seq++;
386 mesh->initial_single_check();
390 void MeshReaderH2D::save_refinements(
Mesh *mesh, FILE* f,
Element* e,
int id,
bool& first)
393 fprintf(f, first ?
"refinements =\n{\n" :
",\n"); first =
false;
396 fprintf(f,
" { %d, 0 }",
id);
397 int sid = mesh->seq; mesh->seq += 4;
398 for (
int i = 0; i < 4; i++)
399 save_refinements(mesh, f, e->
sons[i], sid+i, first);
403 fprintf(f,
" { %d, 1 }",
id);
404 int sid = mesh->seq; mesh->seq += 2;
405 save_refinements(mesh, f, e->
sons[0], sid, first);
406 save_refinements(mesh, f, e->
sons[1], sid+1, first);
410 fprintf(f,
" { %d, 2 }",
id);
411 int sid = mesh->seq; mesh->seq += 2;
412 save_refinements(mesh, f, e->
sons[2], sid, first);
413 save_refinements(mesh, f, e->
sons[3], sid+1, first);
417 void MeshReaderH2D::save_nurbs(Mesh *mesh, FILE* f,
int p1,
int p2, Nurbs* nurbs)
421 fprintf(f,
" [ %d, %d, %.16g ]", p1, p2, nurbs->angle);
425 int inner = nurbs->np - 2;
426 int outer = nurbs->nk - inner;
427 fprintf(f,
" ú %d, %d, %d, ú ", p1, p2, nurbs->degree);
428 for (
int i = 1; i < nurbs->np-1; i++)
429 fprintf(f,
"ú %.16g, %.16g, %.16g ]%s ",
430 nurbs->pt[i][0], nurbs->pt[i][1], nurbs->pt[i][2],
431 i < nurbs->np-2 ?
"," :
"");
434 int max = nurbs->nk - (nurbs->degree+1);
435 for (
int i = nurbs->degree+1; i < max; i++)
436 fprintf(f,
"%.16g%s", nurbs->kv[i], i < max-1 ?
"," :
"");
441 bool MeshReaderH2D::save(
const char* filename, Mesh *mesh)
447 FILE* f = fopen(filename,
"w");
448 if(f == NULL)
throw Hermes::Exceptions::MeshLoadFailureException(
"Could not create mesh file.");
452 fprintf(f,
"vertices =\n[\n");
453 for (i = 0; i < mesh->ntopvert; i++)
454 fprintf(f,
" [ %.16g, %.16g ]%s\n", mesh->nodes[i].x, mesh->nodes[i].y, (i < mesh->ntopvert-1 ?
"," :
""));
457 fprintf(f,
"]\n\nelements =\n[");
459 for (i = 0; i < mesh->get_num_base_elements(); i++)
461 const char* nl = first ?
"\n" :
",\n"; first =
false;
462 e = mesh->get_element_fast(i);
464 fprintf(f,
"%s [ ]", nl);
465 else if(e->is_triangle())
466 fprintf(f,
"%s [ %d, %d, %d, \"%s\" ]", nl, e->vn[0]->id, e->vn[1]->id, e->vn[2]->id, mesh->get_element_markers_conversion().get_user_marker(e->marker).marker.c_str());
468 fprintf(f,
"%s [ %d, %d, %d, %d, \"%s\" ]", nl, e->vn[0]->id, e->vn[1]->id, e->vn[2]->id, e->vn[3]->id, mesh->get_element_markers_conversion().get_user_marker(e->marker).marker.c_str());
472 fprintf(f,
"\n]\n\nboundaries =\n[");
474 for_all_base_elements(e, mesh)
475 for (
unsigned i = 0; i < e->get_nvert(); i++)
476 if((mrk = mesh->get_base_edge_node(e, i)->marker)) {
477 const char* nl = first ?
"\n" :
",\n"; first =
false;
478 fprintf(f,
"%s [ %d, %d, \"%s\" ]", nl, e->vn[i]->id, e->vn[e->next_vert(i)]->id, mesh->boundary_markers_conversion.get_user_marker(mrk).marker.c_str());
480 fprintf(f,
"\n]\n\n");
484 for_all_base_elements(e, mesh)
486 for (
unsigned i = 0; i < e->get_nvert(); i++)
487 if(e->cm->nurbs[i] != NULL && !is_twin_nurbs(e, i)) {
488 fprintf(f, first ?
"curves =\n[\n" :
",\n"); first =
false;
489 save_nurbs(mesh, f, e->vn[i]->id, e->vn[e->next_vert(i)]->id, e->cm->nurbs[i]);
491 if(!first) fprintf(f,
"\n]\n\n");
494 unsigned temp = mesh->seq;
495 mesh->seq = mesh->nbase;
497 for_all_base_elements(e, mesh)
498 save_refinements(mesh, f, e, e->
id, first);
499 if(!first) fprintf(f, "\n]\n\n");