13 #include "../general/sort_pairs.hpp" 14 #include "../general/text.hpp" 41 default: MFEM_ABORT(
"unsupported geometry " << geom);
48 for (
int i = 0; i <
ne; i++)
50 for (
int j = 0; j < 2; j++)
55 for (
int i = 0; i <
nf; i++)
60 for (
int j = 0; j <
nfv[i]; j++)
71 for (
int i = 0; i <
ne; i++)
82 for (
int i = 0; i <
nv; i++)
102 "Element type " << geom <<
" is not supported by NCMesh.");
115 for (
int i = 0; i < mesh->
GetNE(); i++)
120 CheckSupportedGeom(geom);
131 MFEM_ASSERT(root_id == i,
"");
135 for (
int j = 0; j <
GI[geom].
nv; j++)
138 root_elem.
node[j] = id;
139 nodes.Alloc(
id,
id,
id);
150 nodes.Reparent(triple.one, triple.two, triple.three);
155 nodes.UpdateUnused();
156 for (
int i = 0; i <
elements.Size(); i++)
167 for (
int i = 0; i < mesh->
GetNBE(); i++)
176 face =
faces.Find(v[0], v[1], v[2], v[3]);
179 face =
faces.Find(v[0], v[1], v[2]);
182 face =
faces.Find(v[0], v[0], v[1], v[1]);
185 face =
faces.Find(v[0], v[0], v[0], v[0]);
188 MFEM_ABORT(
"Unsupported boundary element geometry.");
191 MFEM_VERIFY(face,
"Boundary face not found.");
199 for (
int i = 0; i < mesh->
GetNV(); i++)
213 , spaceDim(other.spaceDim)
214 , MyRank(other.MyRank)
217 , Legacy(other.Legacy)
220 , elements(other.elements)
255 for (
int i = 0; i <
elements.Size(); i++)
271 "vert_refc: " << (
int)
vert_refc <<
", edge_refc: " 278 int old_p1 = nd.
p1, old_p2 = nd.
p2;
281 nodes.Reparent(node, new_p1, new_p2);
283 MFEM_ASSERT(
shadow.FindId(old_p1, old_p2) < 0,
284 "shadow node already exists");
287 int sh =
shadow.GetId(old_p1, old_p2);
288 shadow[sh].vert_index = node;
293 int mid =
nodes.FindId(node1, node2);
294 if (mid < 0 &&
shadow.Size())
298 mid =
shadow.FindId(node1, node2);
301 mid =
shadow[mid].vert_index;
310 if (mid < 0) { mid =
nodes.GetId(node1, node2); }
318 if (midf >= 0) {
return midf; }
319 return nodes.GetId(en2, en4);
329 for (
int i = 0; i < gi.
nv; i++)
331 nodes[node[i]].vert_refc++;
335 for (
int i = 0; i < gi.
ne; i++)
337 const int* ev = gi.
edges[i];
338 nodes.Get(node[ev[0]], node[ev[1]])->edge_refc++;
342 for (
int i = 0; i < gi.
nf; i++)
344 const int* fv = gi.
faces[i];
345 faces.GetId(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
360 for (
int i = 0; i < gi.
nf; i++)
362 const int* fv = gi.
faces[i];
363 int face =
faces.FindId(node[fv[0]], node[fv[1]],
364 node[fv[2]], node[fv[3]]);
365 MFEM_ASSERT(face >= 0,
"face not found.");
366 faces[face].ForgetElement(elem);
374 for (
int i = 0; i < gi.
ne; i++)
376 const int* ev = gi.
edges[i];
378 MFEM_ASSERT(enode >= 0,
"edge not found.");
379 MFEM_ASSERT(
nodes.IdExists(enode),
"edge does not exist.");
380 if (!
nodes[enode].UnrefEdge())
387 for (
int i = 0; i < gi.
nv; i++)
389 if (!
nodes[node[i]].UnrefVertex())
391 nodes.Delete(node[i]);
401 for (
int i = 0; i < gi.
nf; i++)
404 MFEM_ASSERT(face,
"face not found.");
406 if (fattr) { face->
attribute = fattr[i]; }
412 for (
int i = 0; i < elemFaces.
Size(); i++)
414 if (
faces[elemFaces[i]].Unused())
416 faces.Delete(elemFaces[i]);
423 if (elem[0] < 0) { elem[0] = e; }
424 else if (elem[1] < 0) { elem[1] = e; }
425 else { MFEM_ABORT(
"can't have 3 elements in Face::elem[]."); }
430 if (elem[0] == e) { elem[0] = -1; }
431 else if (elem[1] == e) { elem[1] = -1; }
432 else { MFEM_ABORT(
"element " << e <<
" not found in Face::elem[]."); }
438 const int* fv = gi.
faces[face_no];
439 int* node = elem.
node;
440 return faces.Find(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
447 MFEM_ASSERT(elem[1] < 0,
"not a single element face.");
452 MFEM_ASSERT(elem[1] >= 0,
"no elements in face.");
461 : geom(geom), ref_type(0), tet_type(0), flag(0),
index(-1)
462 , rank(0), attribute(attr), parent(-1)
474 int n4,
int n5,
int n6,
int n7,
476 int fattr0,
int fattr1,
int fattr2,
477 int fattr3,
int fattr4,
int fattr5)
489 for (
int i = 0; i < gi_hex.
nf; i++)
491 const int* fv = gi_hex.
faces[i];
496 f[0]->attribute = fattr0,
f[1]->attribute = fattr1;
497 f[2]->attribute = fattr2,
f[3]->attribute = fattr3;
498 f[4]->attribute = fattr4,
f[5]->attribute = fattr5;
504 int n3,
int n4,
int n5,
506 int fattr0,
int fattr1,
507 int fattr2,
int fattr3,
int fattr4)
519 for (
int i = 0; i < gi_wedge.
nf; i++)
521 const int* fv = gi_wedge.
faces[i];
526 f[0]->attribute = fattr0;
527 f[1]->attribute = fattr1;
528 f[2]->attribute = fattr2;
529 f[3]->attribute = fattr3;
530 f[4]->attribute = fattr4;
536 int fattr0,
int fattr1,
int fattr2,
int fattr3)
547 for (
int i = 0; i < gi_tet.
nf; i++)
549 const int* fv = gi_tet.
faces[i];
553 f[0]->attribute = fattr0;
554 f[1]->attribute = fattr1;
555 f[2]->attribute = fattr2;
556 f[3]->attribute = fattr3;
561 int fattr0,
int fattr1,
int fattr2,
int fattr3,
574 for (
int i = 0; i < gi_pyr.
nf; i++)
576 const int* fv = gi_pyr.
faces[i];
581 f[0]->attribute = fattr0;
582 f[1]->attribute = fattr1;
583 f[2]->attribute = fattr2;
584 f[3]->attribute = fattr3;
585 f[4]->attribute = fattr4;
592 int eattr0,
int eattr1,
int eattr2,
int eattr3)
603 for (
int i = 0; i < gi_quad.
nf; i++)
605 const int* fv = gi_quad.
faces[i];
610 f[0]->attribute = eattr0,
f[1]->attribute = eattr1;
611 f[2]->attribute = eattr2,
f[3]->attribute = eattr3;
617 int attr,
int eattr0,
int eattr1,
int eattr2)
628 for (
int i = 0; i < gi_tri.
nf; i++)
630 const int* fv = gi_tri.
faces[i];
635 f[0]->attribute = eattr0;
636 f[1]->attribute = eattr1;
637 f[2]->attribute = eattr2;
650 int v0 = el.
node[0], v1 = el.
node[1];
651 faces.Get(v0, v0, v0, v0)->attribute = vattr1;
652 faces.Get(v1, v1, v1, v1)->attribute = vattr2;
658 {
return node == n[0] || node == n[3] || node == n[4] || node == n[7]; }
661 {
return node == n[1] || node == n[2] || node == n[5] || node == n[6]; }
664 {
return node == n[0] || node == n[1] || node == n[4] || node == n[5]; }
667 {
return node == n[2] || node == n[3] || node == n[6] || node == n[7]; }
670 {
return node == n[0] || node == n[1] || node == n[2] || node == n[3]; }
673 {
return node == n[4] || node == n[5] || node == n[6] || node == n[7]; }
676 {
return node == n[0] || node == n[1] || node == n[2]; }
679 {
return node == n[3] || node == n[4] || node == n[5]; }
685 Face* face =
faces.Find(vn1, vn2, vn3, vn4);
686 if (!face) {
return; }
690 MFEM_ASSERT(!el.
ref_type,
"element already refined.");
692 int* el_nodes = el.
node;
713 MFEM_ABORT(
"Inconsistent element/face structure.");
730 MFEM_ABORT(
"Inconsistent element/face structure.");
735 MFEM_ABORT(
"Unsupported geometry.")
748 int ev1 = vn1, ev2 = vn4;
756 vn2 = mid[0]; vn3 = mid[2];
760 vn3 = mid[1]; vn4 = mid[3];
764 const Face *face =
faces.Find(vn1, vn2, vn3, vn4);
765 MFEM_ASSERT(face != NULL,
"Face not found: " 766 << vn1 <<
", " << vn2 <<
", " << vn3 <<
", " << vn4
767 <<
" (edge " << ev1 <<
"-" << ev2 <<
").");
776 for (
int i = 0; i < cousins.
Size(); i++)
795 for (
int i = 0, j; i < eid.
Size(); i++)
797 int elem = eid[i].element;
798 for (j = 0; j < nref; j++)
800 if (refs[j].
index == elem) {
break; }
813 int mid12,
int mid34,
int level)
841 if (mid23 >= 0 && mid41 >= 0)
843 int midf =
nodes.FindId(mid23, mid41);
872 for (
int i = 0; i <
reparents.Size(); i++)
908 int en1,
int en2,
int en3,
int en4,
int midf)
926 if (!ref_type) {
return; }
932 char remaining = ref_type & ~el.
ref_type;
958 for (
int i = 0; i < gi.
nf; i++)
960 const int* fv = gi.
faces[i];
961 Face* face =
faces.Find(no[fv[0]], no[fv[1]], no[fv[2]], no[fv[3]]);
990 no[4], mid45, mid67, no[7], attr,
991 fa[0], fa[1], -1, fa[3], fa[4], fa[5]);
994 mid45, no[5], no[6], mid67, attr,
995 fa[0], fa[1], fa[2], fa[3], -1, fa[5]);
1010 no[4], no[5], mid56, mid74, attr,
1011 fa[0], fa[1], fa[2], -1, fa[4], fa[5]);
1014 mid74, mid56, no[6], no[7], attr,
1015 fa[0], -1, fa[2], fa[3], fa[4], fa[5]);
1030 mid04, mid15, mid26, mid37, attr,
1031 fa[0], fa[1], fa[2], fa[3], fa[4], -1);
1034 no[4], no[5], no[6], no[7], attr,
1035 -1, fa[1], fa[2], fa[3], fa[4], fa[5]);
1058 no[4], mid45, midf5, mid74, attr,
1059 fa[0], fa[1], -1, -1, fa[4], fa[5]);
1062 mid45, no[5], mid56, midf5, attr,
1063 fa[0], fa[1], fa[2], -1, -1, fa[5]);
1066 midf5, mid56, no[6], mid67, attr,
1067 fa[0], -1, fa[2], fa[3], -1, fa[5]);
1070 mid74, midf5, mid67, no[7], attr,
1071 fa[0], -1, -1, fa[3], fa[4], fa[5]);
1078 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
1079 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
1097 mid04, midf1, midf3, mid37, attr,
1098 fa[0], fa[1], -1, fa[3], fa[4], -1);
1101 midf1, mid15, mid26, midf3, attr,
1102 fa[0], fa[1], fa[2], fa[3], -1, -1);
1105 mid45, no[5], no[6], mid67, attr,
1106 -1, fa[1], fa[2], fa[3], -1, fa[5]);
1109 no[4], mid45, mid67, no[7], attr,
1110 -1, fa[1], -1, fa[3], fa[4], fa[5]);
1117 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
1118 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
1136 mid04, mid15, midf2, midf4, attr,
1137 fa[0], fa[1], fa[2], -1, fa[4], -1);
1140 midf4, midf2, mid26, mid37, attr,
1141 fa[0], -1, fa[2], fa[3], fa[4], -1);
1144 no[4], no[5], mid56, mid74, attr,
1145 -1, fa[1], fa[2], -1, fa[4], fa[5]);
1148 mid74, mid56, no[6], no[7], attr,
1149 -1, -1, fa[2], fa[3], fa[4], fa[5]);
1156 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
1157 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
1186 mid04, midf1, midel, midf4, attr,
1187 fa[0], fa[1], -1, -1, fa[4], -1);
1190 midf1, mid15, midf2, midel, attr,
1191 fa[0], fa[1], fa[2], -1, -1, -1);
1194 midel, midf2, mid26, midf3, attr,
1195 fa[0], -1, fa[2], fa[3], -1, -1);
1198 midf4, midel, midf3, mid37, attr,
1199 fa[0], -1, -1, fa[3], fa[4], -1);
1202 no[4], mid45, midf5, mid74, attr,
1203 -1, fa[1], -1, -1, fa[4], fa[5]);
1206 mid45, no[5], mid56, midf5, attr,
1207 -1, fa[1], fa[2], -1, -1, fa[5]);
1210 midf5, mid56, no[6], mid67, attr,
1211 -1, -1, fa[2], fa[3], -1, fa[5]);
1214 mid74, midf5, mid67, no[7], attr,
1215 -1, -1, -1, fa[3], fa[4], fa[5]);
1217 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
1218 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
1219 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
1220 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
1221 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
1222 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
1226 MFEM_ABORT(
"invalid refinement type.");
1259 child[0] =
NewWedge(no[0], mid01, mid20,
1260 no[3], mid34, mid53, attr,
1261 fa[0], fa[1], fa[2], -1, fa[4]);
1263 child[1] =
NewWedge(mid01, no[1], mid12,
1264 mid34, no[4], mid45, attr,
1265 fa[0], fa[1], fa[2], fa[3], -1);
1267 child[2] =
NewWedge(mid20, mid12, no[2],
1268 mid53, mid45, no[5], attr,
1269 fa[0], fa[1], -1, fa[3], fa[4]);
1271 child[3] =
NewWedge(mid12, mid20, mid01,
1272 mid45, mid53, mid34, attr,
1273 fa[0], fa[1], -1, -1, -1);
1285 child[0] =
NewWedge(no[0], no[1], no[2],
1286 mid03, mid14, mid25, attr,
1287 fa[0], -1, fa[2], fa[3], fa[4]);
1289 child[1] =
NewWedge(mid03, mid14, mid25,
1290 no[3], no[4], no[5], attr,
1291 -1, fa[1], fa[2], fa[3], fa[4]);
1317 child[0] =
NewWedge(no[0], mid01, mid20,
1318 mid03, midf2, midf4, attr,
1319 fa[0], -1, fa[2], -1, fa[4]);
1321 child[1] =
NewWedge(mid01, no[1], mid12,
1322 midf2, mid14, midf3, attr,
1323 fa[0], -1, fa[2], fa[3], -1);
1325 child[2] =
NewWedge(mid20, mid12, no[2],
1326 midf4, midf3, mid25, attr,
1327 fa[0], -1, -1, fa[3], fa[4]);
1329 child[3] =
NewWedge(mid12, mid20, mid01,
1330 midf3, midf4, midf2, attr,
1331 fa[0], -1, -1, -1, -1);
1333 child[4] =
NewWedge(mid03, midf2, midf4,
1334 no[3], mid34, mid53, attr,
1335 -1, fa[1], fa[2], -1, fa[4]);
1337 child[5] =
NewWedge(midf2, mid14, midf3,
1338 mid34, no[4], mid45, attr,
1339 -1, fa[1], fa[2], fa[3], -1);
1341 child[6] =
NewWedge(midf4, midf3, mid25,
1342 mid53, mid45, no[5], attr,
1343 -1, fa[1], -1, fa[3], fa[4]);
1345 child[7] =
NewWedge(midf3, midf4, midf2,
1346 mid45, mid53, mid34, attr,
1347 -1, fa[1], -1, -1, -1);
1349 CheckIsoFace(no[0], no[1], no[4], no[3], mid01, mid14, mid34, mid03, midf2);
1350 CheckIsoFace(no[1], no[2], no[5], no[4], mid12, mid25, mid45, mid14, midf3);
1351 CheckIsoFace(no[2], no[0], no[3], no[5], mid20, mid03, mid53, mid25, midf4);
1382 -1, fa[1], fa[2], fa[3]);
1385 fa[0], -1, fa[2], fa[3]);
1388 fa[0], fa[1], -1, fa[3]);
1391 fa[0], fa[1], fa[2], -1);
1471 child[0] =
NewPyramid(no[0], mid01, midf0, mid03, mid04,
1472 attr, fa[0], fa[1], -1, -1, fa[4]);
1474 child[1] =
NewPyramid(mid01, no[1], mid12, midf0, mid14,
1475 attr, fa[0], fa[1], fa[2], -1, -1);
1477 child[2] =
NewPyramid(midf0, mid12, no[2], mid23, mid24,
1478 attr, fa[0], -1, fa[2], fa[3], -1);
1480 child[3] =
NewPyramid(mid03, midf0, mid23, no[3], mid34,
1481 attr, fa[0], -1, -1, fa[3], fa[4]);
1483 child[4] =
NewPyramid(mid24, mid14, mid04, mid34, midf0,
1484 attr, -1, -1, -1, -1, -1);
1486 child[5] =
NewPyramid(mid04, mid14, mid24, mid34, no[4],
1487 attr, -1, fa[1], fa[2], fa[3], fa[4]);
1490 attr, -1, -1, -1, fa[1]);
1493 attr, -1, -1, fa[2], -1);
1496 attr, -1, -1, fa[3], -1);
1499 attr, -1, fa[4], -1, -1);
1501 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid03, midf0);
1509 int mid01 =
nodes.GetId(no[0], no[1]);
1510 int mid23 =
nodes.GetId(no[2], no[3]);
1513 attr, fa[0], -1, fa[2], fa[3]);
1516 attr, fa[0], fa[1], fa[2], -1);
1520 int mid12 =
nodes.GetId(no[1], no[2]);
1521 int mid30 =
nodes.GetId(no[3], no[0]);
1524 attr, fa[0], fa[1], -1, fa[3]);
1527 attr, -1, fa[1], fa[2], fa[3]);
1531 int mid01 =
nodes.GetId(no[0], no[1]);
1532 int mid12 =
nodes.GetId(no[1], no[2]);
1533 int mid23 =
nodes.GetId(no[2], no[3]);
1534 int mid30 =
nodes.GetId(no[3], no[0]);
1536 int midel =
nodes.GetId(mid01, mid23);
1539 attr, fa[0], -1, -1, fa[3]);
1542 attr, fa[0], fa[1], -1, -1);
1545 attr, -1, fa[1], fa[2], -1);
1548 attr, -1, -1, fa[2], fa[3]);
1552 MFEM_ABORT(
"Invalid refinement type.");
1562 int mid01 =
nodes.GetId(no[0], no[1]);
1563 int mid12 =
nodes.GetId(no[1], no[2]);
1564 int mid20 =
nodes.GetId(no[2], no[0]);
1566 child[0] =
NewTriangle(no[0], mid01, mid20, attr, fa[0], -1, fa[2]);
1567 child[1] =
NewTriangle(mid01, no[1], mid12, attr, fa[0], fa[1], -1);
1568 child[2] =
NewTriangle(mid20, mid12, no[2], attr, -1, fa[1], fa[2]);
1569 child[3] =
NewTriangle(mid12, mid20, mid01, attr, -1, -1, -1);
1575 int mid =
nodes.GetId(no[0], no[1]);
1576 child[0] =
NewSegment(no[0], mid, attr, fa[0], -1);
1577 child[1] =
NewSegment(mid, no[1], attr, -1, fa[1]);
1581 MFEM_ABORT(
"Unsupported element geometry.");
1585 for (
int i = 0; i < MaxElemChildren && child[i] >= 0; i++)
1598 for (
int i = 0; i < MaxElemChildren && child[i] >= 0; i++)
1607 for (
int i = 0; i < MaxElemChildren && child[i] >= 0; i++)
1616 std::memcpy(el.
child, child,
sizeof(el.
child));
1624 for (
int i = refinements.
Size()-1; i >= 0; i--)
1652 #if defined(MFEM_DEBUG) && !defined(MFEM_USE_MPI) 1653 mfem::out <<
"Refined " << refinements.
Size() <<
" + " << nforced
1654 <<
" elements" << std::endl;
1656 MFEM_CONTRACT_VAR(nforced);
1683 MFEM_ASSERT(ch != -1,
"");
1689 MFEM_ASSERT(ch != -1,
"");
1704 MFEM_ABORT(
"Unsupported element geometry.");
1716 std::memcpy(child, el.
child,
sizeof(child));
1719 for (
int i = 0; i < MaxElemChildren && child[i] >= 0; i++)
1728 int ref_type_key = el.
ref_type - 1;
1736 constexpr
int nb_cube_childs = 8;
1737 for (
int i = 0; i < nb_cube_childs; i++)
1739 const int child_local_index = hex_deref_table[ref_type_key][i];
1740 const int child_global_index = child[child_local_index];
1745 constexpr
int nb_cube_faces = 6;
1746 for (
int i = 0; i < nb_cube_faces; i++)
1748 const int child_local_index = hex_deref_table[ref_type_key]
1749 [i + nb_cube_childs];
1750 const int child_global_index = child[child_local_index];
1753 faces_attribute[i] =
faces.Find(ch.
node[fv[0]], ch.
node[fv[1]],
1760 MFEM_ASSERT(prism_deref_table[ref_type_key][0] != -1,
1761 "invalid prism refinement");
1762 constexpr
int nb_prism_childs = 6;
1763 for (
int i = 0; i < nb_prism_childs; i++)
1765 const int child_local_index = prism_deref_table[ref_type_key][i];
1766 const int child_global_index = child[child_local_index];
1772 constexpr
int nb_prism_faces = 5;
1773 for (
int i = 0; i < nb_prism_faces; i++)
1775 const int child_local_index = prism_deref_table[ref_type_key]
1776 [i + nb_prism_childs];
1777 const int child_global_index = child[child_local_index];
1780 faces_attribute[i] =
faces.Find(ch.
node[fv[0]], ch.
node[fv[1]],
1787 MFEM_ASSERT(pyramid_deref_table[ref_type_key][0] != -1,
1788 "invalid pyramid refinement");
1789 constexpr
int nb_pyramid_childs = 5;
1790 for (
int i = 0; i < nb_pyramid_childs; i++)
1792 const int child_local_index = pyramid_deref_table[ref_type_key][i];
1793 const int child_global_index = child[child_local_index];
1800 constexpr
int nb_pyramid_faces = 5;
1801 for (
int i = 0; i < nb_pyramid_faces; i++)
1803 const int child_local_index = pyramid_deref_table[ref_type_key]
1804 [i + nb_pyramid_childs];
1805 const int child_global_index = child[child_local_index];
1808 faces_attribute[i] =
faces.Find(ch.
node[fv[0]], ch.
node[fv[1]],
1815 for (
int i = 0; i < 4; i++)
1821 faces_attribute[i] =
faces.Find(ch2.
node[fv[0]], ch2.
node[fv[1]],
1828 constexpr
int nb_square_childs = 4;
1829 for (
int i = 0; i < nb_square_childs; i++)
1831 const int child_local_index = quad_deref_table[ref_type_key][i];
1832 const int child_global_index = child[child_local_index];
1836 constexpr
int nb_square_faces = 4;
1837 for (
int i = 0; i < nb_square_faces; i++)
1839 const int child_local_index = quad_deref_table[ref_type_key]
1840 [i + nb_square_childs];
1841 const int child_global_index = child[child_local_index];
1844 faces_attribute[i] =
faces.Find(ch.
node[fv[0]], ch.
node[fv[1]],
1851 constexpr
int nb_triangle_childs = 3;
1852 for (
int i = 0; i < nb_triangle_childs; i++)
1857 faces_attribute[i] =
faces.Find(ch.
node[fv[0]], ch.
node[fv[1]],
1864 constexpr
int nb_segment_childs = 2;
1865 for (
int i = 0; i < nb_segment_childs; i++)
1867 int ni =
elements[child[i]].node[i];
1869 faces_attribute[i] =
faces.Find(ni, ni, ni, ni)->attribute;
1874 MFEM_ABORT(
"Unsupported element geometry.");
1885 el.
rank = std::numeric_limits<int>::max();
1886 for (
int i = 0; i < MaxElemChildren && child[i] >= 0; i++)
1909 int total = 0, ref = 0, ghost = 0;
1918 if (!ref && ghost < total)
1921 int next_row = list.
Size() ? (list.
Last().from + 1) : 0;
1947 int size = list.
Size() ? (list.
Last().from + 1) : 0;
1956 for (
int i = 0; i < deref_table.
Size(); i++)
1958 const int* fine = deref_table.
GetRow(i), size = deref_table.
RowSize(i);
1962 for (
int j = 0; j < size; j++)
1967 for (
int k = 0; k <
Dim; k++)
1969 if ((parent.
ref_type & (1 << k)) &&
1970 splits[k] >= max_nc_level)
1983 MFEM_VERIFY(
Dim < 3 ||
Iso,
1984 "derefinement of 3D anisotropic meshes not implemented yet.");
1992 for (
int i = 0; i < derefs.
Size(); i++)
1994 int row = derefs[i];
1996 "invalid derefinement number.");
2011 for (
int i = 0; i < fine_coarse.
Size(); i++)
2025 for (
int i = 0; i < nfine; i++)
2045 int code = (prn.
ref_type << 4) | i;
2047 fine_coarse[ch.
index] = parent;
2075 el.
index = counter++;
2094 for (
int i = 0; i < 4; i++)
2096 int ch = quad_hilbert_child_order[state][i];
2097 int st = quad_hilbert_child_state[state][i];
2103 for (
int i = 0; i < 8; i++)
2105 int ch = hex_hilbert_child_order[state][i];
2106 int st = hex_hilbert_child_state[state][i];
2114 if (el.
child[i] >= 0)
2153 #ifndef MFEM_NCMESH_OLD_VERTEX_ORDERING 2179 for (
auto & node :
nodes)
2181 node.vert_index = -4;
2187 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2211 for (
auto &node :
nodes)
2213 if (node.vert_index == -1)
2223 for (
int i = 0; i < sfc_order.Size(); i++)
2228 for (
int i = 0; i < sfc_order.Size(); i++)
2231 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2241 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2243 if (node->HasVertex() && node->vert_index >= 0)
2254 for (
int i = 0; i < sfc_order.Size(); i++)
2257 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2267 #else // old ordering for debugging/testing only 2268 bool parallel =
false;
2270 if (dynamic_cast<ParNCMesh*>(
this)) { parallel =
true; }
2276 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2278 if (node->HasVertex()) { node->vert_index =
NVertices++; }
2284 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2291 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2293 if (node->HasVertex()) { node->vert_index = -1; }
2302 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2304 int &vindex =
nodes[el.
node[j]].vert_index;
2305 if (vindex < 0) { vindex =
NVertices++; }
2311 for (
auto &node :
nodes)
2313 if (node.HasVertex() && node.vert_index >= 0)
2320 for (
auto &node :
nodes)
2322 if (node.HasVertex() && node.vert_index < 0)
2343 node_order = (
char*) quad_hilbert_child_order;
2348 node_order = (
char*) hex_hilbert_child_order;
2355 int entry_node = -2;
2358 for (
int i = 0; i < root_count; i++)
2363 if (v_in < 0) { v_in = 0; }
2367 for (
int ni = 0; ni <
MaxElemNodes; ++ni) { shared[ni] = 0; }
2368 if (i+1 < root_count)
2371 for (
int j = 0; j < nch; j++)
2374 if (node >= 0) { shared[node] =
true; }
2379 int state =
Dim*v_in;
2380 for (
int j = 0; j <
Dim; j++)
2382 if (shared[(
int) node_order[nch*(state + j) + nch-1]])
2391 entry_node =
RetrieveNode(el, node_order[nch*state + nch-1]);
2406 MFEM_ABORT(
"invalid geometry");
2421 MFEM_VERIFY(tv.
visited ==
false,
"cyclic vertex dependencies.");
2427 for (
int i = 0; i < 3; i++)
2429 tv.
pos[i] = (pos1[i] + pos2[i]) * 0.5;
2442 for (
int i = 0; i < mesh.
vertices.Size(); i++)
2469 const int* node = nc_elem.
node;
2476 for (
int j = 0; j < gi.
nv; j++)
2478 elem->GetVertices()[j] =
nodes[node[j]].vert_index;
2483 for (
int k = 0; k < gi.
nf; k++)
2485 const int* fv = gi.
faces[k];
2486 const int nfv = gi.
nfv[k];
2487 const Face* face =
faces.Find(node[fv[0]], node[fv[1]],
2488 node[fv[2]], node[fv[3]]);
2497 for (
int j = 0; j < 4; j++)
2499 quad->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2507 MFEM_ASSERT(nfv == 3,
"");
2510 for (
int j = 0; j < 3; j++)
2512 tri->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2521 for (
int j = 0; j < 2; j++)
2523 segment->GetVertices()[j] =
nodes[node[fv[2*j]]].vert_index;
2532 point->GetVertices()[0] =
nodes[node[fv[0]]].vert_index;
2548 for (
auto &node :
nodes)
2550 if (node.HasEdge()) { node.edge_index = -1; }
2552 for (
auto &face :
faces)
2559 for (
int i = 0; i < edge_vertex->
Size(); i++)
2561 const int *ev = edge_vertex->
GetRow(i);
2564 MFEM_ASSERT(node && node->
HasEdge(),
2565 "edge (" << ev[0] <<
"," << ev[1] <<
") not found, " 2573 for (
int i = 0; i <
NFaces; i++)
2575 const int* fv = mesh->
GetFace(i)->GetVertices();
2576 const int nfv = mesh->
GetFace(i)->GetNVertices();
2589 MFEM_ASSERT(nfv == 3,
"");
2597 MFEM_ASSERT(nfv == 2,
"");
2600 face =
faces.Find(n0, n0, n1, n1);
2604 const int *ev = edge_vertex->
GetRow(i);
2605 MFEM_ASSERT((ev[0] == fv[0] && ev[1] == fv[1]) ||
2606 (ev[1] == fv[0] && ev[0] == fv[1]),
"");
2610 MFEM_VERIFY(face,
"face not found.");
2618 for (
auto &node :
nodes)
2620 if (node.HasEdge() && node.edge_index < 0)
2628 for (
auto &face :
faces)
2651 for (
int j = 0; j < gi.
nf; j++)
2653 const int *fv = gi.
faces[j];
2656 MFEM_ASSERT(face,
"face not found!");
2658 if (face->
index < 0)
2674 for (
auto &face :
faces)
2676 if (face.index < 0) { face.index =
NFaces + (nghosts++); }
2687 MFEM_ASSERT(
Dim >= 3,
"");
2696 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3, mid[3] = e4; }
2699 int midf1 = -1, midf2 = -1;
2704 if (midf1 >= 0 && midf1 == midf2)
2707 if (nd.
p1 != e1 && nd.
p2 != e1) { midf1 = -1; }
2708 if (nd.
p1 != e2 && nd.
p2 != e2) { midf2 = -1; }
2712 MFEM_ASSERT(!(midf1 >= 0 && midf2 >= 0),
"incorrectly split face!");
2714 if (midf1 < 0 && midf2 < 0)
2716 if (mid) { mid[4] = -1; }
2719 else if (midf1 >= 0)
2721 if (mid) { mid[4] = midf1; }
2726 if (mid) { mid[4] = midf2; }
2733 int e1 =
nodes.FindId(v1, v2);
2734 if (e1 < 0 || !
nodes[e1].HasVertex()) {
return false; }
2736 int e2 =
nodes.FindId(v2, v3);
2737 if (e2 < 0 || !
nodes[e2].HasVertex()) {
return false; }
2739 int e3 =
nodes.FindId(v3, v1);
2740 if (e3 < 0 || !
nodes[e3].HasVertex()) {
return false; }
2742 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3; }
2752 if (el.
node[i] == node) {
return i; }
2754 MFEM_ABORT(
"Node not found.");
2760 for (
int i = 0; i <
GI[el.
Geom()].
nv; i++)
2764 if (abort) { MFEM_ABORT(
"Node not found."); }
2773 for (
int i = 0; i < gi.
ne; i++)
2775 const int* ev = gi.
edges[i];
2776 int n0 = el.
node[ev[0]];
2777 int n1 = el.
node[ev[1]];
2778 if ((n0 == vn0 && n1 == vn1) ||
2779 (n0 == vn1 && n1 == vn0)) {
return i; }
2782 if (abort) { MFEM_ABORT(
"Edge (" << vn0 <<
", " << vn1 <<
") not found"); }
2789 for (
int i = 0; i < gi.
nf; i++)
2791 const int* fv = gi.
faces[i];
2792 if ((
a == fv[0] ||
a == fv[1] ||
a == fv[2] ||
a == fv[3]) &&
2793 (
b == fv[0] ||
b == fv[1] ||
b == fv[2] ||
b == fv[3]) &&
2794 (c == fv[0] || c == fv[1] || c == fv[2] || c == fv[3]))
2799 MFEM_ABORT(
"Face not found.");
2809 MFEM_ASSERT(
sizeof(
double) ==
sizeof(std::uint64_t),
"");
2813 std::uint64_t hash = 0xf9ca9ba106acbba9;
2814 for (
int i = 0; i < pm.
np; i++)
2816 for (
int j = 0; j < pm.
points[i].
dim; j++)
2821 hash = 31*hash + *((std::uint64_t*) &coord);
2833 int GetIndex(
const NCMesh::PointMatrix &pm)
2835 int &
index = map[pm];
2840 void ExportMatrices(Array<DenseMatrix*> &point_matrices)
const 2842 point_matrices.SetSize(map.size());
2843 for (
const auto &pair : map)
2845 DenseMatrix* mat =
new DenseMatrix();
2846 pair.first.GetMatrix(*mat);
2847 point_matrices[pair.second - 1] = mat;
2851 void DumpBucketSizes()
const 2853 for (
unsigned i = 0; i < map.bucket_count(); i++)
2860 std::unordered_map<NCMesh::PointMatrix, int, PointMatrixHash> map;
2874 int nfv = (v3 >= 0) ? 4 : 3;
2879 reordered.
np = pm.
np;
2880 for (
int i = 0, j; i < nfv; i++)
2882 for (j = 0; j < nfv; j++)
2884 if (fv[i] == master[j])
2890 MFEM_ASSERT(j != nfv,
"node not found.");
2902 Face* fa =
faces.Find(vn0, vn1, vn2, vn3);
2914 sl.
matrix = matrix_map.GetIndex(pm_r);
2916 eface[0] = eface[2] = fa;
2917 eface[1] = eface[3] = fa;
2930 Point pmid0(pm(0), pm(1)), pmid2(pm(2), pm(3));
2934 level+1, ef[0], matrix_map);
2938 level+1, ef[1], matrix_map);
2940 eface[1] = ef[1][1];
2941 eface[3] = ef[0][3];
2942 eface[0] = eface[2] = NULL;
2944 else if (split == 2)
2946 Point pmid1(pm(1), pm(2)), pmid3(pm(3), pm(0));
2950 level+1, ef[0], matrix_map);
2954 level+1, ef[1], matrix_map);
2956 eface[0] = ef[0][0];
2957 eface[2] = ef[1][2];
2958 eface[1] = eface[3] = NULL;
2969 const int fi[3][2] = {{0, 0}, {1, 3}, {2, 0}};
2970 if (!ef[0][fi[split][0]] && !ef[1][fi[split][1]])
2980 MFEM_ASSERT(eid.
Size() > 0,
"edge prism not found");
2981 MFEM_ASSERT(eid.
Size() < 2,
"non-unique edge prism");
2991 Point mid0(pm(0), pm(1)), mid2(pm(2), pm(3));
2992 int v1 =
nodes[mid[0]].vert_index;
2993 int v2 =
nodes[mid[2]].vert_index;
2995 matrix_map.GetIndex(
3001 Point mid1(pm(1), pm(2)), mid3(pm(3), pm(0));
3002 int v1 =
nodes[mid[1]].vert_index;
3003 int v2 =
nodes[mid[3]].vert_index;
3005 matrix_map.GetIndex(
3017 int mid =
nodes.FindId(vn0, vn1);
3018 if (mid < 0) {
return; }
3034 int v0index =
nodes[vn0].vert_index;
3035 int v1index =
nodes[vn1].vert_index;
3038 matrix_map.GetIndex((v0index < v1index) ?
PointMatrix(p0, p1, p0)
3070 sl.
matrix = matrix_map.GetIndex(pm_r);
3079 Point pmid0(pm(0), pm(1)), pmid1(pm(1), pm(2)), pmid2(pm(2), pm(0));
3084 level+1, matrix_map);
3088 level+1, matrix_map);
3092 level+1, matrix_map);
3096 level+1, matrix_map);
3113 if (
Dim < 3) {
return; }
3120 processed_faces = 0;
3129 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3132 for (
int j = 0; j < gi.
nf; j++)
3136 for (
int k = 0; k < 4; k++)
3141 int face =
faces.FindId(node[0], node[1], node[2], node[3]);
3142 MFEM_ASSERT(face >= 0,
"face not found!");
3148 if (processed_faces[face]) {
continue; }
3149 processed_faces[face] = 1;
3154 if (fa.
elem[0] >= 0 && fa.
elem[1] >= 0)
3184 for (
int ii = sb; ii < se; ii++)
3205 int mid =
nodes.FindId(vn0, vn1);
3206 if (mid < 0) {
return; }
3209 if (nd.
HasEdge() && level > 0)
3219 int v0index =
nodes[vn0].vert_index;
3220 int v1index =
nodes[vn1].vert_index;
3221 if (v0index > v1index) { sl.
edge_flags |= 2; }
3225 double tmid = (t0 + t1) / 2;
3226 TraverseEdge(vn0, mid, t0, tmid, flags, level+1, matrix_map);
3227 TraverseEdge(mid, vn1, tmid, t1, flags, level+1, matrix_map);
3236 processed_edges = 0;
3249 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3252 for (
int j = 0; j < gi.
ne; j++)
3255 const int* ev = gi.
edges[j];
3256 int node[2] = { el.
node[ev[0]], el.
node[ev[1]] };
3258 int enode =
nodes.FindId(node[0], node[1]);
3259 MFEM_ASSERT(enode >= 0,
"edge node not found!");
3262 MFEM_ASSERT(nd.
HasEdge(),
"edge not found!");
3270 int face =
faces.FindId(node[0], node[0], node[1], node[1]);
3271 MFEM_ASSERT(face >= 0,
"face not found!");
3283 if (processed_edges[enode]) {
continue; }
3284 processed_edges[enode] = 1;
3287 double t0 = 0.0, t1 = 1.0;
3288 int v0index =
nodes[node[0]].vert_index;
3289 int v1index =
nodes[node[1]].vert_index;
3290 int flags = (v0index > v1index) ? 1 : 0;
3294 TraverseEdge(node[0], node[1], t0, t1, flags, 0, matrix_map);
3304 for (
int ii = sb; ii < se; ii++)
3321 int local = edge_local[sl.
index];
3341 processed_vertices = 0;
3349 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
3351 int node = el.
node[j];
3359 if (processed_vertices[
index]) {
continue; }
3360 processed_vertices[
index] = 1;
3371 oriented_matrix = *(point_matrices[slave.
Geom()][slave.
matrix]);
3375 MFEM_ASSERT(oriented_matrix.
Height() == 1 &&
3376 oriented_matrix.
Width() == 2,
"not an edge point matrix");
3380 oriented_matrix(0,0) = 1.0 - oriented_matrix(0,0);
3381 oriented_matrix(0,1) = 1.0 - oriented_matrix(0,1);
3385 std::swap(oriented_matrix(0,0), oriented_matrix(0,1));
3392 conforming.DeleteAll();
3393 masters.DeleteAll();
3398 for (
int j = 0; j < point_matrices[i].Size(); j++)
3400 delete point_matrices[i][j];
3402 point_matrices[i].DeleteAll();
3405 inv_index.DeleteAll();
3410 return conforming.Size() + masters.Size() + slaves.Size();
3415 if (!inv_index.Size())
3418 for (
int i = 0; i < conforming.Size(); i++)
3420 max_index = std::max(conforming[i].
index, max_index);
3422 for (
int i = 0; i < masters.Size(); i++)
3424 max_index = std::max(masters[i].
index, max_index);
3426 for (
int i = 0; i < slaves.Size(); i++)
3428 if (slaves[i].
index < 0) {
continue; }
3429 max_index = std::max(slaves[i].
index, max_index);
3432 inv_index.SetSize(max_index + 1);
3435 for (
int i = 0; i < conforming.Size(); i++)
3437 inv_index[conforming[i].index] = (i << 2);
3439 for (
int i = 0; i < masters.Size(); i++)
3441 inv_index[masters[i].index] = (i << 2) + 1;
3443 for (
int i = 0; i < slaves.Size(); i++)
3445 if (slaves[i].
index < 0) {
continue; }
3446 inv_index[slaves[i].index] = (i << 2) + 2;
3450 MFEM_ASSERT(
index >= 0 &&
index < inv_index.Size(),
"");
3451 int key = inv_index[
index];
3455 MFEM_VERIFY(key >= 0,
"index " <<
index <<
" not found.");
3459 *type = (key >= 0) ? (key & 0x3) : -1;
3462 if (*type < 0) {
return invalid; }
3468 case 0:
return conforming[key >> 2];
3469 case 1:
return masters[key >> 2];
3470 case 2:
return slaves[key >> 2];
3471 default: MFEM_ABORT(
"internal error");
return conforming[0];
3480 int mid =
nodes.FindId(v0, v1);
3481 if (mid >= 0 &&
nodes[mid].HasVertex())
3495 for (
int i = 0; i < 3; i++)
3552 int** JJ =
new int*[nrows];
3562 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3565 int* node = el.
node;
3568 for (
int j = 0; j < gi.
ne; j++)
3570 const int* ev = gi.
edges[j];
3576 for (
int j = 0; j < gi.
nf; j++)
3578 const int* fv = gi.
faces[j];
3582 node[fv[2]], node[fv[3]], indices);
3595 int size = indices.
Size();
3597 JJ[i] =
new int[size];
3598 std::memcpy(JJ[i], indices.
GetData(), size *
sizeof(int));
3603 for (
int i = 0; i < nrows; i++)
3614 for (
int i = 0; i < nrows; i++)
3616 int cnt = I[i+1] - I[i];
3617 std::memcpy(J+nnz, JJ[i], cnt *
sizeof(
int));
3644 MFEM_VERIFY(elem_set.
Size() == nleaves,
"");
3653 for (
int i = 0; i < nleaves; i++)
3659 for (
int j = 0; j < nv; j++)
3666 for (
int j = 0; j < nv; j++)
3668 vmark[el.
node[j]] = 1;
3679 neighbor_set->
SetSize(nleaves);
3683 for (
int i = 0; i < nleaves; i++)
3691 for (
int j = 0; j < nv; j++)
3693 if (vmark[v[j]]) { hit =
true;
break; }
3700 for (
int j = 0; j < nv; j++)
3702 if (vmark[el.
node[j]]) { hit =
true;
break; }
3709 if (neighbor_set) { (*neighbor_set)[i] = 1; }
3715 static bool sorted_lists_intersect(
const int*
a,
const int*
b,
int na,
int nb)
3718 const int *
const a_end =
a + na;
3719 const int *
const b_end =
b + nb;
3720 while (
a != a_end &&
b != b_end)
3758 while (stack.
Size())
3767 for (
int i = 0; i < nv; i++)
3773 for (
int i = 0; i < nv; i++)
3791 int nv1 = vert.
Size();
3796 for (
int i = 0; i < search_set->
Size(); i++)
3798 int testme = (*search_set)[i];
3805 bool hit = sorted_lists_intersect(v1, v2, nv1, nv2);
3810 for (
int j = 0; j < nv; j++)
3812 hit = sorted_lists_intersect(&el.
node[j], v1, 1, nv1);
3817 if (hit) { neighbors.
Append(testme); }
3831 for (
int i = 0; i < elems.
Size(); i++)
3837 for (
int j = 0; j < nv; j++)
3843 for (
int j = 0; j < nv; j++)
3845 vmark[el.
node[j]] = 1;
3855 for (
int i = 0; i < search_set->
Size(); i++)
3857 int testme = (*search_set)[i];
3863 for (
int j = 0; j < nv; j++)
3865 if (vmark[v[j]]) { hit =
true;
break; }
3871 for (
int j = 0; j < nv; j++)
3873 if (vmark[el.
node[j]]) { hit =
true;
break; }
3877 if (hit) { expanded.
Append(testme); }
3886 if (el.
parent < 0) {
return elem; }
3889 MFEM_ASSERT(pa.
ref_type,
"internal error");
3895 MFEM_ASSERT(geom_parent[el.
Geom()],
"unsupported geometry");
3896 const RefTrf &tr = geom_parent[el.
Geom()][(int) pa.
ref_type][ch];
3897 tr.Apply(coord, coord);
3908 return (pt[0] >= 0) && (pt[0] <= T_ONE) &&
3909 (pt[1] >= 0) && (pt[1] <= T_ONE);
3912 return (pt[0] >= 0) && (pt[0] <= T_ONE) &&
3913 (pt[1] >= 0) && (pt[1] <= T_ONE) &&
3914 (pt[2] >= 0) && (pt[2] <= T_ONE);
3917 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <= T_ONE);
3920 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <= T_ONE) &&
3921 (pt[2] >= 0) && (pt[2] <= T_ONE);
3924 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[2] >= 0.0) &&
3925 (pt[0] + pt[2] <= T_ONE) && (pt[1] + pt[2] <= T_ONE) &&
3929 MFEM_ABORT(
"unsupported geometry");
3947 const RefTrf &tr = geom_child[el.
Geom()][(int) el.
ref_type][ch];
3948 tr.Apply(coord, tcoord);
3950 if (RefPointInside(el.
Geom(), tcoord))
3962 MFEM_ASSERT(geom_corners[el.
Geom()],
"unsupported geometry");
3963 std::memcpy(coord, geom_corners[el.
Geom()][local],
sizeof(coord));
3976 MFEM_ASSERT(np == pm.
np,
"");
3977 for (
int i = 0; i < np; i++)
3980 for (
int j = 0; j < points[i].dim; j++)
3982 if (points[i].coord[j] != pm.
points[i].
coord[j]) {
return false; }
3991 for (
int i = 0; i < np; i++)
3993 for (
int j = 0; j < points[0].dim; j++)
3995 point_matrix(j, i) = points[i].coord[j];
4010 Point(0, 0, 0),
Point(1, 0, 0),
Point(0, 1, 0),
Point(0, 0, 1)
4021 Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
4022 Point(0, 0, 1),
Point(1, 0, 1),
Point(1, 1, 1),
Point(0, 1, 1)
4037 MFEM_ABORT(
"unsupported geometry " << geom);
4049 int ref_type = *ref_path++;
4050 int child = *ref_path++;
4058 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4059 Point mid67(pm(6), pm(7)), mid45(pm(4), pm(5));
4064 pm(4), mid45, mid67, pm(7));
4066 else if (child == 1)
4069 mid45, pm(5), pm(6), mid67);
4072 else if (ref_type == 2)
4074 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4075 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
4080 pm(4), pm(5), mid56, mid74);
4082 else if (child == 1)
4085 mid74, mid56, pm(6), pm(7));
4088 else if (ref_type == 4)
4090 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4091 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4096 mid04, mid15, mid26, mid37);
4098 else if (child == 1)
4101 pm(4), pm(5), pm(6), pm(7));
4104 else if (ref_type == 3)
4106 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4107 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4108 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
4109 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
4111 Point midf0(mid23, mid12, mid01, mid30);
4112 Point midf5(mid45, mid56, mid67, mid74);
4117 pm(4), mid45, midf5, mid74);
4119 else if (child == 1)
4122 mid45, pm(5), mid56, midf5);
4124 else if (child == 2)
4127 midf5, mid56, pm(6), mid67);
4129 else if (child == 3)
4132 mid74, midf5, mid67, pm(7));
4135 else if (ref_type == 5)
4137 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4138 Point mid45(pm(4), pm(5)), mid67(pm(6), pm(7));
4139 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4140 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4142 Point midf1(mid01, mid15, mid45, mid04);
4143 Point midf3(mid23, mid37, mid67, mid26);
4148 mid04, midf1, midf3, mid37);
4150 else if (child == 1)
4153 midf1, mid15, mid26, midf3);
4155 else if (child == 2)
4158 mid45, pm(5), pm(6), mid67);
4160 else if (child == 3)
4163 pm(4), mid45, mid67, pm(7));
4166 else if (ref_type == 6)
4168 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4169 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
4170 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4171 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4173 Point midf2(mid12, mid26, mid56, mid15);
4174 Point midf4(mid30, mid04, mid74, mid37);
4179 mid04, mid15, midf2, midf4);
4181 else if (child == 1)
4184 midf4, midf2, mid26, mid37);
4186 else if (child == 2)
4189 pm(4), pm(5), mid56, mid74);
4191 else if (child == 3)
4194 mid74, mid56, pm(6), pm(7));
4197 else if (ref_type == 7)
4199 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4200 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4201 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
4202 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
4203 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4204 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4206 Point midf0(mid23, mid12, mid01, mid30);
4207 Point midf1(mid01, mid15, mid45, mid04);
4208 Point midf2(mid12, mid26, mid56, mid15);
4209 Point midf3(mid23, mid37, mid67, mid26);
4210 Point midf4(mid30, mid04, mid74, mid37);
4211 Point midf5(mid45, mid56, mid67, mid74);
4213 Point midel(midf1, midf3);
4218 mid04, midf1, midel, midf4);
4220 else if (child == 1)
4223 midf1, mid15, midf2, midel);
4225 else if (child == 2)
4228 midel, midf2, mid26, midf3);
4230 else if (child == 3)
4233 midf4, midel, midf3, mid37);
4235 else if (child == 4)
4238 pm(4), mid45, midf5, mid74);
4240 else if (child == 5)
4243 mid45, pm(5), mid56, midf5);
4245 else if (child == 6)
4248 midf5, mid56, pm(6), mid67);
4250 else if (child == 7)
4253 mid74, midf5, mid67, pm(7));
4261 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4262 Point mid20(pm(2), pm(0)), mid34(pm(3), pm(4));
4263 Point mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
4267 pm =
PointMatrix(pm(0), mid01, mid20, pm(3), mid34, mid53);
4269 else if (child == 1)
4271 pm =
PointMatrix(mid01, pm(1), mid12, mid34, pm(4), mid45);
4273 else if (child == 2)
4275 pm =
PointMatrix(mid20, mid12, pm(2), mid53, mid45, pm(5));
4277 else if (child == 3)
4279 pm =
PointMatrix(mid12, mid20, mid01, mid45, mid53, mid34);
4282 else if (ref_type == 4)
4284 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
4288 pm =
PointMatrix(pm(0), pm(1), pm(2), mid03, mid14, mid25);
4290 else if (child == 1)
4292 pm =
PointMatrix(mid03, mid14, mid25, pm(3), pm(4), pm(5));
4297 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
4298 Point mid34(pm(3), pm(4)), mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
4299 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
4301 Point midf2(mid01, mid14, mid34, mid03);
4302 Point midf3(mid12, mid25, mid45, mid14);
4303 Point midf4(mid20, mid03, mid53, mid25);
4307 pm =
PointMatrix(pm(0), mid01, mid20, mid03, midf2, midf4);
4309 else if (child == 1)
4311 pm =
PointMatrix(mid01, pm(1), mid12, midf2, mid14, midf3);
4313 else if (child == 2)
4315 pm =
PointMatrix(mid20, mid12, pm(2), midf4, midf3, mid25);
4317 else if (child == 3)
4319 pm =
PointMatrix(mid12, mid20, mid01, midf3, midf4, midf2);
4321 else if (child == 4)
4323 pm =
PointMatrix(mid03, midf2, midf4, pm(3), mid34, mid53);
4325 else if (child == 5)
4327 pm =
PointMatrix(midf2, mid14, midf3, mid34, pm(4), mid45);
4329 else if (child == 6)
4331 pm =
PointMatrix(midf4, midf3, mid25, mid53, mid45, pm(5));
4333 else if (child == 7)
4335 pm =
PointMatrix(midf3, midf4, midf2, mid45, mid53, mid34);
4341 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4342 Point mid03(pm(0), pm(3)), mid12(pm(1), pm(2));
4343 Point mid04(pm(0), pm(4)), mid14(pm(1), pm(4));
4344 Point mid24(pm(2), pm(4)), mid34(pm(3), pm(4));
4345 Point midf0(mid23, mid12, mid01, mid03);
4349 pm =
PointMatrix(pm(0), mid01, midf0, mid03, mid04);
4351 else if (child == 1)
4353 pm =
PointMatrix(mid01, pm(1), mid12, midf0, mid14);
4355 else if (child == 2)
4357 pm =
PointMatrix(midf0, mid12, pm(2), mid23, mid24);
4359 else if (child == 3)
4361 pm =
PointMatrix(mid03, midf0, mid23, pm(3), mid34);
4363 else if (child == 4)
4365 pm =
PointMatrix(mid24, mid14, mid04, mid34, midf0);
4367 else if (child == 5)
4369 pm =
PointMatrix(mid04, mid14, mid24, mid34, pm(4));
4371 else if (child == 6)
4375 else if (child == 7)
4379 else if (child == 8)
4383 else if (child == 9)
4390 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid02(pm(2), pm(0));
4391 Point mid03(pm(0), pm(3)), mid13(pm(1), pm(3)), mid23(pm(2), pm(3));
4397 else if (child == 1)
4401 else if (child == 2)
4405 else if (child == 3)
4409 else if (child == 4)
4413 else if (child == 5)
4417 else if (child == 6)
4421 else if (child == 7)
4430 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4436 else if (child == 1)
4441 else if (ref_type == 2)
4443 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4449 else if (child == 1)
4454 else if (ref_type == 3)
4456 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4457 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4458 Point midel(mid01, mid23);
4464 else if (child == 1)
4468 else if (child == 2)
4472 else if (child == 3)
4480 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
4486 else if (child == 1)
4490 else if (child == 2)
4494 else if (child == 3)
4501 Point mid01(pm(0), pm(1));
4507 else if (child == 1)
4515 for (
int i = 0; i < pm.
np; i++)
4517 for (
int j = 0; j < pm(i).dim; j++)
4519 matrix(j, i) = pm(i).coord[j];
4544 int &matrix = map[ref_path];
4545 if (!matrix) { matrix = map.size(); }
4548 emb.
parent = coarse_index;
4555 MFEM_ASSERT(el.
tet_type == 0,
"not implemented");
4558 ref_path.push_back(0);
4562 if (el.
child[i] >= 0)
4564 ref_path[ref_path.length()-1] = i;
4568 ref_path.resize(ref_path.length()-2);
4575 "GetRefinementTransforms() must be preceded by MarkCoarseLevel()" 4583 std::string ref_path;
4584 ref_path.reserve(100);
4589 path_map[g][ref_path] = 1;
4597 used_geoms |= (1 << geom);
4602 if (used_geoms & (1 << g))
4611 RefPathMap::iterator it;
4612 for (it = path_map[g].begin(); it != path_map[g].end(); ++it)
4626 "GetDerefinementTransforms() must be preceded by Derefine().");
4643 int &matrix = mat_no[emb.
geom][code];
4644 if (!matrix) { matrix = mat_no[emb.
geom].size(); }
4652 if (
Geoms & (1 << g))
4661 for (
auto it = mat_no[geom].begin(); it != mat_no[geom].end(); ++it)
4663 char path[3] = { 0, 0, 0 };
4665 int code = it->first;
4668 path[0] = code >> 4;
4669 path[1] = code & 0xf;
4682 bool want_ghosts)
const 4685 conn.
Reserve(embeddings.Size());
4687 int max_parent = -1;
4688 for (
int i = 0; i < embeddings.Size(); i++)
4692 (!emb.
ghost || want_ghosts))
4695 max_parent = std::max(emb.
parent, max_parent);
4713 point_matrices[i].SetSize(0, 0, 0);
4715 embeddings.DeleteAll();
4723 if (point_matrices[i].SizeK()) {
return true; }
4732 a.point_matrices[g].Swap(
b.point_matrices[g]);
4734 Swap(
a.embeddings,
b.embeddings);
4740 static int sgn(
int x)
4742 return (x < 0) ? -1 : (x > 0) ? 1 : 0;
4745 static void HilbertSfc2D(
int x,
int y,
int ax,
int ay,
int bx,
int by,
4748 int w = std::abs(ax + ay);
4749 int h = std::abs(bx + by);
4751 int dax = sgn(ax), day = sgn(ay);
4752 int dbx = sgn(bx), dby = sgn(by);
4756 for (
int i = 0; i < w; i++, x += dax, y += day)
4765 for (
int i = 0; i < h; i++, x += dbx, y += dby)
4773 int ax2 = ax/2, ay2 = ay/2;
4774 int bx2 = bx/2, by2 = by/2;
4776 int w2 = std::abs(ax2 + ay2);
4777 int h2 = std::abs(bx2 + by2);
4781 if ((w2 & 0x1) && (w > 2))
4783 ax2 += dax, ay2 += day;
4786 HilbertSfc2D(x, y, ax2, ay2, bx, by, coords);
4787 HilbertSfc2D(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by, coords);
4791 if ((h2 & 0x1) && (h > 2))
4793 bx2 += dbx, by2 += dby;
4796 HilbertSfc2D(x, y, bx2, by2, ax2, ay2, coords);
4797 HilbertSfc2D(x+bx2, y+by2, ax, ay, bx-bx2, by-by2, coords);
4798 HilbertSfc2D(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
4799 -bx2, -by2, -(ax-ax2), -(ay-ay2), coords);
4803 static void HilbertSfc3D(
int x,
int y,
int z,
4804 int ax,
int ay,
int az,
4805 int bx,
int by,
int bz,
4806 int cx,
int cy,
int cz,
4809 int w = std::abs(ax + ay + az);
4810 int h = std::abs(bx + by + bz);
4811 int d = std::abs(cx + cy + cz);
4813 int dax = sgn(ax), day = sgn(ay), daz = sgn(az);
4814 int dbx = sgn(bx), dby = sgn(by), dbz = sgn(bz);
4815 int dcx = sgn(cx), dcy = sgn(cy), dcz = sgn(cz);
4818 if (h == 1 && d == 1)
4820 for (
int i = 0; i < w; i++, x += dax, y += day, z += daz)
4828 if (w == 1 && d == 1)
4830 for (
int i = 0; i < h; i++, x += dbx, y += dby, z += dbz)
4838 if (w == 1 && h == 1)
4840 for (
int i = 0; i < d; i++, x += dcx, y += dcy, z += dcz)
4849 int ax2 = ax/2, ay2 = ay/2, az2 = az/2;
4850 int bx2 = bx/2, by2 = by/2, bz2 = bz/2;
4851 int cx2 = cx/2, cy2 = cy/2, cz2 = cz/2;
4853 int w2 = std::abs(ax2 + ay2 + az2);
4854 int h2 = std::abs(bx2 + by2 + bz2);
4855 int d2 = std::abs(cx2 + cy2 + cz2);
4858 if ((w2 & 0x1) && (w > 2))
4860 ax2 += dax, ay2 += day, az2 += daz;
4862 if ((h2 & 0x1) && (h > 2))
4864 bx2 += dbx, by2 += dby, bz2 += dbz;
4866 if ((d2 & 0x1) && (d > 2))
4868 cx2 += dcx, cy2 += dcy, cz2 += dcz;
4872 if ((2*w > 3*h) && (2*w > 3*d))
4874 HilbertSfc3D(x, y, z,
4877 cx, cy, cz, coords);
4879 HilbertSfc3D(x+ax2, y+ay2, z+az2,
4880 ax-ax2, ay-ay2, az-az2,
4882 cx, cy, cz, coords);
4887 HilbertSfc3D(x, y, z,
4890 ax2, ay2, az2, coords);
4892 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4894 bx-bx2, by-by2, bz-bz2,
4895 cx, cy, cz, coords);
4897 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4898 y+(ay-day)+(by2-dby),
4899 z+(az-daz)+(bz2-dbz),
4902 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4907 HilbertSfc3D(x, y, z,
4910 bx, by, bz, coords);
4912 HilbertSfc3D(x+cx2, y+cy2, z+cz2,
4915 cx-cx2, cy-cy2, cz-cz2, coords);
4917 HilbertSfc3D(x+(ax-dax)+(cx2-dcx),
4918 y+(ay-day)+(cy2-dcy),
4919 z+(az-daz)+(cz2-dcz),
4921 -(ax-ax2), -(ay-ay2), -(az-az2),
4922 bx, by, bz, coords);
4927 HilbertSfc3D(x, y, z,
4930 ax2, ay2, az2, coords);
4932 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4935 bx-bx2, by-by2, bz-bz2, coords);
4937 HilbertSfc3D(x+(bx2-dbx)+(cx-dcx),
4938 y+(by2-dby)+(cy-dcy),
4939 z+(bz2-dbz)+(cz-dcz),
4942 -(cx-cx2), -(cy-cy2), -(cz-cz2), coords);
4944 HilbertSfc3D(x+(ax-dax)+bx2+(cx-dcx),
4945 y+(ay-day)+by2+(cy-dcy),
4946 z+(az-daz)+bz2+(cz-dcz),
4948 -(ax-ax2), -(ay-ay2), -(az-az2),
4949 bx-bx2, by-by2, bz-bz2, coords);
4951 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4952 y+(ay-day)+(by2-dby),
4953 z+(az-daz)+(bz2-dbz),
4956 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4963 coords.
Reserve(2*width*height);
4965 if (width >= height)
4967 HilbertSfc2D(0, 0, width, 0, 0, height, coords);
4971 HilbertSfc2D(0, 0, 0, height, width, 0, coords);
4979 coords.
Reserve(3*width*height*depth);
4981 if (width >= height && width >= depth)
4983 HilbertSfc3D(0, 0, 0,
4986 0, 0, depth, coords);
4988 else if (height >= width && height >= depth)
4990 HilbertSfc3D(0, 0, 0,
4993 0, 0, depth, coords);
4997 HilbertSfc3D(0, 0, 0,
5000 0, height, 0, coords);
5008 bool oriented)
const 5012 const int* ev = gi.
edges[(int) edge_id.
local];
5014 int n0 = el.
node[ev[0]], n1 = el.
node[ev[1]];
5015 if (n0 > n1) { std::swap(n0, n1); }
5017 vert_index[0] =
nodes[n0].vert_index;
5018 vert_index[1] =
nodes[n1].vert_index;
5020 if (oriented && vert_index[0] > vert_index[1])
5022 std::swap(vert_index[0], vert_index[1]);
5030 const int* ev = gi.
edges[(int) edge_id.
local];
5032 int v0 =
nodes[el.
node[ev[0]]].vert_index;
5033 int v1 =
nodes[el.
node[ev[1]]].vert_index;
5035 return ((v0 < v1 && ev[0] > ev[1]) || (v0 > v1 && ev[0] < ev[1])) ? -1 : 1;
5039 int vert_index[4],
int edge_index[4],
5040 int edge_orientation[4])
const 5042 MFEM_ASSERT(
Dim >= 3,
"");
5047 const int *fv = gi.
faces[(int) face_id.
local];
5048 const int nfv = gi.
nfv[(
int) face_id.
local];
5050 vert_index[3] = edge_index[3] = -1;
5051 edge_orientation[3] = 0;
5053 for (
int i = 0; i < nfv; i++)
5055 vert_index[i] =
nodes[el.
node[fv[i]]].vert_index;
5058 for (
int i = 0; i < nfv; i++)
5061 if (j >= nfv) { j = 0; }
5063 int n1 = el.
node[fv[i]];
5064 int n2 = el.
node[fv[j]];
5067 MFEM_ASSERT(en != NULL,
"edge not found.");
5070 edge_orientation[i] = (vert_index[i] < vert_index[j]) ? 1 : -1;
5078 MFEM_ASSERT(node >= 0,
"edge node not found.");
5081 int p1 = nd.
p1, p2 = nd.
p2;
5082 MFEM_ASSERT(p1 != p2,
"invalid edge node.");
5086 int n1p1 = n1.
p1, n1p2 = n1.
p2;
5087 int n2p1 = n2.p1, n2p2 = n2.p2;
5089 if ((n2p1 != n2p2) && (p1 == n2p1 || p1 == n2p2))
5093 if (n2.HasEdge()) {
return p2; }
5097 if ((n1p1 != n1p2) && (p2 == n1p1 || p2 == n1p2))
5101 if (n1.
HasEdge()) {
return p1; }
5111 MFEM_ASSERT(node >= 0 &&
nodes[node].HasEdge(),
"(v1, v2) is not an edge.");
5114 return (master >= 0) ?
nodes[master].edge_index : -1;
5120 int depth = 0, parent;
5121 while ((parent =
elements[elem].parent) != -1)
5132 int parent, reduction = 1;
5133 while ((parent =
elements[elem].parent) != -1)
5135 if (
elements[parent].ref_type & 1) { reduction *= 2; }
5136 if (
elements[parent].ref_type & 2) { reduction *= 2; }
5137 if (
elements[parent].ref_type & 4) { reduction *= 2; }
5153 for (
int i = 0; i < gi.
nf; i++)
5155 const int* fv = gi.
faces[i];
5158 MFEM_ASSERT(face,
"face not found");
5159 face_indices[i] = face->
index;
5171 int elem = fa.
elem[0];
5172 if (elem < 0) { elem = fa.
elem[1]; }
5173 MFEM_ASSERT(elem >= 0,
"Face has no elements?");
5182 for (
int i = 0; i < 4; i++)
5184 node[i] = el.
node[fv[i]];
5201 if (bdr_attr_is_ess[
faces[face].attribute - 1])
5205 int nfv = (node[3] < 0) ? 3 : 4;
5207 for (
int j = 0; j < nfv; j++)
5211 int enode =
nodes.FindId(node[j], node[(j+1) % nfv]);
5212 MFEM_ASSERT(enode >= 0 &&
nodes[enode].HasEdge(),
"Edge not found.");
5241 bdr_vertices.
Sort();
5248 static int max4(
int a,
int b,
int c,
int d)
5250 return std::max(std::max(
a,
b), std::max(c, d));
5252 static int max6(
int a,
int b,
int c,
int d,
int e,
int f)
5254 return std::max(max4(
a,
b, c, d), std::max(e,
f));
5256 static int max8(
int a,
int b,
int c,
int d,
int e,
int f,
int g,
int h)
5258 return std::max(max4(
a,
b, c, d), max4(e,
f, g, h));
5263 int mid =
nodes.FindId(vn1, vn2);
5264 if (mid < 0 || !
nodes[mid].HasVertex()) {
return 0; }
5272 faces.FindId(vn1, vn2, vn3) < 0)
5286 int& h_level,
int& v_level)
const 5288 int hl1, hl2, vl1, vl2;
5294 h_level = v_level = 0;
5300 h_level = std::max(hl1, hl2);
5301 v_level = std::max(vl1, vl2) + 1;
5307 h_level = std::max(hl1, hl2) + 1;
5308 v_level = std::max(vl1, vl2);
5315 const int* node = el.
node;
5319 for (
int i = 0; i < gi.
ne; i++)
5321 const int* ev = gi.
edges[i];
5328 for (
int i = 0; i < gi.
nf; i++)
5330 const int* fv = gi.
faces[i];
5334 node[fv[2]], node[fv[3]],
5335 flevel[i][1], flevel[i][0]);
5348 splits[0] = max8(flevel[0][0], flevel[1][0], flevel[3][0], flevel[5][0],
5349 elevel[0], elevel[2], elevel[4], elevel[6]);
5351 splits[1] = max8(flevel[0][1], flevel[2][0], flevel[4][0], flevel[5][1],
5352 elevel[1], elevel[3], elevel[5], elevel[7]);
5354 splits[2] = max8(flevel[1][1], flevel[2][1], flevel[3][1], flevel[4][1],
5355 elevel[8], elevel[9], elevel[10], elevel[11]);
5359 splits[0] = splits[1] =
5361 max6(flevel[0][0], flevel[1][0], 0,
5362 flevel[2][0], flevel[3][0], flevel[4][0]),
5363 max6(elevel[0], elevel[1], elevel[2],
5364 elevel[3], elevel[4], elevel[5]));
5366 splits[2] = max6(flevel[2][1], flevel[3][1], flevel[4][1],
5367 elevel[6], elevel[7], elevel[8]);
5371 splits[0] = std::max(
5372 max6(flevel[0][0], flevel[1][0], 0,
5373 flevel[2][0], flevel[3][0], flevel[4][0]),
5374 max8(elevel[0], elevel[1], elevel[2],
5375 elevel[3], elevel[4], elevel[5],
5376 elevel[6], elevel[7]));
5378 splits[1] = splits[0];
5379 splits[2] = splits[0];
5383 splits[0] = std::max(
5384 max4(flevel[0][0], flevel[1][0], flevel[2][0], flevel[3][0]),
5385 max6(elevel[0], elevel[1], elevel[2],
5386 elevel[3], elevel[4], elevel[5]));
5388 splits[1] = splits[0];
5389 splits[2] = splits[0];
5393 splits[0] = std::max(elevel[0], elevel[2]);
5394 splits[1] = std::max(elevel[1], elevel[3]);
5398 splits[0] = std::max(elevel[0], std::max(elevel[1], elevel[2]));
5399 splits[1] = splits[0];
5403 MFEM_ABORT(
"Unsupported element geometry.");
5417 for (
int k = 0; k <
Dim; k++)
5419 if (splits[k] > max_level)
5421 ref_type |= (1 << k);
5439 MFEM_VERIFY(max_nc_level >= 1,
"'max_nc_level' must be 1 or greater.");
5446 if (!refinements.
Size()) {
break; }
5461 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5463 if (node->HasVertex() && node->p1 != node->p2) { nv++; }
5470 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5472 if (node->HasVertex() && node->p1 != node->p2)
5474 MFEM_ASSERT(
nodes[node->p1].HasVertex(),
"");
5475 MFEM_ASSERT(
nodes[node->p2].HasVertex(),
"");
5477 (*os) << node.index() <<
" " << node->p1 <<
" " << node->p2 <<
"\n";
5491 input >>
id >> p1 >> p2;
5492 MFEM_VERIFY(input,
"problem reading vertex parents.");
5494 MFEM_VERIFY(
nodes.IdExists(
id),
"vertex " <<
id <<
" not found.");
5495 MFEM_VERIFY(
nodes.IdExists(p1),
"parent " << p1 <<
" not found.");
5496 MFEM_VERIFY(
nodes.IdExists(p2),
"parent " << p2 <<
" not found.");
5498 int check =
nodes.FindId(p1, p2);
5499 MFEM_VERIFY(check < 0,
"parents (" << p1 <<
", " << p2 <<
") already " 5500 "assigned to node " << check);
5503 nodes.Reparent(
id, p1, p2);
5509 static const int nfv2geom[5] =
5514 int deg = (
Dim == 2) ? 2 : 1;
5517 for (
int i = 0; i <
elements.Size(); i++)
5520 if (!el.
IsLeaf()) {
continue; }
5523 for (
int k = 0; k < gi.
nf; k++)
5525 const int* fv = gi.
faces[k];
5526 const int nfv = gi.
nfv[k];
5529 MFEM_ASSERT(face != NULL,
"face not found");
5532 if (!os) { count++;
continue; }
5534 (*os) << face->
attribute <<
" " << nfv2geom[nfv];
5535 for (
int j = 0; j < nfv; j++)
5537 (*os) <<
" " << el.
node[fv[j*deg]];
5550 for (
int i = 0; i < nb; i++)
5552 input >> attr >> geom;
5557 input >> v1 >> v2 >> v3 >> v4;
5563 input >> v1 >> v2 >> v3;
5581 MFEM_ABORT(
"unsupported boundary element geometry: " << geom);
5590 if (!nv) {
return; }
5593 for (
int i = 0; i < nv; i++)
5608 if (!nv) {
return; }
5615 for (
int i = 0; i < nv; i++)
5620 MFEM_VERIFY(input.good(),
"unexpected EOF");
5636 os <<
"MFEM NC mesh v1.0\n\n" 5637 "# NCMesh supported geometry types:\n" 5641 "# TETRAHEDRON = 4\n" 5646 os <<
"\ndimension\n" <<
Dim <<
"\n";
5648 #ifndef MFEM_USE_MPI 5652 os <<
"\nrank\n" <<
MyRank <<
"\n";
5655 os <<
"\n# rank attr geom ref_type nodes/children";
5656 os <<
"\nelements\n" <<
elements.Size() <<
"\n";
5658 for (
int i = 0; i <
elements.Size(); i++)
5662 if (el.
parent == -2) { os <<
"-1\n";
continue; }
5667 os <<
" " << el.
node[j];
5675 os <<
"\n# attr geom nodes";
5676 os <<
"\nboundary\n" << nb <<
"\n";
5684 os <<
"\n# vert_id p1 p2";
5685 os <<
"\nvertex_parents\n" << nvp <<
"\n";
5692 os <<
"\n# root element orientation";
5703 os <<
"\n# top-level node coordinates";
5704 os <<
"\ncoordinates\n";
5717 for (
int i = 0; i <
elements.Size(); i++)
5724 int child = el.
child[j];
5725 MFEM_VERIFY(child <
elements.Size(),
"invalid mesh file: " 5726 "element " << i <<
" references invalid child " << child);
5739 MFEM_VERIFY(nroots,
"invalid mesh file: no root elements found.");
5742 for (
int i = nroots; i <
elements.Size(); i++)
5744 MFEM_VERIFY(
elements[i].parent != -1,
5745 "invalid mesh file: only the first M elements can be roots. " 5746 "Found element " << i <<
" with no parent.");
5757 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5759 if (node->p1 == node->p2) { ntop = node.index() + 1; }
5775 MFEM_ASSERT(version == 10,
"");
5782 MFEM_VERIFY(ident ==
"dimension",
"Invalid mesh file: " << ident);
5788 if (ident ==
"rank")
5791 MFEM_VERIFY(
MyRank >= 0,
"Invalid rank");
5798 if (ident ==
"sfc_version")
5801 input >> sfc_version;
5802 MFEM_VERIFY(sfc_version == 0,
5803 "Unsupported mesh file SFC version (" << sfc_version <<
"). " 5804 "Please update MFEM.");
5811 MFEM_VERIFY(ident ==
"elements",
"Invalid mesh file: " << ident);
5813 for (
int i = 0; i < count; i++)
5815 int rank, attr, geom, ref_type;
5816 input >> rank >> attr >> geom;
5821 MFEM_ASSERT(
elements.Size() == i+1,
"");
5827 CheckSupportedGeom(type);
5831 MFEM_VERIFY(ref_type >= 0 && ref_type < 8,
"");
5832 el.ref_type = ref_type;
5836 for (
int j = 0; j < ref_type_num_children[ref_type]; j++)
5838 input >> el.child[j];
5840 if (
Dim == 3 && ref_type != 7) {
Iso =
false; }
5844 for (
int j = 0; j <
GI[geom].
nv; j++)
5849 nodes.Alloc(
id,
id,
id);
5869 if (ident ==
"boundary")
5878 if (ident ==
"vertex_parents")
5887 if (ident ==
"root_state")
5891 for (
int i = 0; i < count; i++)
5901 if (ident ==
"coordinates")
5906 "Invalid mesh file: not all top-level nodes are covered by " 5907 "the 'coordinates' section of the mesh file.");
5910 else if (ident ==
"nodes")
5920 MFEM_ABORT(
"Invalid mesh file: either 'coordinates' or " 5921 "'nodes' must be present");
5925 nodes.UpdateUnused();
5926 for (
int i = 0; i <
elements.Size(); i++)
5946 int old_id = el.
child[i];
5948 int new_id =
elements.Append(tmp_elements[old_id]);
5949 el.
child[i] = new_id;
5973 if (
Dim == 3 && ref_type != 7) { iso =
false; }
5976 int nch = ref_type_num_children[ref_type];
5977 for (
int i = 0,
id; i < nch; i++)
5980 MFEM_VERIFY(
id >= 0,
"");
5982 "coarse element cannot be referenced before it is " 5983 "defined (id=" <<
id <<
").");
5986 MFEM_VERIFY(child.parent == -1,
5987 "element " <<
id <<
" cannot have two parents.");
5990 child.parent = elem;
5994 el.
geom = child.geom;
6006 for (
auto el = tmp_elements.
begin(); el != tmp_elements.
end(); ++el)
6008 if (el->parent == -1)
6016 for (
int i = 0; i < root_count; i++)
6029 MFEM_ASSERT(
elements.Size() == 0,
"");
6030 MFEM_ASSERT(
nodes.Size() == 0,
"");
6034 int count, attr, geom;
6039 MFEM_VERIFY(ident ==
"dimension",
"invalid mesh file");
6045 MFEM_VERIFY(ident ==
"elements",
"invalid mesh file");
6048 for (
int i = 0; i < count; i++)
6050 input >> attr >> geom;
6053 CheckSupportedGeom(type);
6057 MFEM_ASSERT(eid == i,
"");
6060 for (
int j = 0; j <
GI[geom].
nv; j++)
6065 nodes.Alloc(
id,
id,
id);
6073 MFEM_VERIFY(ident ==
"boundary",
"invalid mesh file");
6080 if (ident ==
"vertex_parents")
6096 if (ident ==
"coarse_elements")
6111 MFEM_VERIFY(ident ==
"vertices",
"invalid mesh file");
6114 input >> std::ws >> ident;
6115 if (ident !=
"nodes")
6122 for (
int i = 0; i < nvert; i++)
6127 MFEM_VERIFY(input.good(),
"unexpected EOF");
6148 nodes.UpdateUnused();
6150 for (
int i = 0; i <
elements.Size(); i++)
6162 file_leaf_elements = -1;
6163 for (
int i = 0; i <
elements.Size(); i++)
6167 file_leaf_elements[
elements[i].index] = i;
6170 MFEM_ASSERT(file_leaf_elements.
Min() >= 0,
"");
6191 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
6193 if (node->HasVertex())
6195 MFEM_ASSERT(node.index() >= 0,
"");
6196 MFEM_ASSERT(node.index() < order.
Size(),
"");
6197 MFEM_ASSERT(order[node.index()] == -1,
"");
6199 order[node.index()] = node->vert_index;
6203 MFEM_ASSERT(count == order.
Size(),
"");
6204 MFEM_CONTRACT_VAR(count);
6245 long mem = embeddings.MemoryUsage();
6248 mem += point_matrices[i].MemoryUsage();
6255 return nodes.MemoryUsage() +
6256 faces.MemoryUsage() +
6293 <<
ref_stack.MemoryUsage() <<
" ref_stack\n" 6297 <<
sizeof(*this) <<
" NCMesh" 6310 for (
int j = 0; j <
Dim; j++)
6316 if (elem->
node[k] >= 0)
6322 os << sum / count <<
" ";
6333 os <<
nodes.Size() <<
"\n";
6334 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
6337 os << node.index() <<
" " 6338 << pos[0] <<
" " << pos[1] <<
" " << pos[2] <<
" " 6339 << node->p1 <<
" " << node->p2 <<
" " 6340 << node->vert_index <<
" " << node->edge_index <<
" " 6348 for (
int i = 0; i <
elements.Size(); i++)
6350 if (
elements[i].IsLeaf()) { nleaves++; }
6352 os << nleaves <<
"\n";
6353 for (
int i = 0; i <
elements.Size(); i++)
6360 for (
int j = 0; j < gi.
nv; j++)
6362 os << el.
node[j] <<
" ";
6370 os <<
faces.Size() <<
"\n";
6371 for (
auto face =
faces.cbegin(); face !=
faces.cend(); ++face)
6373 int elem = face->elem[0];
6374 if (elem < 0) { elem = face->elem[1]; }
6375 MFEM_ASSERT(elem >= 0,
"");
6387 for (
int i = 0; i < nfv; i++)
6389 os <<
" " << el.
node[fv[i]];
NCList face_list
lazy-initialized list of faces, see GetFaceList
bool CubeFaceTop(int node, int *n)
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
The PointMatrix stores the coordinates of the slave face using the master face coordinate as referenc...
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void DebugDump(std::ostream &out) const
bool TriFaceSplit(int v1, int v2, int v3, int mid[3]=NULL) const
int PrintBoundary(std::ostream *out) const
void LoadLegacyFormat(std::istream &input, int &curved, int &is_nc)
Load the deprecated MFEM mesh v1.1 format for backward compatibility.
Table * GetEdgeVertexTable() const
static void GridSfcOrdering3D(int width, int height, int depth, Array< int > &coords)
int faces[MaxElemFaces][4]
void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4, const Refinement *refs, int nref)
void Print(std::ostream &out) const
I/O: Print the mesh in "MFEM NC mesh v1.0" format.
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
void DebugLeafOrder(std::ostream &out) const
static void GridSfcOrdering2D(int width, int height, Array< int > &coords)
int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
bool CubeFaceLeft(int node, int *n)
static PointMatrix pm_seg_identity
void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
int elem[2]
up to 2 elements sharing the face
char ref_type
refinement XYZ bit mask (7 = full isotropic)
bool ZeroRootStates() const
Return true if all root_states are zero.
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T...
int GetEdgeMaster(int v1, int v2) const
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
void FreeElement(Element *E)
const CoarseFineTransformations & GetDerefinementTransforms()
int child[MaxElemChildren]
2-10 children (if ref_type != 0)
void FindVertexCousins(int elem, int local, Array< int > &cousins) const
void FindEdgeElements(int vn1, int vn2, int vn3, int vn4, Array< MeshId > &prisms) const
virtual int GetNEdges() const =0
void OrientedPointMatrix(const Slave &slave, DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
This holds in one place the constants about the geometries we support.
int GetVertexRootCoord(int elem, RefCoord coord[3]) const
Array< Triple< int, int, int > > reparents
scheduled node reparents (tmp)
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
Array< Element * > boundary
void CollectTriFaceVertices(int v0, int v1, int v2, Array< int > &indices)
char tet_type
tetrahedron split type, currently always 0
int Dimension() const
Dimension of the reference space used within the elements.
int NewSegment(int n0, int n1, int attr, int vattr1, int vattr2)
virtual void LimitNCLevel(int max_nc_level)
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
virtual void Trim()
Save memory by releasing all non-essential and cached data.
int index
element number in the Mesh, -1 if refined
void LegacyToNewVertexOrdering(Array< int > &order) const
I/O: Return a map from old (v1.1) vertex indices to new vertex indices.
void ForceRefinement(int vn1, int vn2, int vn3, int vn4)
long MemoryUsage() const
Return total number of bytes allocated.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
bool Legacy
true if the mesh was loaded from the legacy v1.1 format
int GetAttribute() const
Return element's attribute.
unsigned matrix
index into NCList::point_matrices[geom]
T * GetData()
Returns the data.
void ClearTransforms()
Free all internal data created by the above three functions.
int ReorderFacePointMat(int v0, int v1, int v2, int v3, int elem, const PointMatrix &pm, PointMatrix &reordered) const
Table derefinements
possible derefinements, see GetDerefinementTable
Data type dense matrix using column-major storage.
NCList vertex_list
lazy-initialized list of vertices, see GetVertexList
void InitDerefTransforms()
static PointMatrix pm_prism_identity
char geom
Geometry::Type of the element (char for storage only)
void InitRootState(int root_count)
int NewTetrahedron(int n0, int n1, int n2, int n3, int attr, int fattr0, int fattr1, int fattr2, int fattr3)
void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4, int mid12, int mid34, int level=0)
static PointMatrix pm_tri_identity
Geometry::Type Geom() const
int GetNEdges() const
Return the number of edges.
const Element * GetElement(int i) const
Return pointer to the i'th element object.
bool IsGhost(const Element &el) const
Return true if the Element el is a ghost element.
void CollectDerefinements(int elem, Array< Connection > &list)
Data type quadrilateral element.
void GetLimitRefinements(Array< Refinement > &refinements, int max_level)
void GetMatrix(DenseMatrix &point_matrix) const
void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags, int level, MatrixMap &matrix_map)
static const int MaxElemEdges
Number of edges of an element can have.
int spaceDim
dimensions of the elements and the vertex coordinates
Array< int > vertex_nodeId
vertex-index to node-id map, see UpdateVertices
int attribute
boundary element attribute, -1 if internal face
int GetNBE() const
Returns number of boundary elements.
void FindFaceNodes(int face, int node[4])
bool CubeFaceBack(int node, int *n)
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
static const PointMatrix & GetGeomIdentity(Geometry::Type geom)
bool HavePrisms() const
Return true if the mesh contains prism elements.
void DeleteAll()
Delete the whole array.
static int find_element_edge(const Element &el, int vn0, int vn1, bool abort=true)
int index
Mesh element number.
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
void OnMeshUpdated(Mesh *mesh)
Element * NewElement(int geom)
int NewWedge(int n0, int n1, int n2, int n3, int n4, int n5, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4)
void CollectEdgeVertices(int v0, int v1, Array< int > &indices)
void CollectLeafElements(int elem, int state, Array< int > &ghosts, int &counter)
static int find_local_face(int geom, int a, int b, int c)
std::function< double(const Vector &)> f(double mass_coeff)
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
void GetMeshComponents(Mesh &mesh) const
Fill Mesh::{vertices,elements,boundary} for the current finest level.
void ReferenceElement(int elem)
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
int GetElementDepth(int i) const
Return the distance of leaf 'i' from the root.
void GetPointMatrix(Geometry::Type geom, const char *ref_path, DenseMatrix &matrix)
void CheckIsoFace(int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, int midf)
Data type hexahedron element.
virtual int GetNFaceVertices(int fi) const =0
Face * GetFace(Element &elem, int face_no)
Data type Pyramid element.
void TraverseRefinements(int elem, int coarse_index, std::string &ref_path, RefPathMap &map)
bool CubeFaceRight(int node, int *n)
virtual const int * GetEdgeVertices(int) const =0
int GetMidEdgeNode(int node1, int node2)
Element(Geometry::Type geom, int attr)
Geometry::Type Geom() const
Geometry::Type GetGeometryType() const
int index
face number in the Mesh
const Table & GetDerefinementTable()
void MakeFromList(int nrows, const Array< Connection > &list)
Table element_vertex
leaf-element to vertex table, see FindSetNeighbors
int Append(const T &el)
Append element 'el' to array, resize if necessary.
const double * CalcVertexPos(int node) const
int AddElement(const Element &el)
void GetEdgeVertices(const MeshId &edge_id, int vert_index[2], bool oriented=true) const
Return Mesh vertex indices of an edge identified by 'edge_id'.
virtual void Derefine(const Array< int > &derefs)
std::size_t MemoryUsage() const
void FindNeighbors(int elem, Array< int > &neighbors, const Array< int > *search_set=NULL)
void InitGeom(Geometry::Type geom)
Array< int > coarse_elements
state of leaf_elements before Refine(), set by MarkCoarseLevel()
void UpdateVertices()
This method assigns indices to vertices (Node::vert_index) that will be seen by the Mesh class and th...
int FindMidEdgeNode(int node1, int node2) const
Array< DenseMatrix * > point_matrices[Geometry::NumGeom]
List of unique point matrices for each slave geometry.
void RegisterFaces(int elem, int *fattr=NULL)
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
static PointMatrix pm_pyramid_identity
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
virtual void BuildEdgeList()
int GetElementSizeReduction(int i) const
const CoarseFineTransformations & GetRefinementTransforms()
void LoadCoarseElements(std::istream &input)
Load the element refinement hierarchy from a legacy mesh file.
Identifies a vertex/edge/face in both Mesh and NCMesh.
int parent
parent element, -1 if this is a root element, -2 if free'd
virtual MFEM_DEPRECATED int GetNFaces(int &nFaceVertices) const =0
Data type triangle element.
signed char local
local number within 'element'
virtual void ElementSharesFace(int elem, int local, int face)
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
bool HaveTets() const
Return true if the mesh contains tetrahedral elements.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
void LoadCoordinates(std::istream &input)
Load the "coordinates" section of the mesh file.
virtual void ElementSharesVertex(int elem, int local, int vnode)
int MyRank
used in parallel, or when loading a parallel file in serial
bool CubeFaceFront(int node, int *n)
A class for non-conforming AMR. The class is not used directly by the user, rather it is an extension...
int EdgeSplitLevel(int vn1, int vn2) const
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
int CountTopLevelNodes() const
Return the index of the last top-level node plus one.
friend struct PointMatrixHash
virtual void GetBoundaryClosure(const Array< int > &bdr_attr_is_ess, Array< int > &bdr_vertices, Array< int > &bdr_edges)
int element
NCMesh::Element containing this vertex/edge/face.
bool PrismFaceTop(int node, int *n)
static GeomInfo GI[Geometry::NumGeom]
Data type tetrahedron element.
void ReparentNode(int node, int new_p1, int new_p2)
static const int MaxElemNodes
Number of nodes of an element can have.
int PrintMemoryDetail() const
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
Array< Triple< int, int, int > > tmp_vertex_parents
void DeleteUnusedFaces(const Array< int > &elemFaces)
bool Iso
true if the mesh only contains isotropic refinements
void Swap(Array< T > &, Array< T > &)
std::map< std::string, int > RefPathMap
int QuadFaceSplitType(int v1, int v2, int v3, int v4, int mid[5]=NULL) const
int GetFaceVerticesEdges(const MeshId &face_id, int vert_index[4], int edge_index[4], int edge_orientation[4]) const
unsigned ghost
For internal use: 0 if regular fine element, 1 if parallel ghost element.
virtual void BuildFaceList()
Nonconforming edge/face within a bigger edge/face.
void DerefineElement(int elem)
Derefine the element elem, does nothing on leaf elements.
int TriFaceSplitLevel(int vn1, int vn2, int vn3) const
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
void RegisterElement(int e)
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Array< int > leaf_sfc_index
natural tree ordering of leaf elements
bool PrismFaceBottom(int node, int *n)
void DeleteLast()
Delete the last entry of the array.
Helper struct for defining a connectivity table, see Table::MakeFromList.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void UpdateLeafElements()
Update the leaf elements indices in leaf_elements.
Array< Element * > elements
int PrintVertexParents(std::ostream *out) const
Print the "vertex_parents" section of the mesh file.
int RetrieveNode(const Element &el, int index)
Return el.node[index] correctly, even if the element is refined.
int Geoms
bit mask of element geometries present, see InitGeomFlags()
int SpaceDimension() const
Dimension of the physical space containing the mesh.
int GetNE() const
Returns number of elements.
void BuildElementToVertexTable()
void ForgetElement(int e)
static PointMatrix pm_tet_identity
int GetMidFaceNode(int en1, int en2, int en3, int en4)
void RefineElement(int elem, char ref_type)
static const int MaxElemChildren
Number of children of an element can have.
int NewHexahedron(int n0, int n1, int n2, int n3, int n4, int n5, int n6, int n7, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4, int fattr5)
void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1, MatrixMap &matrix_map)
Array< int > boundary_faces
subset of all faces, set by BuildFaceList
Array< double > coordinates
int Size() const
Returns the number of TYPE I elements.
int edges[MaxElemEdges][2]
const Element * GetFace(int i) const
Array< int > leaf_elements
finest elements, in Mesh ordering (+ ghosts)
static PointMatrix pm_quad_identity
void SetIJ(int *newI, int *newJ, int newsize=-1)
Replace the I and J arrays with the given newI and newJ arrays.
int node[MaxElemNodes]
element corners (if ref_type == 0)
Array< MeshId > conforming
unsigned edge_flags
orientation flags, see OrientedPointMatrix
Array< int > free_element_ids
bool CubeFaceBottom(int node, int *n)
void TraverseQuadFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level, Face *eface[4], MatrixMap &matrix_map)
int index(int i, int j, int nx, int ny)
bool operator==(const PointMatrix &pm) const
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
void GetElementFacesAttributes(int i, Array< int > &faces, Array< int > &fattr) const
Return the faces and face attributes of leaf element 'i'.
virtual int GetNVertices() const =0
int parent
Coarse Element index in the coarse mesh.
static PointMatrix pm_hex_identity
const MeshId & LookUp(int index, int *type=NULL) const
virtual const int * GetFaceVertices(int fi) const =0
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
int Size() const
Return the logical size of the array.
T & Last()
Return the last element in the array.
void NeighborExpand(const Array< int > &elems, Array< int > &expanded, const Array< int > *search_set=NULL)
BlockArray< Element > elements
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
void FindSetNeighbors(const Array< char > &elem_set, Array< int > *neighbors, Array< char > *neighbor_set=NULL)
mfem::Element * NewMeshElement(int geom) const
void InitRootElements()
Count root elements and initialize root_state.
int GetEdgeNCOrientation(const MeshId &edge_id) const
HashTable< Node > shadow
temporary storage for reparented nodes
virtual void BuildVertexList()
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
void UpdateElementToVertexTable()
void LoadBoundary(std::istream &input)
Load the "boundary" section of the mesh file.
int NewPyramid(int n0, int n1, int n2, int n3, int n4, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4)
void PrintCoordinates(std::ostream &out) const
Print the "coordinates" section of the mesh file.
const Element * GetBdrElement(int i) const
Return pointer to the i'th boundary element object.
void CopyElements(int elem, const BlockArray< Element > &tmp_elements)
virtual void ElementSharesEdge(int elem, int local, int enode)
int FindNodeExt(const Element &el, int node, bool abort=true)
Extended version of find_node: works if 'el' is refined.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
char ref_type
bit mask of X,Y,Z refinements (bits 0,1,2 respectively)
static const int MaxElemFaces
Number of faces of an element can have.
void CollectQuadFaceVertices(int v0, int v1, int v2, int v3, Array< int > &indices)
static int find_node(const Element &el, int node)
void UnreferenceElement(int elem, Array< int > &elemFaces)
void LoadVertexParents(std::istream &input)
Load the vertex parent hierarchy from a mesh file.
Point points[MaxElemNodes]
Abstract data type element.
void CollectIncidentElements(int elem, const RefCoord coord[3], Array< int > &list) const
Data type line segment element.
void CountSplits(int elem, int splits[3]) const
int GetSingleElement() const
Return one of elem[0] or elem[1] and make sure the other is -1.
virtual Type GetType() const =0
Returns element's type.
int rank
processor number (ParNCMesh), -1 if undefined/unknown
bool TraverseTriFace(int vn0, int vn1, int vn2, const PointMatrix &pm, int level, MatrixMap &matrix_map)
Defines the position of a fine element within a coarse element.
virtual void Refine(const Array< Refinement > &refinements)
Array< char > face_geom
face geometry by face index, set by OnMeshUpdated