21 #include "mesh_reader_h2d.h"
28 static const int H2D_DG_INNER_EDGE_INT = -1234567;
29 static const std::string H2D_DG_INNER_EDGE =
"-1234567";
33 assert(
type == HERMES_TYPE_VERTEX);
37 void Node::ref_element(
Element* e)
39 if(
type == HERMES_TYPE_EDGE)
48 throw Hermes::Exceptions::Exception(
false,
"No free slot 'elem'");
54 void Node::unref_element(HashTable* ht, Element* e)
56 if(
type == HERMES_TYPE_VERTEX)
58 if(!--
ref) ht->remove_vertex_node(
id);
64 else if(
elem[1] == e)
elem[1] = NULL;
66 if(!--
ref) ht->remove_edge_node(
id);
72 for (
unsigned int i = 0; i < nvert; i++)
75 en[i]->ref_element(
this);
81 int Element::get_edge_orientation(
int ie)
const
83 return (this->
vn[ie]->id < this->
vn[this->
next_vert(ie)]->
id) ? 0 : 1;
88 for (
unsigned int i = 0; i < nvert; i++)
90 vn[i]->unref_element(ht);
91 en[i]->unref_element(ht,
this);
97 Element::Element() : visited(false), area(0.0), diameter(0.0)
101 bool Element::is_triangle()
const
106 bool Element::is_quad()
const
111 bool Element::is_curved()
const
116 int Element::get_nvert()
const
121 ElementMode2D Element::get_mode()
const
123 return (nvert == 3) ? HERMES_MODE_TRIANGLE : HERMES_MODE_QUAD;
128 return (i < (
int)nvert-1) ? i + 1 : 0;
131 int Element::prev_vert(
int i)
const
133 return (i > 0) ? i-1 : nvert-1;
136 bool Element::hsplit()
const
140 return sons[0] != NULL;
143 bool Element::vsplit()
const
147 return sons[2] != NULL;
150 bool Element::bsplit()
const
154 return sons[0] != NULL &&
sons[2] != NULL;
172 double ax, ay, bx, by;
173 ax =
vn[1]->x -
vn[0]->x;
175 bx =
vn[2]->x -
vn[0]->x;
178 this->
area = 0.5*(ax*by - ay*bx);
182 bx =
vn[3]->x -
vn[0]->x;
185 this->
area =
area + 0.5*(ax*by - ay*bx);
195 x = this->
vn[0]->x + this->
vn[1]->x + this->
vn[2]->x;
205 y = this->
vn[0]->
y + this->
vn[1]->
y + this->
vn[2]->
y;
223 for (
int i = 0; i < 3; i++)
226 l = sqr(
vn[i]->x -
vn[j]->x) + sqr(
vn[i]->y -
vn[j]->y);
233 max = sqr(
vn[0]->x -
vn[2]->x) + sqr(
vn[0]->y -
vn[2]->y);
234 l = sqr(
vn[1]->x -
vn[3]->x) + sqr(
vn[1]->y -
vn[3]->y);
244 unsigned g_mesh_seq = 0;
248 nbase = nactive = ntopvert = ninitial = 0;
261 if(this->elements.get_size() < 1)
263 if(this->
nodes.get_size() < 1)
277 ref_mesh->
copy(this->coarse_mesh);
282 void Mesh::initial_single_check()
286 Quad2D* quad = &g_quad_2d_std;
287 for_all_active_elements(e,
this)
291 int i, o, mo = quad->get_max_order(e->get_mode());
293 int k = e->is_triangle() ? 2 : 3;
295 double const_m[2][2] =
297 { e->
vn[1]->x - e->
vn[0]->x, e->
vn[k]->x - e->
vn[0]->x },
298 { e->
vn[1]->
y - e->
vn[0]->
y, e->
vn[k]->
y - e->
vn[0]->
y }
301 double const_jacobian = 0.25 * (const_m[0][0] * const_m[1][1] - const_m[0][1] * const_m[1][0]);
302 double2x2 const_inv_ref_map;
303 if(const_jacobian <= 0.0)
304 throw Hermes::Exceptions::MeshLoadFailureException(
"Element #%d is concave or badly oriented in initial_single_check().", e->
id);
307 double3* pt = quad->get_points(mo, e->get_mode());
310 for (i = 0; i < quad->get_num_points(mo, e->get_mode()); i++)
312 throw Hermes::Exceptions::MeshLoadFailureException(
"Element #%d is concave or badly oriented in initial_single_check().", e->
id);
316 void Mesh::initial_multimesh_check(Hermes::vector<Mesh*> meshes)
327 while (size < 2*nv) size *= 2;
331 for (
int i = 0; i < nv; i++)
334 assert(node->
id == i);
335 node->
ref = TOP_LEVEL_REF;
336 node->
type = HERMES_TYPE_VERTEX;
338 node->p1 = node->
p2 = -1;
340 node->x = verts[i][0];
341 node->
y = verts[i][1];
347 for (
int i = 0; i < nt; i++)
349 this->element_markers_conversion.insert_marker(this->element_markers_conversion.min_marker_unused, tri_markers[i]);
351 e = create_triangle(this->element_markers_conversion.get_internal_marker(tri_markers[i]).marker, &
nodes[tris[i][0]], &
nodes[tris[i][1]],
352 &
nodes[tris[i][2]], NULL);
356 for (
int i = 0; i < nq; i++)
358 this->element_markers_conversion.insert_marker(this->element_markers_conversion.min_marker_unused, quad_markers[i]);
360 e = create_quad(this->element_markers_conversion.get_internal_marker(quad_markers[i]).marker, &
nodes[quads[i][0]], &
nodes[quads[i][1]],
361 &
nodes[quads[i][2]], &
nodes[quads[i][3]], NULL);
365 for (
int i = 0; i < nm; i++)
369 throw Hermes::Exceptions::Exception(
"Boundary data error (edge does not exist)");
371 this->boundary_markers_conversion.insert_marker(this->boundary_markers_conversion.min_marker_unused, boundary_markers[i]);
373 en->
marker = this->boundary_markers_conversion.get_internal_marker(boundary_markers[i]).marker;
375 nodes[mark[i][0]].bnd = 1;
376 nodes[mark[i][1]].bnd = 1;
380 nbase = nactive = ninitial = nt + nq;
386 if(
this == NULL)
throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_elements().");
390 return elements.get_num_items();
396 if(
this == NULL)
throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_base_elements().");
409 throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_base_elements().");
416 for_all_base_elements(e,
this)
426 throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_active_elements().");
437 throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_max_element_id().");
441 return elements.get_size();
447 throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_vertex_nodes().");
465 throw Hermes::Exceptions::Exception(
"this == NULL in Mesh::get_num_vertex_nodes().");
482 if(id < 0 || id >= elements.get_size())
483 throw Hermes::Exceptions::Exception(
"Invalid element ID %d, current range:[0; %d]",
id, elements.get_size());
484 return &(elements[
id]);
499 return &(elements[
id]);
502 int Mesh::get_edge_sons(
Element* e,
int edge,
int& son1,
int& son2)
const
506 if(!e->is_triangle())
508 if(e->
sons[2] == NULL)
510 if(edge == 0 || edge == 2) { son1 = edge >> 1;
return 1; }
511 else if(edge == 1) { son1 = 0; son2 = 1;
return 2; }
512 else { son1 = 1; son2 = 0;
return 2; }
514 else if(e->
sons[0] == NULL)
516 if(edge == 1 || edge == 3) { son1 = (edge == 1) ? 3 : 2;
return 1; }
517 else if(edge == 0) { son1 = 2; son2 = 3;
return 2; }
518 else { son1 = 3; son2 = 2;
return 2; }
528 Element* Mesh::create_triangle(
int marker, Node* v0, Node* v1, Node* v2, CurvMap* cm,
int id)
531 Element* e = elements.add();
546 if(v0 == v1 || v1 == v2 || v2 == v0)
547 throw Hermes::Exceptions::MeshLoadFailureException(
"Some of the vertices of element #%d are identical which is impossible.", e->id);
562 Element* Mesh::create_quad(
int marker, Node* v0, Node* v1, Node* v2, Node* v3,
566 Element* e = elements.add();
581 if(v0 == v1 || v1 == v2 || v2 == v3 || v3 == v0 || v2 == v0 || v3 == v1)
582 throw Hermes::Exceptions::MeshLoadFailureException(
"Some of the vertices of element #%d are identical which is impossible.", e->id);
599 CurvMap* create_son_curv_map(Element* e,
int son)
603 if(e->cm->part & 0xe000000000000000ULL)
608 if(e->iro_cache == 0)
611 CurvMap* cm =
new CurvMap;
612 if(e->cm->toplevel ==
false)
614 cm->parent = e->
cm->parent;
615 cm->part = (e->cm->part << 3) + son + 1;
620 cm->part = (son + 1);
622 cm->toplevel =
false;
628 void Mesh::refine_triangle_to_triangles(Element* e, Element** sons_out)
631 int bnd[3] = { e->
en[0]->
bnd, e->en[1]->bnd, e->en[2]->bnd };
632 int mrk[3] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker };
641 memset(cm, 0,
sizeof(cm));
646 double2 pt[3] = { { 0.0, -1.0 }, { 0.0, 0.0 }, { -1.0, 0.0 } };
647 e->cm->get_mid_edge_points(e, pt, 3);
648 x0->x = pt[0][0]; x0->y = pt[0][1];
649 x1->x = pt[1][0]; x1->y = pt[1][1];
650 x2->x = pt[2][0]; x2->y = pt[2][1];
653 for (
int i = 0; i < 4; i++)
654 cm[i] = create_son_curv_map(e, i);
659 sons[0] = create_triangle(e->marker, e->vn[0], x0, x2, cm[0]);
660 sons[1] = create_triangle(e->marker, x0, e->vn[1], x1, cm[1]);
661 sons[2] = create_triangle(e->marker, x2, x1, e->vn[2], cm[2]);
662 sons[3] = create_triangle(e->marker, x1, x2, x0, cm[3]);
665 for (
int i = 0; i < 4; i++)
666 if(sons[i]->is_curved())
667 sons[i]->cm->update_refmap_coeffs(sons[i]);
672 e->unref_all_nodes(
this);
676 sons[0]->en[0]->bnd = bnd[0]; sons[0]->en[0]->marker = mrk[0];
677 sons[0]->en[2]->bnd = bnd[2]; sons[0]->en[2]->marker = mrk[2];
678 sons[1]->en[0]->bnd = bnd[0]; sons[1]->en[0]->marker = mrk[0];
679 sons[1]->en[1]->bnd = bnd[1]; sons[1]->en[1]->marker = mrk[1];
680 sons[2]->en[1]->bnd = bnd[1]; sons[2]->en[1]->marker = mrk[1];
681 sons[2]->en[2]->bnd = bnd[2]; sons[2]->en[2]->marker = mrk[2];
682 sons[3]->vn[0]->bnd = bnd[1];
683 sons[3]->vn[1]->bnd = bnd[2];
684 sons[3]->vn[2]->bnd = bnd[0];
687 for(
int i = 0; i < 4; i++)
689 if(sons[i] != NULL) sons[i]->parent = e;
693 memcpy(e->sons, sons, 4 *
sizeof(Element*));
698 for(
int i = 0; i < 3; i++) sons_out[i] = sons[i];
705 Node* newnode =
new Node();
706 newnode->type = HERMES_TYPE_VERTEX;
711 newnode->x = (v1->x + v2->x) * 0.5;
712 newnode->y = (v1->y + v2->y) * 0.5;
720 Node* newnode =
new Node();
721 newnode->type = HERMES_TYPE_EDGE;
727 newnode->elem[0] = newnode->elem[1] = NULL;
748 memset(cm, 0,
sizeof(cm));
754 Node* x0, *x1, *x2, *x3, *mid;
764 double2 pt[5] = { { 0.0, -1.0 }, { 1.0, 0.0 }, { 0.0, 1.0 }, { -1.0, 0.0 }, { 0.0, 0.0 } };
765 e->
cm->get_mid_edge_points(e, pt, 5);
766 x0->x = pt[0][0]; x0->
y = pt[0][1];
767 x1->x = pt[1][0]; x1->
y = pt[1][1];
768 x2->x = pt[2][0]; x2->
y = pt[2][1];
769 x3->x = pt[3][0]; x3->
y = pt[3][1];
770 mid->x = pt[4][0]; mid->
y = pt[4][1];
774 cm[i] = create_son_curv_map(e, i);
778 sons[0] = create_quad(e->
marker, e->
vn[0], x0, mid, x3, cm[0]);
779 sons[1] = create_quad(e->
marker, x0, e->
vn[1], x1, mid, cm[1]);
780 sons[2] = create_quad(e->
marker, mid, x1, e->
vn[2], x2, cm[2]);
781 sons[3] = create_quad(e->
marker, x3, mid, x2, e->
vn[3], cm[3]);
789 j = (i > 0) ? i-1 : 3;
790 sons[i]->
en[j]->
bnd = bnd[j]; sons[i]->
en[j]->
marker = mrk[j];
791 sons[i]->
en[i]->
bnd = bnd[i]; sons[i]->
en[i]->
marker = mrk[i];
792 sons[i]->
vn[j]->
bnd = bnd[j];
797 else if(refinement == 1)
806 double2 pt[2] = { { 1.0, 0.0 }, { -1.0, 0.0 } };
807 e->
cm->get_mid_edge_points(e, pt, 2);
808 x1->x = pt[0][0]; x1->
y = pt[0][1];
809 x3->x = pt[1][0]; x3->
y = pt[1][1];
812 for (i = 0; i < 2; i++)
813 cm[i] = create_son_curv_map(e, i + 4);
816 sons[0] = create_quad(e->
marker, e->
vn[0], e->
vn[1], x1, x3, cm[0]);
817 sons[1] = create_quad(e->
marker, x3, x1, e->
vn[2], e->
vn[3], cm[1]);
818 sons[2] = sons[3] = NULL;
822 sons[0]->
en[0]->
bnd = bnd[0]; sons[0]->
en[0]->
marker = mrk[0];
823 sons[0]->
en[1]->
bnd = bnd[1]; sons[0]->
en[1]->
marker = mrk[1];
824 sons[0]->
en[3]->
bnd = bnd[3]; sons[0]->
en[3]->
marker = mrk[3];
825 sons[1]->
en[1]->
bnd = bnd[1]; sons[1]->
en[1]->
marker = mrk[1];
826 sons[1]->
en[2]->
bnd = bnd[2]; sons[1]->
en[2]->
marker = mrk[2];
827 sons[1]->
en[3]->
bnd = bnd[3]; sons[1]->
en[3]->
marker = mrk[3];
828 sons[0]->
vn[2]->
bnd = bnd[1];
829 sons[0]->
vn[3]->
bnd = bnd[3];
833 else if(refinement == 2)
842 double2 pt[2] = { { 0.0, -1.0 }, { 0.0, 1.0 } };
843 e->
cm->get_mid_edge_points(e, pt, 2);
844 x0->x = pt[0][0]; x0->
y = pt[0][1];
845 x2->x = pt[1][0]; x2->
y = pt[1][1];
848 for (i = 0; i < 2; i++)
849 cm[i] = create_son_curv_map(e, i + 6);
852 sons[0] = sons[1] = NULL;
853 sons[2] = create_quad(e->
marker, e->
vn[0], x0, x2, e->
vn[3], cm[0]);
854 sons[3] = create_quad(e->
marker, x0, e->
vn[1], e->
vn[2], x2, cm[1]);
858 sons[2]->
en[0]->
bnd = bnd[0]; sons[2]->
en[0]->
marker = mrk[0];
859 sons[2]->
en[2]->
bnd = bnd[2]; sons[2]->
en[2]->
marker = mrk[2];
860 sons[2]->
en[3]->
bnd = bnd[3]; sons[2]->
en[3]->
marker = mrk[3];
861 sons[3]->
en[0]->
bnd = bnd[0]; sons[3]->
en[0]->
marker = mrk[0];
862 sons[3]->
en[1]->
bnd = bnd[1]; sons[3]->
en[1]->
marker = mrk[1];
863 sons[3]->
en[2]->
bnd = bnd[2]; sons[3]->
en[2]->
marker = mrk[2];
864 sons[2]->
vn[1]->
bnd = bnd[0];
865 sons[2]->
vn[2]->
bnd = bnd[2];
870 for (i = 0; i < 4; i++)
871 if(sons[i] != NULL && sons[i]->cm != NULL)
872 sons[i]->
cm->update_refmap_coeffs(sons[i]);
876 for (i = 0; i < 4; i++)
881 for(
int i = 0; i < 4; i++)
882 if(sons[i] != NULL) sons[i]->
parent = e;
885 memcpy(e->
sons, sons,
sizeof(sons));
890 for(
int i = 0; i < 4; i++) sons_out[i] = sons[i];
894 void Mesh::unrefine_element_internal(
Element* e)
896 this->
refinements.push_back(std::pair<unsigned int, int>(e->
id, -1));
903 for (
unsigned i = 0; i < e->get_nvert(); i++)
905 get_edge_sons(e, i, s1, s2);
914 Element* son = e->
sons[i];
918 if(son->cm != NULL)
delete son->cm;
919 elements.remove(son->id);
925 for (i = 0; i < e->get_nvert(); i++)
933 for (i = 0; i < e->get_nvert(); i++)
936 e->
en[i]->
bnd = bnd[i];
940 void Mesh::refine_element(Element* e,
int refinement)
942 this->
refinements.push_back(std::pair<unsigned int, int>(e->id, refinement));
948 refine_triangle_to_quads(
this, e);
952 this->refine_triangle_to_triangles(e);
957 this->seq = g_mesh_seq++;
965 if(!e->
used)
throw Hermes::Exceptions::Exception(
"Invalid element id number.");
966 if(!e->
active)
throw Hermes::Exceptions::Exception(
"Attempt to refine element #%d which has been refined already.", e->
id);
967 this->refine_element(e, refinement);
979 elements.set_append_only(
true);
981 for_all_active_elements(e,
this)
984 elements.set_append_only(
false);
990 static int rtb_marker;
991 static bool rtb_aniso;
992 static char* rtb_vert;
997 elements.set_append_only(
true);
998 for (
int r, i = 0; i < depth; i++)
1000 for_all_active_elements(e,
this)
1002 if((r = criterion(e)) >= 0)
1006 elements.set_append_only(
false);
1014 static int rtv_criterion(
Element* e)
1016 for (
unsigned int i = 0; i < e->get_nvert(); i++)
1017 if(e->
vn[i]->
id == rtv_id)
1033 for (i = 0; i < e->get_nvert(); i++)
1035 if(e->
en[i]->
marker == rtb_marker || rtb_vert[e->
vn[i]->
id])
1041 if(i >= e->get_nvert())
return -1;
1046 if(e->is_triangle() || !rtb_aniso)
return 0;
1049 if((e->
en[0]->
marker == rtb_marker && !rtb_vert[e->
vn[2]->
id] && !rtb_vert[e->
vn[3]->
id]) ||
1050 (e->
en[2]->
marker == rtb_marker && !rtb_vert[e->
vn[0]->
id] && !rtb_vert[e->
vn[1]->
id]) ||
1052 e->
en[1]->
marker != rtb_marker && e->
en[3]->
marker != rtb_marker))
return 1;
1055 if((e->
en[1]->
marker == rtb_marker && !rtb_vert[e->
vn[3]->
id] && !rtb_vert[e->
vn[0]->
id]) ||
1056 (e->
en[3]->
marker == rtb_marker && !rtb_vert[e->
vn[1]->
id] && !rtb_vert[e->
vn[2]->
id]) ||
1058 e->
en[0]->
marker != rtb_marker && e->
en[2]->
marker != rtb_marker))
return 2;
1066 bool refined =
true;
1069 for (
int i = 0; i < depth; i++)
1073 rtb_vert =
new char[size];
1074 memset(rtb_vert, 0,
sizeof(
char) * size);
1077 for_all_active_elements(e,
this)
1078 for (
unsigned int j = 0; j < e->get_nvert(); j++)
1080 bool marker_matched =
false;
1081 for(
unsigned int marker_i = 0; marker_i < markers.size(); marker_i++)
1082 if(e->
en[j]->
marker == this->boundary_markers_conversion.get_internal_marker(markers[marker_i]).marker)
1083 marker_matched =
true;
1098 throw Hermes::Exceptions::Exception(
"None of the markers in Mesh::refine_towards_boundary found in the Mesh.");
1103 if(marker == HERMES_ANY)
1104 for(std::map<int, std::string>::iterator it = this->boundary_markers_conversion.conversion_table.begin(); it != this->boundary_markers_conversion.conversion_table.end(); ++it)
1109 bool refined =
true;
1110 rtb_marker = this->boundary_markers_conversion.get_internal_marker(marker).marker;
1114 for (
int i = 0; i < depth; i++)
1118 rtb_vert =
new char[size];
1119 memset(rtb_vert, 0,
sizeof(
char) * size);
1122 for_all_active_elements(e,
this)
1123 for (
unsigned int j = 0; j < e->get_nvert(); j++)
1125 if(e->
en[j]->
marker == this->boundary_markers_conversion.get_internal_marker(marker).marker)
1139 throw Hermes::Exceptions::Exception(
"None of the markers in Mesh::refine_towards_boundary found in the Mesh.");
1145 Hermes::vector<std::string> markers;
1146 markers.push_back(marker);
1152 bool refined =
true;
1153 for (
int i = 0; i < depth; i++)
1157 for_all_active_elements(e,
this)
1159 for(
unsigned int marker_i = 0; marker_i < markers.size(); marker_i++)
1160 if(e->
marker == this->element_markers_conversion.get_internal_marker(markers[marker_i]).marker || markers[marker_i] == HERMES_ANY)
1162 this->refine_element(e, 0);
1171 throw Hermes::Exceptions::Exception(
"None of the markers in Mesh::refine_in_areas found in the Mesh.");
1177 if(!e->
used)
throw Hermes::Exceptions::Exception(
"Invalid element id number.");
1180 for (
int i = 0; i < 4; i++)
1181 if(e->
sons[i] != NULL)
1184 unrefine_element_internal(e);
1191 Hermes::vector<int> list;
1193 for_all_inactive_elements(e,
this)
1196 for (
unsigned int i = 0; i < 4; i++)
1197 if(e->
sons[i] != NULL &&
1198 (!e->
sons[i]->
active || (keep_initial_refinements && e->
sons[i]->
id < ninitial))
1200 { found =
false;
break; }
1202 if(found) list.push_back(e->
id);
1206 for (
unsigned int i = 0; i < list.size(); i++)
1216 rev->
pt =
new double3[nurbs->
np];
1217 for (
int i = 0; i < nurbs->
np; i++)
1219 rev->
pt[nurbs->
np-1 - i][0] = nurbs->
pt[i][0];
1220 rev->
pt[nurbs->
np-1 - i][1] = nurbs->
pt[i][1];
1221 rev->
pt[nurbs->
np-1 - i][2] = nurbs->
pt[i][2];
1224 rev->
kv =
new double[nurbs->
nk];
1225 for (
int i = 0; i < nurbs->
nk; i++)
1226 rev->
kv[i] = nurbs->
kv[i];
1227 for (
int i = nurbs->
degree + 1; i < nurbs->nk - nurbs->
degree - 1; i++)
1228 rev->
kv[nurbs->
nk-1 - i] = 1.0 - nurbs->
kv[i];
1237 return sqrt(sqr(a_1) + sqr(a_2));
1240 bool Mesh::same_line(
double p_1,
double p_2,
double q_1,
double q_2,
double r_1,
double r_2)
1242 double pq_1 = q_1 - p_1, pq_2 = q_2 - p_2, pr_1 = r_1 - p_1, pr_2 = r_2 - p_2;
1245 double sin_angle = (pq_1*pr_2 - pq_2*pr_1)/(length_pq*length_pr);
1246 if(fabs(sin_angle) < 1e-8)
return true;
1252 if(a_1*b_2 - a_2*b_1 > 0)
return true;
1256 void Mesh::check_triangle(
int i,
Node *&v0,
Node *&v1,
Node *&v2)
1263 if(length_1 < 1e-14 || length_2 < 1e-14 || length_3 < 1e-14)
1264 throw Hermes::Exceptions::Exception(
"Edge of triangular element #%d has length less than 1e-14.", i);
1267 if(
same_line(v0->x, v0->
y, v1->x, v1->
y, v2->x, v2->
y))
1268 throw Hermes::Exceptions::Exception(
"Triangular element #%d: all vertices lie on the same line.", i);
1271 if(!
is_convex(v1->x - v0->x, v1->
y - v0->
y, v2->x - v0->x, v2->
y - v0->
y))
1277 void Mesh::check_quad(
int i, Node *&v0, Node *&v1, Node *&v2, Node *&v3)
1285 if(length_1 < 1e-14 || length_2 < 1e-14 || length_3 < 1e-14 || length_4 < 1e-14)
1286 throw Hermes::Exceptions::Exception(
"Edge of quad element #%d has length less than 1e-14.", i);
1292 if(diag_1 < 1e-14 || diag_2 < 1e-14)
1293 throw Hermes::Exceptions::Exception(
"Diagonal of quad element #%d has length less than 1e-14.", i);
1296 if(
same_line(v0->x, v0->y, v1->x, v1->y, v2->x, v2->y))
1297 throw Hermes::Exceptions::Exception(
"Quad element #%d: vertices v0, v1, v2 lie on the same line.", i);
1299 if(
same_line(v0->x, v0->y, v1->x, v1->y, v3->x, v3->y))
1300 throw Hermes::Exceptions::Exception(
"Quad element #%d: vertices v0, v1, v3 lie on the same line.", i);
1302 if(
same_line(v0->x, v0->y, v2->x, v2->y, v3->x, v3->y))
1303 throw Hermes::Exceptions::Exception(
"Quad element #%d: vertices v0, v2, v3 lie on the same line.", i);
1305 if(
same_line(v1->x, v1->y, v2->x, v2->y, v3->x, v3->y))
1306 throw Hermes::Exceptions::Exception(
"Quad element #%d: vertices v1, v2, v3 lie on the same line.", i);
1309 int vertex_1_ok =
is_convex(v1->x - v0->x, v1->y - v0->y, v2->x - v0->x, v2->y - v0->y);
1310 if(!vertex_1_ok)
throw Hermes::Exceptions::Exception(
"Vertex v1 of quad element #%d does not lie on the right of the diagonal v2-v0.", i);
1312 int vertex_3_ok =
is_convex(v2->x - v0->x, v2->y - v0->y, v3->x - v0->x, v3->y - v0->y);
1313 if(!vertex_3_ok)
throw Hermes::Exceptions::Exception(
"Vertex v3 of quad element #%d does not lie on the left of the diagonal v2-v0.", i);
1315 int vertex_2_ok =
is_convex(v2->x - v1->x, v2->y - v1->y, v3->x - v1->x, v3->y - v1->y);
1316 if(!vertex_2_ok)
throw Hermes::Exceptions::Exception(
"Vertex v2 of quad element #%d does not lie on the right of the diagonal v3-v1.", i);
1318 int vertex_0_ok =
is_convex(v3->x - v1->x, v3->y - v1->y, v0->x - v1->x, v0->y - v1->y);
1319 if(!vertex_0_ok)
throw Hermes::Exceptions::Exception(
"Vertex v0 of quad element #%d does not lie on the left of the diagonal v2-v1.", i);
1326 for_all_vertex_nodes(n,
this) {
1333 for_all_elements(e,
this)
1336 throw CurvedException(e->
id);
1351 elements.copy(mesh->elements);
1356 for_all_elements(e,
this)
1359 for (i = 0; i < e->get_nvert(); i++)
1365 for (i = 0; i < e->get_nvert(); i++)
1371 for (i = 0; i < 4; i++)
1372 if(e->
sons[i] != NULL)
1380 if(!e->
cm->toplevel)
1381 e->
cm->parent = &elements[e->
cm->parent->
id];
1391 for_all_edge_nodes(node,
this)
1392 for (i = 0; i < 2; i++)
1393 if(node->
elem[i] != NULL)
1394 node->
elem[i] = &elements[node->
elem[i]->
id];
1396 nbase = mesh->nbase;
1397 nactive = mesh->nactive;
1398 ntopvert = mesh->ntopvert;
1399 ninitial = mesh->ninitial;
1401 boundary_markers_conversion = mesh->boundary_markers_conversion;
1402 element_markers_conversion = mesh->element_markers_conversion;
1405 Node* Mesh::get_base_edge_node(
Element* base,
int edge)
1410 get_edge_sons(base, edge, son1, son2);
1411 base = base->
sons[son1];
1413 return base->
en[edge];
1431 if(node->
ref < TOP_LEVEL_REF)
break;
1433 assert(newnode->
id == i && node->
type == HERMES_TYPE_VERTEX);
1434 memcpy(newnode, node,
sizeof(
Node));
1435 newnode->
ref = TOP_LEVEL_REF;
1440 for_all_base_elements(e, mesh)
1444 if(e->is_triangle())
1445 enew = this->create_triangle(e->
marker, v0, v1, v2, NULL);
1447 enew = this->create_quad(e->
marker, v0, v1, v2, &
nodes[e->
vn[3]->
id], NULL);
1450 for (
unsigned int j = 0; j < e->get_nvert(); j++)
1452 Node* en = get_base_edge_node(e, j);
1461 this->boundary_markers_conversion = mesh->boundary_markers_conversion;
1462 this->element_markers_conversion = mesh->element_markers_conversion;
1464 nbase = nactive = ninitial = mesh->nbase;
1465 ntopvert = mesh->ntopvert;
1472 for_all_elements(e,
this)
1482 this->boundary_markers_conversion.conversion_table.clear();
1483 this->boundary_markers_conversion.conversion_table_inverse.clear();
1484 this->element_markers_conversion.conversion_table.clear();
1485 this->element_markers_conversion.conversion_table_inverse.clear();
1494 this->boundary_markers_conversion = mesh->boundary_markers_conversion;
1495 this->element_markers_conversion = mesh->element_markers_conversion;
1498 for(
int i = 0; i <
nodes.get_size(); i++)
1501 if(node.
type == HERMES_TYPE_EDGE) {
1502 for(
int k = 0; k < 2; k++)
1503 node.
elem[k] = NULL;
1510 for_all_active_elements(e, mesh)
1515 if(e->is_triangle())
1518 enew = elements.add();
1538 enew = elements.add();
1559 for (
unsigned int j = 0; j < e->get_nvert(); j++)
1561 Node* en = get_base_edge_node(e, j);
1570 nbase = nactive = ninitial = mesh->nactive;
1575 void Mesh::convert_quads_to_triangles()
1579 elements.set_append_only(
true);
1580 for_all_active_elements(e,
this)
1581 refine_element_to_triangles_id(e->
id);
1582 elements.set_append_only(false);
1584 Mesh mesh_tmp_for_convert;
1586 for (
int i = 0; i < mesh_tmp_for_convert.ntopvert; i++)
1588 if(mesh_tmp_for_convert.
nodes[i].type == 1)
1590 mesh_tmp_for_convert.
nodes[i].y = 0.0;
1593 MeshReaderH2D loader_mesh_tmp_for_convert;
1594 char* mesh_file_tmp = NULL;
1595 mesh_file_tmp = tmpnam(NULL);
1596 loader_mesh_tmp_for_convert.save(mesh_file_tmp, &mesh_tmp_for_convert);
1597 loader_mesh_tmp_for_convert.load(mesh_file_tmp, &mesh_tmp_for_convert);
1598 remove(mesh_file_tmp);
1599 copy(&mesh_tmp_for_convert);
1602 void Mesh::convert_to_base()
1606 elements.set_append_only(
true);
1607 for_all_active_elements(e,
this)
1608 convert_element_to_base_id(e->
id);
1609 elements.set_append_only(false);
1611 Mesh mesh_tmp_for_convert;
1613 for (
int i = 0; i < mesh_tmp_for_convert.ntopvert; i++)
1615 if(mesh_tmp_for_convert.nodes[i].type == 1)
1617 mesh_tmp_for_convert.nodes[i].y = 0.0;
1620 MeshReaderH2D loader_mesh_tmp_for_convert;
1621 char* mesh_file_tmp = NULL;
1622 mesh_file_tmp = tmpnam(NULL);
1623 loader_mesh_tmp_for_convert.save(mesh_file_tmp, &mesh_tmp_for_convert);
1624 loader_mesh_tmp_for_convert.load(mesh_file_tmp, &mesh_tmp_for_convert);
1625 remove(mesh_file_tmp);
1626 copy(&mesh_tmp_for_convert);
1629 void Mesh::refine_triangle_to_quads(Mesh* mesh, Element* e, Element** sons_out)
1632 int bnd[3] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd };
1633 int mrk[3] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker };
1641 mid->x = (x0->x + x1->x + x2->x)/3;
1642 mid->y = (x0->y + x1->y + x2->y)/3;
1645 bool e_inter =
true;
1646 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1653 memset(cm, 0,
sizeof(cm));
1660 double2 pt[4] = { { 0.0, -1.0 }, { 0.0, 0.0 }, { -1.0, 0.0 }, { -0.33333333, -0.33333333 } };
1661 e->cm->get_mid_edge_points(e, pt, 4);
1662 x0->x = pt[0][0]; x0->y = pt[0][1];
1663 x1->x = pt[1][0]; x1->y = pt[1][1];
1664 x2->x = pt[2][0]; x2->y = pt[2][1];
1665 mid->x = pt[3][0]; mid->y = pt[3][1];
1670 double refinement_angle[3] = {0.0, 0.0, 0.0};
1671 if(e->is_curved() && (!e_inter))
1674 if(e->cm->toplevel ==
true)
1676 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1678 if(e->cm->nurbs[n] != NULL)
1681 refinement_angle[n] = e->cm->nurbs[n]->angle;
1687 if(e->parent->cm->toplevel ==
true)
1689 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1691 if(e->parent->cm->nurbs[n] != NULL)
1694 refinement_angle[n] = e->parent->cm->nurbs[n]->angle / 2;
1700 if(e->parent->parent->cm->toplevel ==
true)
1702 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1704 if(e->parent->parent->cm->nurbs[n] != NULL)
1707 refinement_angle[n] = e->parent->parent->cm->nurbs[n]->angle / 4;
1713 if(e->parent->parent->parent->cm->toplevel ==
true)
1715 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1717 if(e->parent->parent->parent->cm->nurbs[n] != NULL)
1720 refinement_angle[n] = e->parent->parent->parent->cm->nurbs[n]->angle / 8;
1726 if(e->parent->parent->parent->parent->cm->toplevel ==
true)
1728 for (
unsigned int n = 0; n < e->get_nvert(); n++)
1730 if(e->parent->parent->parent->parent->cm->nurbs[n] != NULL)
1733 refinement_angle[n] = e->parent->parent->parent->parent->cm->nurbs[n]->angle / 16;
1739 double angle2 = 0.0;
1742 if((e->is_curved()) && (!e_inter))
1744 for (idx = 0; idx < 2; idx++)
1746 if(e->cm->nurbs[idx] != NULL)
1748 cm[idx] =
new CurvMap;
1749 memset(cm[idx], 0,
sizeof(CurvMap));
1750 cm[idx + 1] =
new CurvMap;
1751 memset(cm[idx + 1], 0,
sizeof(CurvMap));
1756 if(e->cm->nurbs[idx] != NULL)
1758 angle2 = refinement_angle[0] / 2;
1759 Node* node_temp = this->
get_vertex_node(e->vn[idx%3]->id, e->vn[(idx + 1)%3]->id);
1761 for (
int k = 0; k < 2; k++)
1768 p1 = e->vn[(idx)%3]->
id;
1770 if(idx == 0) idx2 = 0;
1771 if(idx == 1) idx2 = 1;
1772 if(idx == 2)
continue;
1777 p2 = e->vn[(idx + 1)%3]->
id;
1779 if(idx == 0)
continue;
1780 if(idx == 1) idx2 = 0;
1781 if(idx == 2) idx2 = 0;
1784 Nurbs* nurbs =
new Nurbs;
1787 nurbs->
arc = cricle;
1790 int inner = 1, outer = 0;
1791 nurbs->np = inner + 2;
1792 nurbs->pt =
new double3[nurbs->np];
1794 nurbs->pt[0][0] =
nodes[p1].x;
1795 nurbs->pt[0][1] =
nodes[p1].y;
1796 nurbs->pt[0][2] = 1.0;
1798 nurbs->pt[inner + 1][0] =
nodes[p2].x;
1799 nurbs->pt[inner + 1][1] =
nodes[p2].y;
1800 nurbs->pt[inner + 1][2] = 1.0;
1802 double angle = angle2;
1803 double a = (180.0 - angle) / 180.0 * M_PI;
1804 nurbs->angle = angle;
1807 double x = 1.0 / tan(a * 0.5);
1808 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
1809 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
1810 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
1814 nurbs->nk = nurbs->degree + nurbs->np + 1;
1815 outer = nurbs->nk - inner;
1818 nurbs->kv =
new double[nurbs->nk];
1820 for (i = 0; i < outer/2; i++)
1822 for (i = outer/2 + inner; i < nurbs->nk; i++)
1826 cm[idx]->toplevel = 1;
1828 cm[idx]->nurbs[idx2] = nurbs;
1834 if(e->cm->nurbs[idx] != NULL)
1836 angle2 = refinement_angle[1] / 2;
1837 Node* node_temp = this->
get_vertex_node(e->vn[idx%3]->id, e->vn[(idx + 1)%3]->id);
1838 for (
int k = 0; k < 2; k++)
1844 p1 = e->vn[(idx)%3]->
id;
1846 if(idx == 0) idx2 = 0;
1847 if(idx == 1) idx2 = 1;
1848 if(idx == 2)
continue;
1853 p2 = e->vn[(idx + 1)%3]->
id;
1855 if(idx == 0)
continue;
1856 if(idx == 1) idx2 = 0;
1857 if(idx == 2) idx2 = 0;
1860 Nurbs* nurbs =
new Nurbs;
1863 nurbs->arc = cricle;
1865 int inner = 1, outer = 0;
1866 nurbs->np = inner + 2;
1867 nurbs->pt =
new double3[nurbs->np];
1869 nurbs->pt[0][0] =
nodes[p1].x;
1870 nurbs->pt[0][1] =
nodes[p1].y;
1871 nurbs->pt[0][2] = 1.0;
1873 nurbs->pt[inner + 1][0] =
nodes[p2].x;
1874 nurbs->pt[inner + 1][1] =
nodes[p2].y;
1875 nurbs->pt[inner + 1][2] = 1.0;
1877 double angle = angle2;
1878 double a = (180.0 - angle) / 180.0 * M_PI;
1879 nurbs->angle = angle;
1882 double x = 1.0 / tan(a * 0.5);
1883 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
1884 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
1885 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
1889 nurbs->nk = nurbs->degree + nurbs->np + 1;
1890 outer = nurbs->nk - inner;
1893 nurbs->kv =
new double[nurbs->nk];
1894 for (i = 0; i < outer/2; i++)
1896 for (i = outer/2 + inner; i < nurbs->nk; i++)
1900 cm[idx]->toplevel = 1;
1902 cm[idx]->nurbs[idx2] = nurbs;
1910 sons[0] = mesh->create_quad(e->marker, e->vn[0], x0, mid, x2, cm[0]);
1911 sons[1] = mesh->create_quad(e->marker, x0, e->vn[1], x1, mid, cm[1]);
1912 sons[2] = mesh->create_quad(e->marker, x1, e->vn[2], x2, mid, cm[2]);
1915 for (
int i = 0; i < 3; i++)
1916 if(sons[i]->is_curved())
1917 sons[i]->cm->update_refmap_coeffs(sons[i]);
1924 e->unref_all_nodes(mesh);
1929 sons[0]->en[0]->bnd = bnd[0]; sons[0]->en[0]->marker = mrk[0];
1930 sons[0]->en[3]->bnd = bnd[2]; sons[0]->en[3]->marker = mrk[2];
1931 sons[1]->en[0]->bnd = bnd[0]; sons[1]->en[0]->marker = mrk[0];
1932 sons[1]->en[1]->bnd = bnd[1]; sons[1]->en[1]->marker = mrk[1];
1933 sons[2]->en[0]->bnd = bnd[1]; sons[2]->en[0]->marker = mrk[1];
1934 sons[2]->en[1]->bnd = bnd[2]; sons[2]->en[1]->marker = mrk[2];
1937 for(
int i = 0; i < 3; i++)
1939 if(sons[i] != NULL) sons[i]->parent = e;
1943 memcpy(e->sons, sons, 3 *
sizeof(Element*));
1946 if(sons_out != NULL)
1948 for(
int i = 0; i < 3; i++) sons_out[i] = sons[i];
1952 void Mesh::refine_element_to_quads_id(
int id)
1955 if(!e->used)
throw Hermes::Exceptions::Exception(
"Invalid element id number.");
1956 if(!e->active)
throw Hermes::Exceptions::Exception(
"Attempt to refine element #%d which has been refined already.", e->id);
1958 if(e->is_triangle())
1959 refine_triangle_to_quads(
this, e);
1961 refine_quad_to_quads(e);
1966 void Mesh::refine_quad_to_triangles(Element* e)
1969 int bnd[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd, e->en[3]->bnd };
1970 int mrk[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker, e->en[3]->marker };
1975 e->unref_all_nodes(
this);
1979 double length_x_0_2 = (e->vn[0]->x - e->vn[2]->x)*(e->vn[0]->x - e->vn[2]->x);
1980 double length_x_1_3 = (e->vn[1]->x - e->vn[3]->x)*(e->vn[1]->x - e->vn[3]->x);
1982 double length_y_0_2 = (e->vn[0]->y - e->vn[2]->y)*(e->vn[0]->y - e->vn[2]->y);
1983 double length_y_1_3 = (e->vn[1]->y - e->vn[3]->y)*(e->vn[1]->y - e->vn[3]->y);
1985 if((length_x_0_2 + length_y_0_2) > (length_x_1_3 + length_y_1_3))
1993 memset(cm, 0,
sizeof(cm));
2001 if((e->cm->nurbs[0] != NULL) || (e->cm->nurbs[1] != NULL))
2003 cm[0] =
new CurvMap;
2004 memset(cm[0], 0,
sizeof(CurvMap));
2006 if((e->cm->nurbs[2] != NULL) || (e->cm->nurbs[3] != NULL))
2008 cm[1] =
new CurvMap;
2009 memset(cm[1], 0,
sizeof(CurvMap));
2012 else if(bcheck ==
false)
2014 if((e->cm->nurbs[1] != NULL) || (e->cm->nurbs[2] != NULL))
2016 cm[0] =
new CurvMap;
2017 memset(cm[0], 0,
sizeof(CurvMap));
2019 if((e->cm->nurbs[3] != NULL) || (e->cm->nurbs[0] != NULL))
2021 cm[1] =
new CurvMap;
2022 memset(cm[1], 0,
sizeof(CurvMap));
2027 for (
unsigned int k = 0; k < 2; k++)
2029 for (idx = 0 + 2*k; idx < 2 + 2*k; idx++)
2031 if(e->cm->nurbs[(idx + i_case2)%4] != NULL)
2033 angle2 = e->cm->nurbs[(idx + i_case2)%4]->angle;
2037 p1 = e->vn[(idx + i_case2)%4]->
id;
2038 p2 = e->vn[(idx + i_case2 + 1)%4]->
id;
2040 Nurbs* nurbs =
new Nurbs;
2043 nurbs->arc = cricle;
2046 int inner = 1, outer;
2048 nurbs->np = inner + 2;
2049 nurbs->pt =
new double3[nurbs->np];
2051 nurbs->pt[0][0] =
nodes[p1].x;
2052 nurbs->pt[0][1] =
nodes[p1].y;
2053 nurbs->pt[0][2] = 1.0;
2055 nurbs->pt[inner + 1][0] =
nodes[p2].x;
2056 nurbs->pt[inner + 1][1] =
nodes[p2].y;
2057 nurbs->pt[inner + 1][2] = 1.0;
2059 double angle = angle2;
2060 double a = (180.0 - angle) / 180.0 * M_PI;
2061 nurbs->angle = angle;
2064 double x = 1.0 / tan(a * 0.5);
2065 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
2066 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
2067 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
2071 nurbs->nk = nurbs->degree + nurbs->np + 1;
2072 outer = nurbs->nk - inner;
2075 nurbs->kv =
new double[nurbs->nk];
2077 for (i = 0; i < outer/2; i++)
2079 for (i = outer/2 + inner; i < nurbs->nk; i++)
2083 cm[k]->toplevel = 1;
2085 cm[k]->nurbs[idx%2] = nurbs;
2096 sons[0] = this->create_triangle(e->marker, e->vn[0], e->vn[1], e->vn[2], cm[0]);
2097 sons[1] = this->create_triangle(e->marker, e->vn[2], e->vn[3], e->vn[0], cm[1]);
2103 sons[0] = this->create_triangle(e->marker, e->vn[1], e->vn[2], e->vn[3], cm[0]);
2104 sons[1] = this->create_triangle(e->marker, e->vn[3], e->vn[0], e->vn[1], cm[1]);
2110 for (
int i = 0; i < 2; i++)
2112 if(sons[i]->is_curved())
2114 sons[i]->cm->update_refmap_coeffs(sons[i]);
2122 sons[0]->en[0]->bnd = bnd[0]; sons[0]->en[0]->marker = mrk[0];
2123 sons[0]->en[1]->bnd = bnd[1]; sons[0]->en[1]->marker = mrk[1];
2124 sons[0]->vn[1]->bnd = bnd[0];
2126 sons[1]->en[0]->bnd = bnd[2]; sons[1]->en[0]->marker = mrk[2];
2127 sons[1]->en[1]->bnd = bnd[3]; sons[1]->en[1]->marker = mrk[3];
2128 sons[1]->vn[2]->bnd = bnd[1];
2132 sons[0]->en[0]->bnd = bnd[1]; sons[0]->en[0]->marker = mrk[1];
2133 sons[0]->en[1]->bnd = bnd[2]; sons[0]->en[1]->marker = mrk[2];
2134 sons[0]->vn[1]->bnd = bnd[1];
2136 sons[1]->en[0]->bnd = bnd[3]; sons[1]->en[0]->marker = mrk[3];
2137 sons[1]->en[1]->bnd = bnd[0]; sons[1]->en[1]->marker = mrk[0];
2138 sons[1]->vn[2]->bnd = bnd[0];
2144 sons[i]->parent = e;
2147 memcpy(e->sons, sons, H2D_MAX_ELEMENT_SONS *
sizeof(Element*));
2150 void Mesh::refine_element_to_triangles_id(
int id)
2153 if(!e->used)
throw Hermes::Exceptions::Exception(
"Invalid element id number.");
2154 if(!e->active)
throw Hermes::Exceptions::Exception(
"Attempt to refine element #%d which has been refined already.", e->id);
2156 if(e->is_triangle())
2159 refine_quad_to_triangles(e);
2164 void Mesh::convert_element_to_base_id(
int id)
2167 if(!e->used)
throw Hermes::Exceptions::Exception(
"Invalid element id number.");
2168 if(!e->active)
throw Hermes::Exceptions::Exception(
"Attempt to refine element #%d which has been refined already.", e->id);
2170 if(e->is_triangle())
2171 convert_triangles_to_base(e);
2173 convert_quads_to_base(e);
2178 Mesh::MarkersConversion::MarkersConversion() : min_marker_unused(1)
2182 Mesh::MarkersConversion::StringValid::StringValid()
2186 Mesh::MarkersConversion::StringValid::StringValid(
std::string marker,
bool valid) : marker(marker), valid(valid)
2190 Mesh::MarkersConversion::IntValid::IntValid()
2194 Mesh::MarkersConversion::IntValid::IntValid(
int marker,
bool valid) : marker(marker), valid(valid)
2198 Mesh::ElementMarkersConversion::ElementMarkersConversion()
2202 Mesh::MarkersConversion::MarkersConversionType Mesh::ElementMarkersConversion::get_type()
const
2204 return HERMES_ELEMENT_MARKERS_CONVERSION;
2207 Mesh::BoundaryMarkersConversion::BoundaryMarkersConversion()
2211 Mesh::MarkersConversion::MarkersConversionType Mesh::BoundaryMarkersConversion::get_type()
const
2213 return HERMES_BOUNDARY_MARKERS_CONVERSION;
2216 Mesh::ElementMarkersConversion &Mesh::get_element_markers_conversion()
2218 return element_markers_conversion;
2221 Mesh::BoundaryMarkersConversion &Mesh::get_boundary_markers_conversion()
2223 return boundary_markers_conversion;
2226 void Mesh::MarkersConversion::insert_marker(
int internal_marker,
std::string user_marker)
2229 if(user_marker !=
"")
2230 if(conversion_table_inverse.find(user_marker) != conversion_table_inverse.end())
2232 if(conversion_table.size() == 0 || conversion_table.find(internal_marker) == conversion_table.end())
2234 conversion_table.insert(std::pair<int, std::string>(internal_marker, user_marker));
2235 conversion_table_inverse.insert(std::pair<std::string, int>(user_marker, internal_marker));
2236 if(user_marker !=
"")
2237 this->min_marker_unused++;
2242 Mesh::MarkersConversion::StringValid Mesh::MarkersConversion::get_user_marker(
int internal_marker)
const
2244 if(internal_marker == H2D_DG_INNER_EDGE_INT)
2245 return StringValid(H2D_DG_INNER_EDGE,
true);
2247 if(conversion_table.find(internal_marker) == conversion_table.end())
2248 return StringValid(
"-999",
false);
2250 return StringValid(conversion_table.find(internal_marker)->second,
true);
2253 Mesh::MarkersConversion::IntValid Mesh::MarkersConversion::get_internal_marker(
std::string user_marker)
const
2255 if(user_marker == H2D_DG_INNER_EDGE)
2256 return IntValid(H2D_DG_INNER_EDGE_INT,
true);
2258 if(conversion_table_inverse.find(user_marker) == conversion_table_inverse.end())
2259 return IntValid(-999,
false);
2261 return IntValid(conversion_table_inverse.find(user_marker)->second,
true);
2264 Mesh::CurvedException::CurvedException(
int elementId) : elementId(elementId)
2266 char * msg =
new char[150];
2267 sprintf(msg,
"Element id %i is curved, this is not supported in this method.", elementId);
2271 Mesh::CurvedException::CurvedException(
const CurvedException & e)
2273 char * msg =
new char[strlen(e.what())+1];
2274 strcpy(msg, e.what());
2276 elementId = e.elementId;
2279 int Mesh::CurvedException::getElementId()
const
2281 return this->elementId;
2284 void Mesh::convert_triangles_to_base(Element *e)
2287 int bnd[3] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd };
2288 int mrk[3] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker };
2291 bool e_inter =
true;
2292 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2299 double refinement_angle[3] = {0.0, 0.0, 0.0};
2300 if(e->is_curved() && (!e_inter))
2303 if(e->cm->toplevel ==
true)
2305 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2307 if(e->cm->nurbs[n] != NULL)
2310 refinement_angle[n] = e->cm->nurbs[n]->angle;
2316 if(e->parent->cm->toplevel ==
true)
2318 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2320 if(e->parent->cm->nurbs[n] != NULL)
2323 refinement_angle[n] = e->parent->cm->nurbs[n]->angle / 2;
2329 if(e->parent->parent->cm->toplevel ==
true)
2331 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2333 if(e->parent->parent->cm->nurbs[n] != NULL)
2336 refinement_angle[n] = e->parent->parent->cm->nurbs[n]->angle / 4;
2342 if(e->parent->parent->parent->cm->toplevel ==
true)
2344 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2346 if(e->parent->parent->parent->cm->nurbs[n] != NULL)
2349 refinement_angle[n] = e->parent->parent->parent->cm->nurbs[n]->angle / 8;
2355 if(e->parent->parent->parent->parent->cm->toplevel ==
true)
2357 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2359 if(e->parent->parent->parent->parent->cm->nurbs[n] != NULL)
2362 refinement_angle[n] = e->parent->parent->parent->parent->cm->nurbs[n]->angle / 16;
2370 e->unref_all_nodes(
this);
2372 double angle2 = 0.0;
2375 memset(&cm, 0,
sizeof(cm));
2378 if((e->is_curved()) && (!e_inter))
2381 memset(cm, 0,
sizeof(CurvMap));
2383 for (idx = 0; idx < 3; idx++)
2384 if((e->cm->nurbs[idx] != NULL) && (bnd[idx] == 1))
2386 angle2 = refinement_angle[idx];
2388 p1 = e->en[idx]->p1;
2389 p2 = e->en[idx]->p2;
2390 if(p1 > p2) std::swap(p1, p2);
2392 Nurbs* nurbs =
new Nurbs;
2395 nurbs->arc = cricle;
2398 int inner = 1, outer = 0;
2399 nurbs->np = inner + 2;
2400 nurbs->pt =
new double3[nurbs->np];
2402 nurbs->pt[0][0] =
nodes[p1].x;
2403 nurbs->pt[0][1] =
nodes[p1].y;
2404 nurbs->pt[0][2] = 1.0;
2406 nurbs->pt[inner + 1][0] =
nodes[p2].x;
2407 nurbs->pt[inner + 1][1] =
nodes[p2].y;
2408 nurbs->pt[inner + 1][2] = 1.0;
2410 double angle = angle2;
2411 double a = (180.0 - angle) / 180.0 * M_PI;
2412 nurbs->angle = angle;
2415 double x = 1.0 / tan(a * 0.5);
2416 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
2417 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
2418 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
2422 nurbs->nk = nurbs->degree + nurbs->np + 1;
2423 outer = nurbs->nk - inner;
2426 nurbs->kv =
new double[nurbs->nk];
2428 for (i = 0; i < outer/2; i++)
2430 for (i = outer/2 + inner; i < nurbs->nk; i++)
2436 cm->nurbs[idx] = nurbs;
2443 Node *v0 = &
nodes[e->vn[0]->id], *v1 = &
nodes[e->vn[1]->id], *v2 = &
nodes[e->vn[2]->id];
2444 enew = this->create_triangle(e->marker, v0, v1, v2, cm);
2446 if(enew->is_curved())
2448 enew->cm->update_refmap_coeffs(enew);
2453 enew->en[0]->bnd = bnd[0];
2454 enew->en[1]->bnd = bnd[1];
2455 enew->en[2]->bnd = bnd[2];
2456 enew->en[0]->marker = mrk[0];
2457 enew->en[1]->marker = mrk[1];
2458 enew->en[2]->marker = mrk[2];
2462 void Mesh::convert_quads_to_base(Element *e)
2465 int bnd[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd, e->en[3]->bnd };
2466 int mrk[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker, e->en[3]->marker };
2469 bool e_inter =
true;
2470 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2478 if(e->is_curved() && (!e_inter))
2481 if(e->cm->toplevel ==
true)
2483 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2485 if((e->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2488 refinement_angle[n] = e->cm->nurbs[n]->angle;
2494 if(e->parent->cm->toplevel ==
true)
2496 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2498 if((e->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2501 refinement_angle[n] = e->parent->cm->nurbs[n]->angle / 2;
2507 if(e->parent->parent->cm->toplevel ==
true)
2509 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2511 if((e->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2514 refinement_angle[n] = e->parent->parent->cm->nurbs[n]->angle / 4;
2520 if(e->parent->parent->parent->cm->toplevel ==
true)
2522 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2524 if((e->parent->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2527 refinement_angle[n] = e->parent->parent->parent->cm->nurbs[n]->angle / 8;
2533 if(e->parent->parent->parent->parent->cm->toplevel ==
true)
2535 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2537 if((e->parent->parent->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2540 refinement_angle[n] = e->parent->parent->parent->parent->cm->nurbs[n]->angle / 16;
2548 for (
unsigned int i = 0; i < e->get_nvert(); i++)
2549 refinement_angle[i] = refinement_angle[i]*2;
2553 e->unref_all_nodes(
this);
2555 double angle2 = 0.0;
2558 memset(&cm, 0,
sizeof(cm));
2561 if((e->is_curved()) && (!e_inter))
2563 bool create_new =
false;
2564 for (
unsigned int i = 0; i < e->get_nvert(); i++)
2566 if(fabs(refinement_angle[i] - 0.0) > 1e-4)
2576 memset(cm, 0,
sizeof(CurvMap));
2579 for (idx = 0; idx < 4; idx++)
2580 if(fabs(refinement_angle[idx] - 0.0) > 1e-4)
2582 angle2 = refinement_angle[idx];
2584 p1 = e->en[idx]->p1;
2585 p2 = e->en[idx]->p2;
2586 if(p1 > p2) std::swap(p1, p2);
2588 Nurbs* nurbs =
new Nurbs;
2591 nurbs->arc = cricle;
2594 int inner = 1, outer = 0;
2595 nurbs->np = inner + 2;
2596 nurbs->pt =
new double3[nurbs->np];
2598 nurbs->pt[0][0] =
nodes[p1].x;
2599 nurbs->pt[0][1] =
nodes[p1].y;
2600 nurbs->pt[0][2] = 1.0;
2602 nurbs->pt[inner + 1][0] =
nodes[p2].x;
2603 nurbs->pt[inner + 1][1] =
nodes[p2].y;
2604 nurbs->pt[inner + 1][2] = 1.0;
2606 double angle = angle2;
2607 double a = (180.0 - angle) / 180.0 * M_PI;
2608 nurbs->angle = angle;
2611 double x = 1.0 / tan(a * 0.5);
2612 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
2613 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
2614 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
2618 nurbs->nk = nurbs->degree + nurbs->np + 1;
2619 outer = nurbs->nk - inner;
2622 nurbs->kv =
new double[nurbs->nk];
2624 for (i = 0; i < outer/2; i++)
2626 for (i = outer/2 + inner; i < nurbs->nk; i++)
2632 cm->nurbs[idx] = nurbs;
2639 Node *v0 = &
nodes[e->vn[0]->id], *v1 = &
nodes[e->vn[1]->id], *v2 = &
nodes[e->vn[2]->id], *v3 = &
nodes[e->vn[3]->id];
2640 enew = this->create_quad(e->marker, v0, v1, v2, v3, cm);
2642 if(enew->is_curved())
2644 enew->cm->update_refmap_coeffs(enew);
2649 enew->en[0]->bnd = bnd[0];
2650 enew->en[1]->bnd = bnd[1];
2651 enew->en[2]->bnd = bnd[2];
2652 enew->en[3]->bnd = bnd[3];
2653 enew->en[0]->marker = mrk[0];
2654 enew->en[1]->marker = mrk[1];
2655 enew->en[2]->marker = mrk[2];
2656 enew->en[3]->marker = mrk[3];
2660 void Mesh::refine_quad_to_quads(Element* e,
int refinement)
2663 int bnd[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd, e->en[3]->bnd };
2664 int mrk[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker, e->en[3]->marker };
2667 bool e_inter =
true;
2668 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2676 if(e->is_curved() && (!e_inter))
2679 if(e->cm->toplevel ==
true)
2681 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2683 if((e->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2686 refinement_angle[n] = e->cm->nurbs[n]->angle;
2692 if(e->parent->cm->toplevel ==
true)
2694 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2696 if((e->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2699 refinement_angle[n] = e->parent->cm->nurbs[n]->angle / 2;
2705 if(e->parent->parent->cm->toplevel ==
true)
2707 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2709 if((e->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2712 refinement_angle[n] = e->parent->parent->cm->nurbs[n]->angle / 4;
2718 if(e->parent->parent->parent->cm->toplevel ==
true)
2720 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2722 if((e->parent->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2725 refinement_angle[n] = e->parent->parent->parent->cm->nurbs[n]->angle / 8;
2731 if(e->parent->parent->parent->parent->cm->toplevel ==
true)
2733 for (
unsigned int n = 0; n < e->get_nvert(); n++)
2735 if((e->parent->parent->parent->parent->cm->nurbs[n] != NULL) && (bnd[n] == 1))
2738 refinement_angle[n] = e->parent->parent->parent->parent->cm->nurbs[n]->angle / 16;
2747 e->unref_all_nodes(
this);
2749 double angle2 = 0.0;
2754 memset(cm, 0,
sizeof(cm));
2769 double2 pt[5] = { { 0.0, -1.0 }, { 1.0, 0.0 }, { 0.0, 1.0 }, { -1.0, 0.0 }, { 0.0, 0.0 } };
2770 e->cm->get_mid_edge_points(e, pt, 5);
2771 x0->x = pt[0][0]; x0->y = pt[0][1];
2772 x1->x = pt[1][0]; x1->y = pt[1][1];
2773 x2->x = pt[2][0]; x2->y = pt[2][1];
2774 x3->x = pt[3][0]; x3->y = pt[3][1];
2775 mid->x = pt[4][0]; mid->y = pt[4][1];
2779 if((e->is_curved()) && (!e_inter))
2782 for (
unsigned int i = 0; i < e->get_nvert(); i++)
2784 if(fabs(refinement_angle[i] - 0.0) > 1e-4)
2786 cm[i%4] =
new CurvMap;
2787 memset(cm[i%4], 0,
sizeof(CurvMap));
2788 cm[(i + 1)%4] =
new CurvMap;
2789 memset(cm[(i + 1)%4], 0,
sizeof(CurvMap));
2793 for (idx = 0; idx < 4; idx++)
2796 if((fabs(refinement_angle[idx%4] - 0.0) > 1e-4))
2798 angle2 = refinement_angle[idx%4] / 2;
2799 Node* node_temp = this->
get_vertex_node(e->vn[idx%4]->id, e->vn[(idx + 1)%4]->id);
2802 p1 = e->vn[(idx)%4]->
id;
2805 Nurbs* nurbs =
new Nurbs;
2808 nurbs->arc = cricle;
2811 int inner = 1, outer = 0;
2812 nurbs->np = inner + 2;
2813 nurbs->pt =
new double3[nurbs->np];
2815 nurbs->pt[0][0] =
nodes[p1].x;
2816 nurbs->pt[0][1] =
nodes[p1].y;
2817 nurbs->pt[0][2] = 1.0;
2819 nurbs->pt[inner + 1][0] =
nodes[p2].x;
2820 nurbs->pt[inner + 1][1] =
nodes[p2].y;
2821 nurbs->pt[inner + 1][2] = 1.0;
2823 double angle = angle2;
2824 double a = (180.0 - angle) / 180.0 * M_PI;
2825 nurbs->angle = angle;
2828 double x = 1.0 / tan(a * 0.5);
2829 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
2830 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
2831 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
2835 nurbs->nk = nurbs->degree + nurbs->np + 1;
2836 outer = nurbs->nk - inner;
2839 nurbs->kv =
new double[nurbs->nk];
2841 for (i = 0; i < outer/2; i++)
2843 for (i = outer/2 + inner; i < nurbs->nk; i++)
2847 cm[idx]->toplevel = 1;
2849 cm[idx]->nurbs[idx%4] = nurbs;
2853 if((fabs(refinement_angle[(idx + 3)%4] - 0.0) > 1e-4))
2855 angle2 = refinement_angle[(idx + 3)%4]/2;
2856 Node* node_temp = this->
get_vertex_node(e->vn[idx%4]->id, e->vn[(idx + 1)%4]->id);
2859 p1 = e->vn[(idx)%4]->
id;
2862 Nurbs* nurbs =
new Nurbs;
2865 nurbs->arc = cricle;
2868 int inner = 1, outer = 0;
2869 nurbs->np = inner + 2;
2870 nurbs->pt =
new double3[nurbs->np];
2872 nurbs->pt[0][0] =
nodes[p1].x;
2873 nurbs->pt[0][1] =
nodes[p1].y;
2874 nurbs->pt[0][2] = 1.0;
2876 nurbs->pt[inner + 1][0] =
nodes[p2].x;
2877 nurbs->pt[inner + 1][1] =
nodes[p2].y;
2878 nurbs->pt[inner + 1][2] = 1.0;
2880 double angle = angle2;
2881 double a = (180.0 - angle) / 180.0 * M_PI;
2882 nurbs->angle = angle;
2885 double x = 1.0 / tan(a * 0.5);
2886 nurbs->pt[1][0] = 0.5*((nurbs->pt[2][0] + nurbs->pt[0][0]) + (nurbs->pt[2][1] - nurbs->pt[0][1]) * x);
2887 nurbs->pt[1][1] = 0.5*((nurbs->pt[2][1] + nurbs->pt[0][1]) - (nurbs->pt[2][0] - nurbs->pt[0][0]) * x);
2888 nurbs->pt[1][2] = cos((M_PI - a) * 0.5);
2892 nurbs->nk = nurbs->degree + nurbs->np + 1;
2893 outer = nurbs->nk - inner;
2896 nurbs->kv =
new double[nurbs->nk];
2898 for (i = 0; i < outer/2; i++)
2900 for (i = outer/2 + inner; i < nurbs->nk; i++)
2904 cm[idx]->toplevel = 1;
2906 cm[idx]->nurbs[(idx + 3)%4] = nurbs;
2913 sons[0] = this->create_quad(e->marker, e->vn[0], x0, mid, x3, cm[0]);
2914 sons[1] = this->create_quad(e->marker, x0, e->vn[1], x1, mid, cm[1]);
2915 sons[2] = this->create_quad(e->marker, mid, x1, e->vn[2], x2, cm[2]);
2916 sons[3] = this->create_quad(e->marker, x3, mid, x2, e->vn[3], cm[3]);
2922 for (i = 0; i < 4; i++)
2924 j = (i > 0) ? i-1 : 3;
2925 sons[i]->en[j]->bnd = bnd[j]; sons[i]->en[j]->marker = mrk[j];
2926 sons[i]->en[i]->bnd = bnd[i]; sons[i]->en[i]->marker = mrk[i];
2927 sons[i]->vn[j]->bnd = bnd[j];
2933 for (i = 0; i < 4; i++)
2934 if(sons[i] != NULL && sons[i]->cm != NULL)
2935 sons[i]->cm->update_refmap_coeffs(sons[i]);
2938 for(
int i = 0; i < 4; i++)
2940 sons[i]->parent = e;
2943 memcpy(e->sons, sons,
sizeof(sons));
2946 int Mesh::get_edge_degree(Node* v1, Node* v2)
2952 degree = 1 + std::max(get_edge_degree(v1, v3), get_edge_degree(v3, v2));
2957 void Mesh::regularize_triangle(Element* e)
2963 int eo[3] = { get_edge_degree(e->vn[0], e->vn[1]),
2964 get_edge_degree(e->vn[1], e->vn[2]),
2965 get_edge_degree(e->vn[2], e->vn[0]) };
2967 int sum = eo[0] + eo[1] + eo[2];
2975 int bnd[3] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd };
2976 int mrk[3] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker };
2981 for(i = 0; i < 3; i++)
2982 if(eo[i] == 1) k = i;
2983 k1 = e->next_vert(k);
2984 k2 = e->prev_vert(k);
2989 e->unref_all_nodes(
this);
2991 t[0] = this->create_triangle(e->marker, e->vn[k], v4, e->vn[k2], NULL);
2992 t[1] = this->create_triangle(e->marker, v4, e->vn[k1], e->vn[k2], NULL);
2995 t[0]->en[2]->bnd = bnd[k2];
2996 t[1]->en[1]->bnd = bnd[k1];
2997 t[0]->en[2]->marker = mrk[k2];
2998 t[1]->en[1]->marker = mrk[k1];
3008 for(i = 0; i < 3; i++)
3009 if(eo[i] == 0) k = i;
3010 k1 = e->next_vert(k);
3011 k2 = e->prev_vert(k);
3017 e->unref_all_nodes(
this);
3019 t[0] = this->create_triangle(e->marker, e->vn[k], e->vn[k1], v4, NULL);
3020 t[1] = this->create_triangle(e->marker, v4, v5, e->vn[k], NULL);
3021 t[2] = this->create_triangle(e->marker, v4, e->vn[k2], v5, NULL);
3024 t[0]->en[0]->bnd = bnd[k];
3025 t[0]->en[0]->marker = mrk[k];
3037 for (i = 0; i < 4; i++)
3038 assign_parent(e, i);
3042 void Mesh::regularize_quad(Element* e)
3044 int i, k = 0, k1, k2, k3, n = 0, m = 0;
3048 int eo[4] = { get_edge_degree(e->vn[0], e->vn[1]),
3049 get_edge_degree(e->vn[1], e->vn[2]),
3050 get_edge_degree(e->vn[2], e->vn[3]),
3051 get_edge_degree(e->vn[3], e->vn[0]) };
3053 int sum = eo[0] + eo[1] + eo[2] + eo[3];
3061 int bnd[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->bnd, e->en[1]->bnd, e->en[2]->bnd , e->en[3]->bnd };
3062 int mrk[
H2D_MAX_NUMBER_EDGES] = { e->en[0]->marker, e->en[1]->marker, e->en[2]->marker, e->en[3]->marker };
3066 for(i = 0; i < 4; i++)
3067 if(eo[i] == 1) k = i;
3068 k1 = e->next_vert(k);
3069 k2 = e->next_vert(k1);
3070 k3 = e->prev_vert(k);
3075 e->unref_all_nodes(
this);
3077 t[0] = this->create_triangle(e->marker, e->vn[k], v4, e->vn[k3], NULL);
3078 t[1] = this->create_triangle(e->marker, v4, e->vn[k1], e->vn[k2], NULL);
3079 t[2] = this->create_triangle(e->marker, v4, e->vn[k2], e->vn[k3], NULL);
3082 t[0]->en[2]->bnd = bnd[k3];
3083 t[1]->en[1]->bnd = bnd[k1];
3084 t[2]->en[1]->bnd = bnd[k2];
3085 t[0]->en[2]->marker = mrk[k3];
3086 t[1]->en[1]->marker = mrk[k1];
3087 t[2]->en[1]->marker = mrk[k2];
3101 for(i = 0; i < 4; i++)
3102 if(eo[i] == 1 && eo[e->next_vert(i)] == 1) k = i;
3103 k1 = e->next_vert(k);
3104 k2 = e->next_vert(k1);
3105 k3 = e->prev_vert(k);
3111 e->unref_all_nodes(
this);
3113 t[0] = this->create_triangle(e->marker, e->vn[k1], v5, v4, NULL);
3114 t[1] = this->create_triangle(e->marker, v5, e->vn[k2], e->vn[k3], NULL);
3115 t[2] = this->create_triangle(e->marker, v4, v5, e->vn[k3], NULL);
3116 t[3] = this->create_triangle(e->marker, v4, e->vn[k3], e->vn[k], NULL);
3118 t[1]->en[1]->bnd = bnd[k2];
3119 t[3]->en[1]->bnd = bnd[k3];
3120 t[1]->en[1]->marker = mrk[k2];
3121 t[3]->en[1]->marker = mrk[k3];
3131 if(eo[0] == 1 && eo[2] == 1)
3134 for (i = 0; i < 4; i++)
3135 assign_parent(e, i);
3138 else if(eo[1] == 1 && eo[3] == 1)
3141 for (i = 0; i < 4; i++)
3142 assign_parent(e, i);
3146 regularize_quad(e->sons[n]);
3147 regularize_quad(e->sons[m]);
3154 for (i = 0; i < 4; i++)
3155 assign_parent(e, i);
3159 void Mesh::flatten()
3162 for_all_edge_nodes(node,
this)
3164 if(node->elem[0] != NULL) node->elem[0] = (Element*) (node->elem[0]->id + 1);
3165 if(node->elem[1] != NULL) node->elem[1] = (Element*) (node->elem[1]->id + 1);
3168 int* idx =
new int[elements.get_size() + 1];
3169 Array<Element> new_elements;
3171 for_all_active_elements(e,
this)
3173 Element* ee = new_elements.add();
3178 parents[ee->id] = parents[e->id];
3181 elements.copy(new_elements);
3182 nbase = nactive = elements.get_num_items();
3184 for_all_edge_nodes(node,
this)
3186 if(node->elem[0] != NULL) node->elem[0] = &(elements[idx[((int) (
long) node->elem[0]) - 1]]);
3187 if(node->elem[1] != NULL) node->elem[1] = &(elements[idx[((
int) (
long) node->elem[1]) - 1]]);
3191 void Mesh::assign_parent(Element* e,
int i)
3193 if(e->sons[i] != NULL)
3195 if(e->sons[i]->id >= parents_size)
3197 parents_size = 2 * parents_size;
3198 parents = (
int*) realloc(parents,
sizeof(
int) * parents_size);
3201 parents[e->sons[i]->id] = parents[e->id];
3219 parents = (
int*) malloc(
sizeof(
int) * parents_size);
3220 for_all_active_elements(e,
this)
3221 parents[e->
id] = e->
id;
3226 for_all_active_elements(e,
this)
3229 if(e->is_triangle())
3231 for(
unsigned int i = 0; i < e->get_nvert(); i++)
3234 if(get_edge_degree(e->
vn[i], e->
vn[j]) > n)
3235 { iso = 0; ok =
false;
break; }
3240 if( ((get_edge_degree(e->
vn[0], e->
vn[1]) > n) || (get_edge_degree(e->
vn[2], e->
vn[3]) > n))
3241 && (get_edge_degree(e->
vn[1], e->
vn[2]) <= n) && (get_edge_degree(e->
vn[3], e->
vn[0]) <= n) )
3242 { iso = 2; ok =
false; }
3243 else if( (get_edge_degree(e->
vn[0], e->
vn[1]) <= n) && (get_edge_degree(e->
vn[2], e->
vn[3]) <= n)
3244 && ((get_edge_degree(e->
vn[1], e->
vn[2]) > n) || (get_edge_degree(e->
vn[3], e->
vn[0]) > n)) )
3245 { iso = 1; ok =
false; }
3248 for(
unsigned int i = 0; i < e->get_nvert(); i++)
3251 if(get_edge_degree(e->
vn[i], e->
vn[j]) > n)
3252 { iso = 0; ok =
false;
break; }
3260 for (
int i = 0; i < 4; i++)
3261 assign_parent(e, i);
3269 for_all_active_elements(e,
this)
3271 if(e->is_curved())
throw Hermes::Exceptions::Exception(
"Regularization of curved elements is not supported.");
3273 if(e->is_triangle())
3274 regularize_triangle(e);