17 #include "mesh_reader_h2d.h"
24 extern unsigned g_mesh_seq;
26 MeshReaderH2D::MeshReaderH2D()
30 MeshReaderH2D::~MeshReaderH2D()
34 Arc* MeshReaderH2D::load_arc(MeshSharedPtr mesh, MeshData *m,
int id, Node** en,
int &p1,
int &p2, Arc* arc)
37 p1 = m->curv_first[
id];
38 p2 = m->curv_second[
id];
40 *en = mesh->peek_edge_node(p1, p2);
42 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: edge %d-%d does not exist.",
id, p1, p2);
45 std::vector<double> vCP;
48 arc->pt[0][0] = mesh->nodes[p1].x;
49 arc->pt[0][1] = mesh->nodes[p1].y;
51 arc->pt[2][0] = mesh->nodes[p2].x;
52 arc->pt[2][1] = mesh->nodes[p2].y;
56 arc->angle = m->curv_third[
id];
57 double a = (180.0 - arc->angle) / 180.0 * M_PI;
60 double x = 1.0 / tan(a * 0.5);
61 arc->pt[1][0] = 0.5*((arc->pt[2][0] + arc->pt[0][0]) + (arc->pt[2][1] - arc->pt[0][1]) * x);
62 arc->pt[1][1] = 0.5*((arc->pt[2][1] + arc->pt[0][1]) - (arc->pt[2][0] - arc->pt[0][0]) * x);
63 arc->pt[1][2] = cos((M_PI - a) * 0.5);
66 std::vector<double> vKnots;
71 Nurbs* MeshReaderH2D::load_nurbs(MeshSharedPtr mesh, MeshData *m,
int id, Node** en,
int &p1,
int &p2, Nurbs* nurbs)
74 p1 = m->curv_first[
id];
75 p2 = m->curv_second[
id];
77 *en = mesh->peek_edge_node(p1, p2);
79 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: edge %d-%d does not exist.",
id, p1, p2);
81 nurbs->degree = m->curv_third[
id];
84 std::vector<double> vCP;
87 for (
unsigned int i = 0; i < m->vars_[m->curv_inner_pts[
id]].size(); ++i)
89 std::istringstream istr(m->vars_[m->curv_inner_pts[
id]][i]);
92 if (!(istr >> dummy_dbl))
93 vCP.push_back(atof(m->vars_[m->vars_[m->curv_inner_pts[
id]][i]][0].c_str()));
95 vCP.push_back(atof(m->vars_[m->curv_inner_pts[
id]][i].c_str()));
97 inner = vCP.size() / 3;
99 nurbs->np = inner + 2;
102 nurbs->pt =
new double3[nurbs->np];
103 nurbs->pt[0][0] = mesh->nodes[p1].x;
104 nurbs->pt[0][1] = mesh->nodes[p1].y;
105 nurbs->pt[0][2] = 1.0;
106 nurbs->pt[inner + 1][0] = mesh->nodes[p2].x;
107 nurbs->pt[inner + 1][1] = mesh->nodes[p2].y;
108 nurbs->pt[inner + 1][2] = 1.0;
111 for (
int i = 0; i < inner; i++)
113 for (
int j = 0; j < 3; ++j)
114 nurbs->pt[i + 1][j] = vCP[3 * i + j];
118 std::vector<double> vKnots;
121 for (
unsigned int i = 0; i < m->vars_[m->curv_knots[
id]].size(); ++i)
123 std::istringstream istr(m->vars_[m->curv_knots[
id]][i]);
126 if (!(istr >> dummy_dbl))
127 vKnots.push_back(atof(m->vars_[m->vars_[m->curv_knots[
id]][i]][0].c_str()));
129 vKnots.push_back(atof(m->vars_[m->curv_knots[
id]][i].c_str()));
131 inner = vKnots.size();
133 nurbs->nk = nurbs->degree + nurbs->np + 1;
134 outer = nurbs->nk - inner;
135 if ((outer & 1) == 1)
136 throw Hermes::Exceptions::MeshLoadFailureException(
"Curve #%d: incorrect number of knot points.",
id);
139 nurbs->kv =
new double[nurbs->nk];
141 for (
int i = 0; i < outer / 2; i++)
145 for (
int i = outer / 2; i < inner + outer / 2; i++) {
146 nurbs->kv[i] = vKnots[i - (outer / 2)];
150 for (
int i = outer / 2 + inner; i < nurbs->nk; i++)
156 Curve* MeshReaderH2D::load_curve(MeshSharedPtr mesh, MeshData *m,
int id, Node** en,
int &p1,
int &p2)
158 if (m->curv_nurbs[
id])
159 return load_nurbs(mesh, m,
id, en, p1, p2,
new Nurbs);
161 return load_arc(mesh, m,
id, en, p1, p2,
new Arc);
167 std::ifstream s(filename);
169 throw Hermes::Exceptions::MeshLoadFailureException(
"Mesh file not found.");
185 if (n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'vertices' must be a list.", filename);
186 if (n < 2)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: invalid number of vertices.", filename);
190 while (size < 8 * n) size *= 2;
194 for (i = 0; i < n; i++)
196 Node* node = mesh->nodes.add();
197 assert(node->
id == i);
198 node->
ref = TOP_LEVEL_REF;
199 node->
type = HERMES_TYPE_VERTEX;
201 node->
p1 = node->p2 = -1;
211 if (n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'elements' must be a list.", filename);
212 if (n < 1)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: no elements defined.", filename);
216 for (i = 0; i < n; i++)
220 if (m.
en4[i] == -1) nv = 4;
223 int* idx =
new int[nv - 1];
226 mesh->elements.skip_slot()->cm =
nullptr;
230 if (nv < 4 || nv > 5)
233 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: element #%d: wrong number of vertex indices.", filename, i);
241 el_marker = m.
e_mtl[i];
249 el_marker = m.
e_mtl[i];
251 for (j = 0; j < nv - 1; j++)
252 if (idx[j] < 0 || idx[j] >= mesh->ntopvert)
255 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: error creating element #%d: vertex #%d does not exist.", filename, i, idx[j]);
258 Node *v0 = &mesh->nodes[idx[0]], *v1 = &mesh->nodes[idx[1]], *v2 = &mesh->nodes[idx[2]];
264 mesh->element_markers_conversion.insert_marker(el_marker);
265 marker = mesh->element_markers_conversion.get_internal_marker(el_marker).
marker;
268 Mesh::check_triangle(i, v0, v1, v2);
269 mesh->create_triangle(marker, v0, v1, v2,
nullptr);
272 Node *v3 = &mesh->nodes[idx[3]];
273 Mesh::check_quad(i, v0, v1, v2, v3);
274 mesh->create_quad(marker, v0, v1, v2, v3,
nullptr);
289 for (i = 0; i < n; i++)
295 en = mesh->peek_edge_node(v1, v2);
297 throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: boundary data #%d: edge %d-%d does not exist", filename, i, v1, v2);
304 mesh->boundary_markers_conversion.insert_marker(bnd_marker);
305 marker = mesh->boundary_markers_conversion.get_internal_marker(bnd_marker).marker;
312 for_all_edge_nodes(node, mesh)
316 mesh->nodes[node->
p1].bnd = 1;
317 mesh->nodes[node->p2].bnd = 1;
326 if (n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'curves' must be a list.", filename);
329 for (i = 0; i < n; i++)
335 Curve* curve = load_curve(mesh, &m, i, &en, p1, p2);
344 for_all_used_elements(e, mesh)
346 if (e->
cm !=
nullptr)
348 this->
ref_map.set_element_iro_cache(e);
355 if (n < 0)
throw Hermes::Exceptions::MeshLoadFailureException(
"File %s: 'refinements' must be a list.", filename);
358 for (i = 0; i < n; i++)
363 mesh->refine_element_id(
id, ref);
366 mesh->ninitial = mesh->elements.get_num_items();
368 mesh->seq = g_mesh_seq++;
369 if (HermesCommonApi.get_integral_param_value(checkMeshesOnLoad))
370 mesh->initial_single_check();
373 void MeshReaderH2D::save_refinements(MeshSharedPtr mesh, FILE* f,
Element* e,
int id,
bool& first)
376 fprintf(f, first ?
"refinements =\n{\n" :
",\n"); first =
false;
379 fprintf(f,
" { %d, 0 }",
id);
380 int sid = mesh->seq; mesh->seq += 4;
381 for (
int i = 0; i < 4; i++)
382 save_refinements(mesh, f, e->
sons[i], sid + i, first);
384 else if (e->hsplit())
386 fprintf(f,
" { %d, 1 }",
id);
387 int sid = mesh->seq; mesh->seq += 2;
388 save_refinements(mesh, f, e->
sons[0], sid, first);
389 save_refinements(mesh, f, e->
sons[1], sid + 1, first);
393 fprintf(f,
" { %d, 2 }",
id);
394 int sid = mesh->seq; mesh->seq += 2;
395 save_refinements(mesh, f, e->
sons[2], sid, first);
396 save_refinements(mesh, f, e->
sons[3], sid + 1, first);
400 void MeshReaderH2D::save_curve(MeshSharedPtr mesh, FILE* f,
int p1,
int p2, Curve* curve)
402 if (curve->type == ArcType)
404 fprintf(f,
" [ %d, %d, %.16g ]", p1, p2, ((Arc*)curve)->angle);
408 int inner = ((Nurbs*)curve)->np - 2;
409 int outer = ((Nurbs*)curve)->nk - inner;
410 fprintf(f,
" ú %d, %d, %d, ú ", p1, p2, ((Nurbs*)curve)->degree);
411 for (
int i = 1; i < ((Nurbs*)curve)->np - 1; i++)
412 fprintf(f,
"ú %.16g, %.16g, %.16g ]%s ",
413 ((Nurbs*)curve)->pt[i][0], ((Nurbs*)curve)->pt[i][1], ((Nurbs*)curve)->pt[i][2],
414 i < ((Nurbs*)curve)->np - 2 ?
"," :
"");
417 int max = ((Nurbs*)curve)->nk - (((Nurbs*)curve)->degree + 1);
418 for (
int i = ((Nurbs*)curve)->degree + 1; i < max; i++)
419 fprintf(f,
"%.16g%s", ((Nurbs*)curve)->kv[i], i < max - 1 ?
"," :
"");
424 void MeshReaderH2D::save(
const char* filename, MeshSharedPtr mesh)
430 FILE* f = fopen(filename,
"w");
431 if (f ==
nullptr)
throw Hermes::Exceptions::MeshLoadFailureException(
"Could not create mesh file.");
435 fprintf(f,
"vertices =\n[\n");
436 for (i = 0; i < mesh->ntopvert; i++)
437 fprintf(f,
" [ %.16g, %.16g ]%s\n", mesh->nodes[i].x, mesh->nodes[i].y, (i < mesh->ntopvert - 1 ?
"," :
""));
440 fprintf(f,
"]\n\nelements =\n[");
442 for (i = 0; i < mesh->get_num_base_elements(); i++)
444 const char* nl = first ?
"\n" :
",\n"; first =
false;
445 e = mesh->get_element_fast(i);
447 fprintf(f,
"%s [ ]", nl);
448 else if (e->is_triangle())
449 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());
451 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());
455 fprintf(f,
"\n]\n\nboundaries =\n[");
457 for_all_base_elements(e, mesh)
459 for (
unsigned char i = 0; i < e->get_nvert(); i++)
462 const char* nl = first ?
"\n" :
",\n"; first =
false;
463 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());
466 fprintf(f,
"\n]\n\n");
470 for_all_base_elements(e, mesh)
474 for (
unsigned char i = 0; i < e->get_nvert(); i++)
475 if (e->cm->curves[i] !=
nullptr)
477 fprintf(f, first ?
"curves =\n[\n" :
",\n"); first =
false;
478 save_curve(mesh, f, e->vn[i]->id, e->vn[e->next_vert(i)]->id, e->cm->curves[i]);
480 if (!first) fprintf(f,
"\n]\n\n");
484 unsigned temp = mesh->seq;
485 mesh->seq = mesh->nbase;
487 for_all_base_elements(e, mesh)
488 save_refinements(mesh, f, e, e->
id, first);
489 if (!first) fprintf(f, "\n]\n\n");
::xsd::cxx::tree::id< char, ncname > id
C++ type corresponding to the ID XML Schema built-in type.
std::vector< std::string > e_mtl
Element markers – single word strings.
double x
vertex node coordinates
void parse_mesh(void)
This function parses a given input mesh file line by line and extracts the necessary information into...
unsigned type
0 = vertex node; 1 = edge node
std::vector< int > ref_elt
List of elements to be refined.
Node * next_hash
next node in hash synonym list
Stores one element of a mesh.
int n_ref
Number of elements with specified refinements.
RefMap ref_map
Reference mapping for detecting the inverse reference mapping order.
int n_vert
Number of vertices.
CurvMap * cm
curved mapping, nullptr if not curvilinear
int n_el
Number of elements.
std::vector< std::string > bdy_type
Boundary name.
Class to stored 2d mesh parameters. The MeshData class organizes all the necessary data structures re...
Stores one node of a mesh.
std::vector< int > en4
Nodes with local node number 4. Only for quadrilateral elements. For triangular elements it is set to...
int n_curv
Number of curved edges (including NURBS curves)
std::vector< int > en3
Nodes with local node number 3.
std::vector< int > en2
Nodes with local node number 2.
std::vector< int > ref_type
List of element refinement type.
int n_bdy
Number of boundary edges.
std::vector< int > bdy_first
First node of a boundary edge.
unsigned bnd
1 = boundary node; 0 = inner node
std::vector< int > en1
Nodes with local node number 1.
std::vector< double > y_vertex
y-coordinate of the vertices
std::vector< double > x_vertex
x-coordinate of the vertices
::xsd::cxx::tree::string< char, simple_type > string
C++ type corresponding to the string XML Schema built-in type.
std::vector< int > bdy_second
Second node of a boundary edge.
unsigned ref
the number of elements using the node
void update_refmap_coeffs(Element *e)
virtual void load(const char *filename, MeshSharedPtr mesh)
Element * sons[H2D_MAX_ELEMENT_SONS]
son elements (up to four)
bool active
0 = active, no sons; 1 = inactive (refined), has sons
static Node * get_base_edge_node(Element *base, int edge)
For internal use.
static const int H2D_DEFAULT_HASH_SIZE
32K entries
static void assign_curve(Node *en, Curve *curve, int p1, int p2)
For internal use.