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.begin(); node !=
nodes.end(); ++node)
2181 node->vert_index = -4;
2187 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2211 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
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.begin(); node !=
nodes.end(); ++node)
2313 if (node->HasVertex() && node->vert_index >= 0)
2320 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
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++)
2461 const int* node = nc_elem.
node;
2468 for (
int j = 0; j < gi.
nv; j++)
2470 elem->GetVertices()[j] =
nodes[node[j]].vert_index;
2475 for (
int k = 0; k < gi.
nf; k++)
2477 const int* fv = gi.
faces[k];
2478 const int nfv = gi.
nfv[k];
2479 const Face* face =
faces.Find(node[fv[0]], node[fv[1]],
2480 node[fv[2]], node[fv[3]]);
2489 for (
int j = 0; j < 4; j++)
2491 quad->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2499 MFEM_ASSERT(nfv == 3,
"");
2502 for (
int j = 0; j < 3; j++)
2504 tri->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2513 for (
int j = 0; j < 2; j++)
2515 segment->GetVertices()[j] =
nodes[node[fv[2*j]]].vert_index;
2524 point->GetVertices()[0] =
nodes[node[fv[0]]].vert_index;
2540 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2542 if (node->HasEdge()) { node->edge_index = -1; }
2544 for (
auto face =
faces.begin(); face !=
faces.end(); ++face)
2551 for (
int i = 0; i < edge_vertex->
Size(); i++)
2553 const int *ev = edge_vertex->
GetRow(i);
2556 MFEM_ASSERT(node && node->
HasEdge(),
2557 "edge (" << ev[0] <<
"," << ev[1] <<
") not found, " 2565 for (
int i = 0; i <
NFaces; i++)
2567 const int* fv = mesh->
GetFace(i)->GetVertices();
2568 const int nfv = mesh->
GetFace(i)->GetNVertices();
2581 MFEM_ASSERT(nfv == 3,
"");
2589 MFEM_ASSERT(nfv == 2,
"");
2592 face =
faces.Find(n0, n0, n1, n1);
2596 const int *ev = edge_vertex->
GetRow(i);
2597 MFEM_ASSERT((ev[0] == fv[0] && ev[1] == fv[1]) ||
2598 (ev[1] == fv[0] && ev[0] == fv[1]),
"");
2602 MFEM_VERIFY(face,
"face not found.");
2610 for (
auto node =
nodes.begin(); node !=
nodes.end(); ++node)
2612 if (node->HasEdge() && node->edge_index < 0)
2620 for (
auto face =
faces.begin(); face !=
faces.end(); ++face)
2643 for (
int j = 0; j < gi.
nf; j++)
2645 const int *fv = gi.
faces[j];
2648 MFEM_ASSERT(face,
"face not found!");
2650 if (face->
index < 0)
2666 for (
auto face =
faces.begin(); face !=
faces.end(); ++face)
2668 if (face->index < 0) { face->index =
NFaces + (nghosts++); }
2679 MFEM_ASSERT(
Dim >= 3,
"");
2688 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3, mid[3] = e4; }
2691 int midf1 = -1, midf2 = -1;
2696 if (midf1 >= 0 && midf1 == midf2)
2699 if (nd.
p1 != e1 && nd.
p2 != e1) { midf1 = -1; }
2700 if (nd.
p1 != e2 && nd.
p2 != e2) { midf2 = -1; }
2704 MFEM_ASSERT(!(midf1 >= 0 && midf2 >= 0),
"incorrectly split face!");
2706 if (midf1 < 0 && midf2 < 0)
2708 if (mid) { mid[4] = -1; }
2711 else if (midf1 >= 0)
2713 if (mid) { mid[4] = midf1; }
2718 if (mid) { mid[4] = midf2; }
2725 int e1 =
nodes.FindId(v1, v2);
2726 if (e1 < 0 || !
nodes[e1].HasVertex()) {
return false; }
2728 int e2 =
nodes.FindId(v2, v3);
2729 if (e2 < 0 || !
nodes[e2].HasVertex()) {
return false; }
2731 int e3 =
nodes.FindId(v3, v1);
2732 if (e3 < 0 || !
nodes[e3].HasVertex()) {
return false; }
2734 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3; }
2744 if (el.
node[i] == node) {
return i; }
2746 MFEM_ABORT(
"Node not found.");
2752 for (
int i = 0; i <
GI[el.
Geom()].
nv; i++)
2756 if (abort) { MFEM_ABORT(
"Node not found."); }
2765 for (
int i = 0; i < gi.
ne; i++)
2767 const int* ev = gi.
edges[i];
2768 int n0 = el.
node[ev[0]];
2769 int n1 = el.
node[ev[1]];
2770 if ((n0 == vn0 && n1 == vn1) ||
2771 (n0 == vn1 && n1 == vn0)) {
return i; }
2774 if (abort) { MFEM_ABORT(
"Edge (" << vn0 <<
", " << vn1 <<
") not found"); }
2781 for (
int i = 0; i < gi.
nf; i++)
2783 const int* fv = gi.
faces[i];
2784 if ((
a == fv[0] ||
a == fv[1] ||
a == fv[2] ||
a == fv[3]) &&
2785 (
b == fv[0] ||
b == fv[1] ||
b == fv[2] ||
b == fv[3]) &&
2786 (c == fv[0] || c == fv[1] || c == fv[2] || c == fv[3]))
2791 MFEM_ABORT(
"Face not found.");
2801 MFEM_ASSERT(
sizeof(
double) ==
sizeof(std::uint64_t),
"");
2805 std::uint64_t hash = 0xf9ca9ba106acbba9;
2806 for (
int i = 0; i < pm.
np; i++)
2808 for (
int j = 0; j < pm.
points[i].
dim; j++)
2813 hash = 31*hash + *((std::uint64_t*) &coord);
2825 int GetIndex(
const NCMesh::PointMatrix &pm)
2827 int &
index = map[pm];
2832 void ExportMatrices(Array<DenseMatrix*> &point_matrices)
const 2834 point_matrices.SetSize(map.size());
2835 for (
const auto &pair : map)
2837 DenseMatrix* mat =
new DenseMatrix();
2838 pair.first.GetMatrix(*mat);
2839 point_matrices[pair.second - 1] = mat;
2843 void DumpBucketSizes()
const 2845 for (
unsigned i = 0; i < map.bucket_count(); i++)
2852 std::unordered_map<NCMesh::PointMatrix, int, PointMatrixHash> map;
2866 int nfv = (v3 >= 0) ? 4 : 3;
2871 reordered.
np = pm.
np;
2872 for (
int i = 0, j; i < nfv; i++)
2874 for (j = 0; j < nfv; j++)
2876 if (fv[i] == master[j])
2882 MFEM_ASSERT(j != nfv,
"node not found.");
2894 Face* fa =
faces.Find(vn0, vn1, vn2, vn3);
2906 sl.
matrix = matrix_map.GetIndex(pm_r);
2908 eface[0] = eface[2] = fa;
2909 eface[1] = eface[3] = fa;
2922 Point pmid0(pm(0), pm(1)), pmid2(pm(2), pm(3));
2926 level+1, ef[0], matrix_map);
2930 level+1, ef[1], matrix_map);
2932 eface[1] = ef[1][1];
2933 eface[3] = ef[0][3];
2934 eface[0] = eface[2] = NULL;
2936 else if (split == 2)
2938 Point pmid1(pm(1), pm(2)), pmid3(pm(3), pm(0));
2942 level+1, ef[0], matrix_map);
2946 level+1, ef[1], matrix_map);
2948 eface[0] = ef[0][0];
2949 eface[2] = ef[1][2];
2950 eface[1] = eface[3] = NULL;
2961 const int fi[3][2] = {{0, 0}, {1, 3}, {2, 0}};
2962 if (!ef[0][fi[split][0]] && !ef[1][fi[split][1]])
2972 MFEM_ASSERT(eid.
Size() > 0,
"edge prism not found");
2973 MFEM_ASSERT(eid.
Size() < 2,
"non-unique edge prism");
2983 Point mid0(pm(0), pm(1)), mid2(pm(2), pm(3));
2984 int v1 =
nodes[mid[0]].vert_index;
2985 int v2 =
nodes[mid[2]].vert_index;
2987 matrix_map.GetIndex(
2993 Point mid1(pm(1), pm(2)), mid3(pm(3), pm(0));
2994 int v1 =
nodes[mid[1]].vert_index;
2995 int v2 =
nodes[mid[3]].vert_index;
2997 matrix_map.GetIndex(
3009 int mid =
nodes.FindId(vn0, vn1);
3010 if (mid < 0) {
return; }
3026 int v0index =
nodes[vn0].vert_index;
3027 int v1index =
nodes[vn1].vert_index;
3030 matrix_map.GetIndex((v0index < v1index) ?
PointMatrix(p0, p1, p0)
3062 sl.
matrix = matrix_map.GetIndex(pm_r);
3071 Point pmid0(pm(0), pm(1)), pmid1(pm(1), pm(2)), pmid2(pm(2), pm(0));
3076 level+1, matrix_map);
3080 level+1, matrix_map);
3084 level+1, matrix_map);
3088 level+1, matrix_map);
3105 if (
Dim < 3) {
return; }
3112 processed_faces = 0;
3121 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3124 for (
int j = 0; j < gi.
nf; j++)
3128 for (
int k = 0; k < 4; k++)
3133 int face =
faces.FindId(node[0], node[1], node[2], node[3]);
3134 MFEM_ASSERT(face >= 0,
"face not found!");
3140 if (processed_faces[face]) {
continue; }
3141 processed_faces[face] = 1;
3146 if (fa.
elem[0] >= 0 && fa.
elem[1] >= 0)
3176 for (
int ii = sb; ii < se; ii++)
3197 int mid =
nodes.FindId(vn0, vn1);
3198 if (mid < 0) {
return; }
3201 if (nd.
HasEdge() && level > 0)
3211 int v0index =
nodes[vn0].vert_index;
3212 int v1index =
nodes[vn1].vert_index;
3213 if (v0index > v1index) { sl.
edge_flags |= 2; }
3217 double tmid = (t0 + t1) / 2;
3218 TraverseEdge(vn0, mid, t0, tmid, flags, level+1, matrix_map);
3219 TraverseEdge(mid, vn1, tmid, t1, flags, level+1, matrix_map);
3228 processed_edges = 0;
3241 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3244 for (
int j = 0; j < gi.
ne; j++)
3247 const int* ev = gi.
edges[j];
3248 int node[2] = { el.
node[ev[0]], el.
node[ev[1]] };
3250 int enode =
nodes.FindId(node[0], node[1]);
3251 MFEM_ASSERT(enode >= 0,
"edge node not found!");
3254 MFEM_ASSERT(nd.
HasEdge(),
"edge not found!");
3262 int face =
faces.FindId(node[0], node[0], node[1], node[1]);
3263 MFEM_ASSERT(face >= 0,
"face not found!");
3275 if (processed_edges[enode]) {
continue; }
3276 processed_edges[enode] = 1;
3279 double t0 = 0.0, t1 = 1.0;
3280 int v0index =
nodes[node[0]].vert_index;
3281 int v1index =
nodes[node[1]].vert_index;
3282 int flags = (v0index > v1index) ? 1 : 0;
3286 TraverseEdge(node[0], node[1], t0, t1, flags, 0, matrix_map);
3296 for (
int ii = sb; ii < se; ii++)
3313 int local = edge_local[sl.
index];
3333 processed_vertices = 0;
3341 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
3343 int node = el.
node[j];
3351 if (processed_vertices[
index]) {
continue; }
3352 processed_vertices[
index] = 1;
3363 oriented_matrix = *(point_matrices[slave.
Geom()][slave.
matrix]);
3367 MFEM_ASSERT(oriented_matrix.
Height() == 1 &&
3368 oriented_matrix.
Width() == 2,
"not an edge point matrix");
3372 oriented_matrix(0,0) = 1.0 - oriented_matrix(0,0);
3373 oriented_matrix(0,1) = 1.0 - oriented_matrix(0,1);
3377 std::swap(oriented_matrix(0,0), oriented_matrix(0,1));
3384 conforming.DeleteAll();
3385 masters.DeleteAll();
3390 for (
int j = 0; j < point_matrices[i].Size(); j++)
3392 delete point_matrices[i][j];
3394 point_matrices[i].DeleteAll();
3397 inv_index.DeleteAll();
3402 return conforming.Size() + masters.Size() + slaves.Size();
3407 if (!inv_index.Size())
3410 for (
int i = 0; i < conforming.Size(); i++)
3412 max_index = std::max(conforming[i].
index, max_index);
3414 for (
int i = 0; i < masters.Size(); i++)
3416 max_index = std::max(masters[i].
index, max_index);
3418 for (
int i = 0; i < slaves.Size(); i++)
3420 if (slaves[i].
index < 0) {
continue; }
3421 max_index = std::max(slaves[i].
index, max_index);
3424 inv_index.SetSize(max_index + 1);
3427 for (
int i = 0; i < conforming.Size(); i++)
3429 inv_index[conforming[i].index] = (i << 2);
3431 for (
int i = 0; i < masters.Size(); i++)
3433 inv_index[masters[i].index] = (i << 2) + 1;
3435 for (
int i = 0; i < slaves.Size(); i++)
3437 if (slaves[i].
index < 0) {
continue; }
3438 inv_index[slaves[i].index] = (i << 2) + 2;
3442 MFEM_ASSERT(
index >= 0 &&
index < inv_index.Size(),
"");
3443 int key = inv_index[
index];
3447 MFEM_VERIFY(key >= 0,
"entity not found.");
3451 *type = (key >= 0) ? (key & 0x3) : -1;
3454 if (*type < 0) {
return invalid; }
3460 case 0:
return conforming[key >> 2];
3461 case 1:
return masters[key >> 2];
3462 case 2:
return slaves[key >> 2];
3463 default: MFEM_ABORT(
"internal error");
return conforming[0];
3472 int mid =
nodes.FindId(v0, v1);
3473 if (mid >= 0 &&
nodes[mid].HasVertex())
3487 for (
int i = 0; i < 3; i++)
3544 int** JJ =
new int*[nrows];
3554 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
3557 int* node = el.
node;
3560 for (
int j = 0; j < gi.
ne; j++)
3562 const int* ev = gi.
edges[j];
3568 for (
int j = 0; j < gi.
nf; j++)
3570 const int* fv = gi.
faces[j];
3574 node[fv[2]], node[fv[3]], indices);
3587 int size = indices.
Size();
3589 JJ[i] =
new int[size];
3590 std::memcpy(JJ[i], indices.
GetData(), size *
sizeof(int));
3595 for (
int i = 0; i < nrows; i++)
3606 for (
int i = 0; i < nrows; i++)
3608 int cnt = I[i+1] - I[i];
3609 std::memcpy(J+nnz, JJ[i], cnt *
sizeof(
int));
3636 MFEM_VERIFY(elem_set.
Size() == nleaves,
"");
3645 for (
int i = 0; i < nleaves; i++)
3651 for (
int j = 0; j < nv; j++)
3658 for (
int j = 0; j < nv; j++)
3660 vmark[el.
node[j]] = 1;
3671 neighbor_set->
SetSize(nleaves);
3675 for (
int i = 0; i < nleaves; i++)
3683 for (
int j = 0; j < nv; j++)
3685 if (vmark[v[j]]) { hit =
true;
break; }
3692 for (
int j = 0; j < nv; j++)
3694 if (vmark[el.
node[j]]) { hit =
true;
break; }
3701 if (neighbor_set) { (*neighbor_set)[i] = 1; }
3707 static bool sorted_lists_intersect(
const int*
a,
const int*
b,
int na,
int nb)
3710 const int *
const a_end =
a + na;
3711 const int *
const b_end =
b + nb;
3712 while (
a != a_end &&
b != b_end)
3750 while (stack.
Size())
3759 for (
int i = 0; i < nv; i++)
3765 for (
int i = 0; i < nv; i++)
3783 int nv1 = vert.
Size();
3788 for (
int i = 0; i < search_set->
Size(); i++)
3790 int testme = (*search_set)[i];
3797 bool hit = sorted_lists_intersect(v1, v2, nv1, nv2);
3802 for (
int j = 0; j < nv; j++)
3804 hit = sorted_lists_intersect(&el.
node[j], v1, 1, nv1);
3809 if (hit) { neighbors.
Append(testme); }
3823 for (
int i = 0; i < elems.
Size(); i++)
3829 for (
int j = 0; j < nv; j++)
3835 for (
int j = 0; j < nv; j++)
3837 vmark[el.
node[j]] = 1;
3847 for (
int i = 0; i < search_set->
Size(); i++)
3849 int testme = (*search_set)[i];
3855 for (
int j = 0; j < nv; j++)
3857 if (vmark[v[j]]) { hit =
true;
break; }
3863 for (
int j = 0; j < nv; j++)
3865 if (vmark[el.
node[j]]) { hit =
true;
break; }
3869 if (hit) { expanded.
Append(testme); }
3878 if (el.
parent < 0) {
return elem; }
3881 MFEM_ASSERT(pa.
ref_type,
"internal error");
3887 MFEM_ASSERT(geom_parent[el.
Geom()],
"unsupported geometry");
3888 const RefTrf &tr = geom_parent[el.
Geom()][(int) pa.
ref_type][ch];
3889 tr.Apply(coord, coord);
3900 return (pt[0] >= 0) && (pt[0] <= T_ONE) &&
3901 (pt[1] >= 0) && (pt[1] <= T_ONE);
3904 return (pt[0] >= 0) && (pt[0] <= T_ONE) &&
3905 (pt[1] >= 0) && (pt[1] <= T_ONE) &&
3906 (pt[2] >= 0) && (pt[2] <= T_ONE);
3909 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <= T_ONE);
3912 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <= T_ONE) &&
3913 (pt[2] >= 0) && (pt[2] <= T_ONE);
3916 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[2] >= 0.0) &&
3917 (pt[0] + pt[2] <= T_ONE) && (pt[1] + pt[2] <= T_ONE) &&
3921 MFEM_ABORT(
"unsupported geometry");
3939 const RefTrf &tr = geom_child[el.
Geom()][(int) el.
ref_type][ch];
3940 tr.Apply(coord, tcoord);
3942 if (RefPointInside(el.
Geom(), tcoord))
3954 MFEM_ASSERT(geom_corners[el.
Geom()],
"unsupported geometry");
3955 std::memcpy(coord, geom_corners[el.
Geom()][local],
sizeof(coord));
3968 MFEM_ASSERT(np == pm.
np,
"");
3969 for (
int i = 0; i < np; i++)
3972 for (
int j = 0; j < points[i].dim; j++)
3974 if (points[i].coord[j] != pm.
points[i].
coord[j]) {
return false; }
3983 for (
int i = 0; i < np; i++)
3985 for (
int j = 0; j < points[0].dim; j++)
3987 point_matrix(j, i) = points[i].coord[j];
4002 Point(0, 0, 0),
Point(1, 0, 0),
Point(0, 1, 0),
Point(0, 0, 1)
4013 Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
4014 Point(0, 0, 1),
Point(1, 0, 1),
Point(1, 1, 1),
Point(0, 1, 1)
4029 MFEM_ABORT(
"unsupported geometry " << geom);
4041 int ref_type = *ref_path++;
4042 int child = *ref_path++;
4050 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4051 Point mid67(pm(6), pm(7)), mid45(pm(4), pm(5));
4056 pm(4), mid45, mid67, pm(7));
4058 else if (child == 1)
4061 mid45, pm(5), pm(6), mid67);
4064 else if (ref_type == 2)
4066 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4067 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
4072 pm(4), pm(5), mid56, mid74);
4074 else if (child == 1)
4077 mid74, mid56, pm(6), pm(7));
4080 else if (ref_type == 4)
4082 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4083 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4088 mid04, mid15, mid26, mid37);
4090 else if (child == 1)
4093 pm(4), pm(5), pm(6), pm(7));
4096 else if (ref_type == 3)
4098 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4099 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4100 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
4101 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
4103 Point midf0(mid23, mid12, mid01, mid30);
4104 Point midf5(mid45, mid56, mid67, mid74);
4109 pm(4), mid45, midf5, mid74);
4111 else if (child == 1)
4114 mid45, pm(5), mid56, midf5);
4116 else if (child == 2)
4119 midf5, mid56, pm(6), mid67);
4121 else if (child == 3)
4124 mid74, midf5, mid67, pm(7));
4127 else if (ref_type == 5)
4129 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4130 Point mid45(pm(4), pm(5)), mid67(pm(6), pm(7));
4131 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4132 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4134 Point midf1(mid01, mid15, mid45, mid04);
4135 Point midf3(mid23, mid37, mid67, mid26);
4140 mid04, midf1, midf3, mid37);
4142 else if (child == 1)
4145 midf1, mid15, mid26, midf3);
4147 else if (child == 2)
4150 mid45, pm(5), pm(6), mid67);
4152 else if (child == 3)
4155 pm(4), mid45, mid67, pm(7));
4158 else if (ref_type == 6)
4160 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4161 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
4162 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4163 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4165 Point midf2(mid12, mid26, mid56, mid15);
4166 Point midf4(mid30, mid04, mid74, mid37);
4171 mid04, mid15, midf2, midf4);
4173 else if (child == 1)
4176 midf4, midf2, mid26, mid37);
4178 else if (child == 2)
4181 pm(4), pm(5), mid56, mid74);
4183 else if (child == 3)
4186 mid74, mid56, pm(6), pm(7));
4189 else if (ref_type == 7)
4191 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4192 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4193 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
4194 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
4195 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
4196 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
4198 Point midf0(mid23, mid12, mid01, mid30);
4199 Point midf1(mid01, mid15, mid45, mid04);
4200 Point midf2(mid12, mid26, mid56, mid15);
4201 Point midf3(mid23, mid37, mid67, mid26);
4202 Point midf4(mid30, mid04, mid74, mid37);
4203 Point midf5(mid45, mid56, mid67, mid74);
4205 Point midel(midf1, midf3);
4210 mid04, midf1, midel, midf4);
4212 else if (child == 1)
4215 midf1, mid15, midf2, midel);
4217 else if (child == 2)
4220 midel, midf2, mid26, midf3);
4222 else if (child == 3)
4225 midf4, midel, midf3, mid37);
4227 else if (child == 4)
4230 pm(4), mid45, midf5, mid74);
4232 else if (child == 5)
4235 mid45, pm(5), mid56, midf5);
4237 else if (child == 6)
4240 midf5, mid56, pm(6), mid67);
4242 else if (child == 7)
4245 mid74, midf5, mid67, pm(7));
4253 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4254 Point mid20(pm(2), pm(0)), mid34(pm(3), pm(4));
4255 Point mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
4259 pm =
PointMatrix(pm(0), mid01, mid20, pm(3), mid34, mid53);
4261 else if (child == 1)
4263 pm =
PointMatrix(mid01, pm(1), mid12, mid34, pm(4), mid45);
4265 else if (child == 2)
4267 pm =
PointMatrix(mid20, mid12, pm(2), mid53, mid45, pm(5));
4269 else if (child == 3)
4271 pm =
PointMatrix(mid12, mid20, mid01, mid45, mid53, mid34);
4274 else if (ref_type == 4)
4276 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
4280 pm =
PointMatrix(pm(0), pm(1), pm(2), mid03, mid14, mid25);
4282 else if (child == 1)
4284 pm =
PointMatrix(mid03, mid14, mid25, pm(3), pm(4), pm(5));
4289 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
4290 Point mid34(pm(3), pm(4)), mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
4291 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
4293 Point midf2(mid01, mid14, mid34, mid03);
4294 Point midf3(mid12, mid25, mid45, mid14);
4295 Point midf4(mid20, mid03, mid53, mid25);
4299 pm =
PointMatrix(pm(0), mid01, mid20, mid03, midf2, midf4);
4301 else if (child == 1)
4303 pm =
PointMatrix(mid01, pm(1), mid12, midf2, mid14, midf3);
4305 else if (child == 2)
4307 pm =
PointMatrix(mid20, mid12, pm(2), midf4, midf3, mid25);
4309 else if (child == 3)
4311 pm =
PointMatrix(mid12, mid20, mid01, midf3, midf4, midf2);
4313 else if (child == 4)
4315 pm =
PointMatrix(mid03, midf2, midf4, pm(3), mid34, mid53);
4317 else if (child == 5)
4319 pm =
PointMatrix(midf2, mid14, midf3, mid34, pm(4), mid45);
4321 else if (child == 6)
4323 pm =
PointMatrix(midf4, midf3, mid25, mid53, mid45, pm(5));
4325 else if (child == 7)
4327 pm =
PointMatrix(midf3, midf4, midf2, mid45, mid53, mid34);
4333 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4334 Point mid03(pm(0), pm(3)), mid12(pm(1), pm(2));
4335 Point mid04(pm(0), pm(4)), mid14(pm(1), pm(4));
4336 Point mid24(pm(2), pm(4)), mid34(pm(3), pm(4));
4337 Point midf0(mid23, mid12, mid01, mid03);
4341 pm =
PointMatrix(pm(0), mid01, midf0, mid03, mid04);
4343 else if (child == 1)
4345 pm =
PointMatrix(mid01, pm(1), mid12, midf0, mid14);
4347 else if (child == 2)
4349 pm =
PointMatrix(midf0, mid12, pm(2), mid23, mid24);
4351 else if (child == 3)
4353 pm =
PointMatrix(mid03, midf0, mid23, pm(3), mid34);
4355 else if (child == 4)
4357 pm =
PointMatrix(mid24, mid14, mid04, mid34, midf0);
4359 else if (child == 5)
4361 pm =
PointMatrix(mid04, mid14, mid24, mid34, pm(4));
4363 else if (child == 6)
4367 else if (child == 7)
4371 else if (child == 8)
4375 else if (child == 9)
4382 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid02(pm(2), pm(0));
4383 Point mid03(pm(0), pm(3)), mid13(pm(1), pm(3)), mid23(pm(2), pm(3));
4389 else if (child == 1)
4393 else if (child == 2)
4397 else if (child == 3)
4401 else if (child == 4)
4405 else if (child == 5)
4409 else if (child == 6)
4413 else if (child == 7)
4422 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
4428 else if (child == 1)
4433 else if (ref_type == 2)
4435 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
4441 else if (child == 1)
4446 else if (ref_type == 3)
4448 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
4449 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
4450 Point midel(mid01, mid23);
4456 else if (child == 1)
4460 else if (child == 2)
4464 else if (child == 3)
4472 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
4478 else if (child == 1)
4482 else if (child == 2)
4486 else if (child == 3)
4493 Point mid01(pm(0), pm(1));
4499 else if (child == 1)
4507 for (
int i = 0; i < pm.
np; i++)
4509 for (
int j = 0; j < pm(i).dim; j++)
4511 matrix(j, i) = pm(i).coord[j];
4536 int &matrix = map[ref_path];
4537 if (!matrix) { matrix = map.size(); }
4540 emb.
parent = coarse_index;
4547 MFEM_ASSERT(el.
tet_type == 0,
"not implemented");
4550 ref_path.push_back(0);
4554 if (el.
child[i] >= 0)
4556 ref_path[ref_path.length()-1] = i;
4560 ref_path.resize(ref_path.length()-2);
4567 "GetRefinementTransforms() must be preceded by MarkCoarseLevel()" 4575 std::string ref_path;
4576 ref_path.reserve(100);
4581 path_map[g][ref_path] = 1;
4589 used_geoms |= (1 << geom);
4594 if (used_geoms & (1 << g))
4603 RefPathMap::iterator it;
4604 for (it = path_map[g].begin(); it != path_map[g].end(); ++it)
4618 "GetDerefinementTransforms() must be preceded by Derefine().");
4635 int &matrix = mat_no[emb.
geom][code];
4636 if (!matrix) { matrix = mat_no[emb.
geom].size(); }
4644 if (
Geoms & (1 << g))
4653 for (
auto it = mat_no[geom].begin(); it != mat_no[geom].end(); ++it)
4655 char path[3] = { 0, 0, 0 };
4657 int code = it->first;
4660 path[0] = code >> 4;
4661 path[1] = code & 0xf;
4674 bool want_ghosts)
const 4677 conn.
Reserve(embeddings.Size());
4679 int max_parent = -1;
4680 for (
int i = 0; i < embeddings.Size(); i++)
4684 (!emb.
ghost || want_ghosts))
4687 max_parent = std::max(emb.
parent, max_parent);
4705 point_matrices[i].SetSize(0, 0, 0);
4707 embeddings.DeleteAll();
4715 if (point_matrices[i].SizeK()) {
return true; }
4724 a.point_matrices[g].Swap(
b.point_matrices[g]);
4726 Swap(
a.embeddings,
b.embeddings);
4732 static int sgn(
int x)
4734 return (x < 0) ? -1 : (x > 0) ? 1 : 0;
4737 static void HilbertSfc2D(
int x,
int y,
int ax,
int ay,
int bx,
int by,
4740 int w = std::abs(ax + ay);
4741 int h = std::abs(bx + by);
4743 int dax = sgn(ax), day = sgn(ay);
4744 int dbx = sgn(bx), dby = sgn(by);
4748 for (
int i = 0; i < w; i++, x += dax, y += day)
4757 for (
int i = 0; i < h; i++, x += dbx, y += dby)
4765 int ax2 = ax/2, ay2 = ay/2;
4766 int bx2 = bx/2, by2 = by/2;
4768 int w2 = std::abs(ax2 + ay2);
4769 int h2 = std::abs(bx2 + by2);
4773 if ((w2 & 0x1) && (w > 2))
4775 ax2 += dax, ay2 += day;
4778 HilbertSfc2D(x, y, ax2, ay2, bx, by, coords);
4779 HilbertSfc2D(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by, coords);
4783 if ((h2 & 0x1) && (h > 2))
4785 bx2 += dbx, by2 += dby;
4788 HilbertSfc2D(x, y, bx2, by2, ax2, ay2, coords);
4789 HilbertSfc2D(x+bx2, y+by2, ax, ay, bx-bx2, by-by2, coords);
4790 HilbertSfc2D(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
4791 -bx2, -by2, -(ax-ax2), -(ay-ay2), coords);
4795 static void HilbertSfc3D(
int x,
int y,
int z,
4796 int ax,
int ay,
int az,
4797 int bx,
int by,
int bz,
4798 int cx,
int cy,
int cz,
4801 int w = std::abs(ax + ay + az);
4802 int h = std::abs(bx + by + bz);
4803 int d = std::abs(cx + cy + cz);
4805 int dax = sgn(ax), day = sgn(ay), daz = sgn(az);
4806 int dbx = sgn(bx), dby = sgn(by), dbz = sgn(bz);
4807 int dcx = sgn(cx), dcy = sgn(cy), dcz = sgn(cz);
4810 if (h == 1 && d == 1)
4812 for (
int i = 0; i < w; i++, x += dax, y += day, z += daz)
4820 if (w == 1 && d == 1)
4822 for (
int i = 0; i < h; i++, x += dbx, y += dby, z += dbz)
4830 if (w == 1 && h == 1)
4832 for (
int i = 0; i < d; i++, x += dcx, y += dcy, z += dcz)
4841 int ax2 = ax/2, ay2 = ay/2, az2 = az/2;
4842 int bx2 = bx/2, by2 = by/2, bz2 = bz/2;
4843 int cx2 = cx/2, cy2 = cy/2, cz2 = cz/2;
4845 int w2 = std::abs(ax2 + ay2 + az2);
4846 int h2 = std::abs(bx2 + by2 + bz2);
4847 int d2 = std::abs(cx2 + cy2 + cz2);
4850 if ((w2 & 0x1) && (w > 2))
4852 ax2 += dax, ay2 += day, az2 += daz;
4854 if ((h2 & 0x1) && (h > 2))
4856 bx2 += dbx, by2 += dby, bz2 += dbz;
4858 if ((d2 & 0x1) && (d > 2))
4860 cx2 += dcx, cy2 += dcy, cz2 += dcz;
4864 if ((2*w > 3*h) && (2*w > 3*d))
4866 HilbertSfc3D(x, y, z,
4869 cx, cy, cz, coords);
4871 HilbertSfc3D(x+ax2, y+ay2, z+az2,
4872 ax-ax2, ay-ay2, az-az2,
4874 cx, cy, cz, coords);
4879 HilbertSfc3D(x, y, z,
4882 ax2, ay2, az2, coords);
4884 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4886 bx-bx2, by-by2, bz-bz2,
4887 cx, cy, cz, coords);
4889 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4890 y+(ay-day)+(by2-dby),
4891 z+(az-daz)+(bz2-dbz),
4894 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4899 HilbertSfc3D(x, y, z,
4902 bx, by, bz, coords);
4904 HilbertSfc3D(x+cx2, y+cy2, z+cz2,
4907 cx-cx2, cy-cy2, cz-cz2, coords);
4909 HilbertSfc3D(x+(ax-dax)+(cx2-dcx),
4910 y+(ay-day)+(cy2-dcy),
4911 z+(az-daz)+(cz2-dcz),
4913 -(ax-ax2), -(ay-ay2), -(az-az2),
4914 bx, by, bz, coords);
4919 HilbertSfc3D(x, y, z,
4922 ax2, ay2, az2, coords);
4924 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4927 bx-bx2, by-by2, bz-bz2, coords);
4929 HilbertSfc3D(x+(bx2-dbx)+(cx-dcx),
4930 y+(by2-dby)+(cy-dcy),
4931 z+(bz2-dbz)+(cz-dcz),
4934 -(cx-cx2), -(cy-cy2), -(cz-cz2), coords);
4936 HilbertSfc3D(x+(ax-dax)+bx2+(cx-dcx),
4937 y+(ay-day)+by2+(cy-dcy),
4938 z+(az-daz)+bz2+(cz-dcz),
4940 -(ax-ax2), -(ay-ay2), -(az-az2),
4941 bx-bx2, by-by2, bz-bz2, coords);
4943 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4944 y+(ay-day)+(by2-dby),
4945 z+(az-daz)+(bz2-dbz),
4948 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4955 coords.
Reserve(2*width*height);
4957 if (width >= height)
4959 HilbertSfc2D(0, 0, width, 0, 0, height, coords);
4963 HilbertSfc2D(0, 0, 0, height, width, 0, coords);
4971 coords.
Reserve(3*width*height*depth);
4973 if (width >= height && width >= depth)
4975 HilbertSfc3D(0, 0, 0,
4978 0, 0, depth, coords);
4980 else if (height >= width && height >= depth)
4982 HilbertSfc3D(0, 0, 0,
4985 0, 0, depth, coords);
4989 HilbertSfc3D(0, 0, 0,
4992 0, height, 0, coords);
5000 bool oriented)
const 5004 const int* ev = gi.
edges[(int) edge_id.
local];
5006 int n0 = el.
node[ev[0]], n1 = el.
node[ev[1]];
5007 if (n0 > n1) { std::swap(n0, n1); }
5009 vert_index[0] =
nodes[n0].vert_index;
5010 vert_index[1] =
nodes[n1].vert_index;
5012 if (oriented && vert_index[0] > vert_index[1])
5014 std::swap(vert_index[0], vert_index[1]);
5022 const int* ev = gi.
edges[(int) edge_id.
local];
5024 int v0 =
nodes[el.
node[ev[0]]].vert_index;
5025 int v1 =
nodes[el.
node[ev[1]]].vert_index;
5027 return ((v0 < v1 && ev[0] > ev[1]) || (v0 > v1 && ev[0] < ev[1])) ? -1 : 1;
5031 int vert_index[4],
int edge_index[4],
5032 int edge_orientation[4])
const 5034 MFEM_ASSERT(
Dim >= 3,
"");
5039 const int *fv = gi.
faces[(int) face_id.
local];
5040 const int nfv = gi.
nfv[(
int) face_id.
local];
5042 vert_index[3] = edge_index[3] = -1;
5043 edge_orientation[3] = 0;
5045 for (
int i = 0; i < nfv; i++)
5047 vert_index[i] =
nodes[el.
node[fv[i]]].vert_index;
5050 for (
int i = 0; i < nfv; i++)
5053 if (j >= nfv) { j = 0; }
5055 int n1 = el.
node[fv[i]];
5056 int n2 = el.
node[fv[j]];
5059 MFEM_ASSERT(en != NULL,
"edge not found.");
5062 edge_orientation[i] = (vert_index[i] < vert_index[j]) ? 1 : -1;
5070 MFEM_ASSERT(node >= 0,
"edge node not found.");
5073 int p1 = nd.
p1, p2 = nd.
p2;
5074 MFEM_ASSERT(p1 != p2,
"invalid edge node.");
5078 int n1p1 = n1.
p1, n1p2 = n1.
p2;
5079 int n2p1 = n2.p1, n2p2 = n2.p2;
5081 if ((n2p1 != n2p2) && (p1 == n2p1 || p1 == n2p2))
5085 if (n2.HasEdge()) {
return p2; }
5089 if ((n1p1 != n1p2) && (p2 == n1p1 || p2 == n1p2))
5093 if (n1.
HasEdge()) {
return p1; }
5103 MFEM_ASSERT(node >= 0 &&
nodes[node].HasEdge(),
"(v1, v2) is not an edge.");
5106 return (master >= 0) ?
nodes[master].edge_index : -1;
5112 int depth = 0, parent;
5113 while ((parent =
elements[elem].parent) != -1)
5124 int parent, reduction = 1;
5125 while ((parent =
elements[elem].parent) != -1)
5127 if (
elements[parent].ref_type & 1) { reduction *= 2; }
5128 if (
elements[parent].ref_type & 2) { reduction *= 2; }
5129 if (
elements[parent].ref_type & 4) { reduction *= 2; }
5145 for (
int i = 0; i < gi.
nf; i++)
5147 const int* fv = gi.
faces[i];
5150 MFEM_ASSERT(face,
"face not found");
5151 face_indices[i] = face->
index;
5163 int elem = fa.
elem[0];
5164 if (elem < 0) { elem = fa.
elem[1]; }
5165 MFEM_ASSERT(elem >= 0,
"Face has no elements?");
5174 for (
int i = 0; i < 4; i++)
5176 node[i] = el.
node[fv[i]];
5193 if (bdr_attr_is_ess[
faces[face].attribute - 1])
5197 int nfv = (node[3] < 0) ? 3 : 4;
5199 for (
int j = 0; j < nfv; j++)
5203 int enode =
nodes.FindId(node[j], node[(j+1) % nfv]);
5204 MFEM_ASSERT(enode >= 0 &&
nodes[enode].HasEdge(),
"Edge not found.");
5233 bdr_vertices.
Sort();
5240 static int max4(
int a,
int b,
int c,
int d)
5242 return std::max(std::max(
a,
b), std::max(c, d));
5244 static int max6(
int a,
int b,
int c,
int d,
int e,
int f)
5246 return std::max(max4(
a,
b, c, d), std::max(e,
f));
5248 static int max8(
int a,
int b,
int c,
int d,
int e,
int f,
int g,
int h)
5250 return std::max(max4(
a,
b, c, d), max4(e,
f, g, h));
5255 int mid =
nodes.FindId(vn1, vn2);
5256 if (mid < 0 || !
nodes[mid].HasVertex()) {
return 0; }
5264 faces.FindId(vn1, vn2, vn3) < 0)
5278 int& h_level,
int& v_level)
const 5280 int hl1, hl2, vl1, vl2;
5286 h_level = v_level = 0;
5292 h_level = std::max(hl1, hl2);
5293 v_level = std::max(vl1, vl2) + 1;
5299 h_level = std::max(hl1, hl2) + 1;
5300 v_level = std::max(vl1, vl2);
5307 const int* node = el.
node;
5311 for (
int i = 0; i < gi.
ne; i++)
5313 const int* ev = gi.
edges[i];
5320 for (
int i = 0; i < gi.
nf; i++)
5322 const int* fv = gi.
faces[i];
5326 node[fv[2]], node[fv[3]],
5327 flevel[i][1], flevel[i][0]);
5340 splits[0] = max8(flevel[0][0], flevel[1][0], flevel[3][0], flevel[5][0],
5341 elevel[0], elevel[2], elevel[4], elevel[6]);
5343 splits[1] = max8(flevel[0][1], flevel[2][0], flevel[4][0], flevel[5][1],
5344 elevel[1], elevel[3], elevel[5], elevel[7]);
5346 splits[2] = max8(flevel[1][1], flevel[2][1], flevel[3][1], flevel[4][1],
5347 elevel[8], elevel[9], elevel[10], elevel[11]);
5351 splits[0] = splits[1] =
5353 max6(flevel[0][0], flevel[1][0], 0,
5354 flevel[2][0], flevel[3][0], flevel[4][0]),
5355 max6(elevel[0], elevel[1], elevel[2],
5356 elevel[3], elevel[4], elevel[5]));
5358 splits[2] = max6(flevel[2][1], flevel[3][1], flevel[4][1],
5359 elevel[6], elevel[7], elevel[8]);
5363 splits[0] = std::max(
5364 max6(flevel[0][0], flevel[1][0], 0,
5365 flevel[2][0], flevel[3][0], flevel[4][0]),
5366 max8(elevel[0], elevel[1], elevel[2],
5367 elevel[3], elevel[4], elevel[5],
5368 elevel[6], elevel[7]));
5370 splits[1] = splits[0];
5371 splits[2] = splits[0];
5375 splits[0] = std::max(
5376 max4(flevel[0][0], flevel[1][0], flevel[2][0], flevel[3][0]),
5377 max6(elevel[0], elevel[1], elevel[2],
5378 elevel[3], elevel[4], elevel[5]));
5380 splits[1] = splits[0];
5381 splits[2] = splits[0];
5385 splits[0] = std::max(elevel[0], elevel[2]);
5386 splits[1] = std::max(elevel[1], elevel[3]);
5390 splits[0] = std::max(elevel[0], std::max(elevel[1], elevel[2]));
5391 splits[1] = splits[0];
5395 MFEM_ABORT(
"Unsupported element geometry.");
5409 for (
int k = 0; k <
Dim; k++)
5411 if (splits[k] > max_level)
5413 ref_type |= (1 << k);
5431 MFEM_VERIFY(max_nc_level >= 1,
"'max_nc_level' must be 1 or greater.");
5438 if (!refinements.
Size()) {
break; }
5453 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5455 if (node->HasVertex() && node->p1 != node->p2) { nv++; }
5462 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5464 if (node->HasVertex() && node->p1 != node->p2)
5466 MFEM_ASSERT(
nodes[node->p1].HasVertex(),
"");
5467 MFEM_ASSERT(
nodes[node->p2].HasVertex(),
"");
5469 (*os) << node.index() <<
" " << node->p1 <<
" " << node->p2 <<
"\n";
5483 input >>
id >> p1 >> p2;
5484 MFEM_VERIFY(input,
"problem reading vertex parents.");
5486 MFEM_VERIFY(
nodes.IdExists(
id),
"vertex " <<
id <<
" not found.");
5487 MFEM_VERIFY(
nodes.IdExists(p1),
"parent " << p1 <<
" not found.");
5488 MFEM_VERIFY(
nodes.IdExists(p2),
"parent " << p2 <<
" not found.");
5490 int check =
nodes.FindId(p1, p2);
5491 MFEM_VERIFY(check < 0,
"parents (" << p1 <<
", " << p2 <<
") already " 5492 "assigned to node " << check);
5495 nodes.Reparent(
id, p1, p2);
5501 static const int nfv2geom[5] =
5506 int deg = (
Dim == 2) ? 2 : 1;
5509 for (
int i = 0; i <
elements.Size(); i++)
5512 if (!el.
IsLeaf()) {
continue; }
5515 for (
int k = 0; k < gi.
nf; k++)
5517 const int* fv = gi.
faces[k];
5518 const int nfv = gi.
nfv[k];
5521 MFEM_ASSERT(face != NULL,
"face not found");
5524 if (!os) { count++;
continue; }
5526 (*os) << face->
attribute <<
" " << nfv2geom[nfv];
5527 for (
int j = 0; j < nfv; j++)
5529 (*os) <<
" " << el.
node[fv[j*deg]];
5542 for (
int i = 0; i < nb; i++)
5544 input >> attr >> geom;
5549 input >> v1 >> v2 >> v3 >> v4;
5555 input >> v1 >> v2 >> v3;
5573 MFEM_ABORT(
"unsupported boundary element geometry: " << geom);
5582 if (!nv) {
return; }
5585 for (
int i = 0; i < nv; i++)
5600 if (!nv) {
return; }
5607 for (
int i = 0; i < nv; i++)
5612 MFEM_VERIFY(input.good(),
"unexpected EOF");
5628 os <<
"MFEM NC mesh v1.0\n\n" 5629 "# NCMesh supported geometry types:\n" 5633 "# TETRAHEDRON = 4\n" 5638 os <<
"\ndimension\n" <<
Dim <<
"\n";
5640 #ifndef MFEM_USE_MPI 5644 os <<
"\nrank\n" <<
MyRank <<
"\n";
5647 os <<
"\n# rank attr geom ref_type nodes/children";
5648 os <<
"\nelements\n" <<
elements.Size() <<
"\n";
5650 for (
int i = 0; i <
elements.Size(); i++)
5654 if (el.
parent == -2) { os <<
"-1\n";
continue; }
5659 os <<
" " << el.
node[j];
5667 os <<
"\n# attr geom nodes";
5668 os <<
"\nboundary\n" << nb <<
"\n";
5676 os <<
"\n# vert_id p1 p2";
5677 os <<
"\nvertex_parents\n" << nvp <<
"\n";
5684 os <<
"\n# root element orientation";
5695 os <<
"\n# top-level node coordinates";
5696 os <<
"\ncoordinates\n";
5709 for (
int i = 0; i <
elements.Size(); i++)
5716 int child = el.
child[j];
5717 MFEM_VERIFY(child <
elements.Size(),
"invalid mesh file: " 5718 "element " << i <<
" references invalid child " << child);
5731 MFEM_VERIFY(nroots,
"invalid mesh file: no root elements found.");
5734 for (
int i = nroots; i <
elements.Size(); i++)
5736 MFEM_VERIFY(
elements[i].parent != -1,
5737 "invalid mesh file: only the first M elements can be roots. " 5738 "Found element " << i <<
" with no parent.");
5749 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
5751 if (node->p1 == node->p2) { ntop = node.index() + 1; }
5767 MFEM_ASSERT(version == 10,
"");
5774 MFEM_VERIFY(ident ==
"dimension",
"Invalid mesh file: " << ident);
5780 if (ident ==
"rank")
5783 MFEM_VERIFY(
MyRank >= 0,
"Invalid rank");
5790 if (ident ==
"sfc_version")
5793 input >> sfc_version;
5794 MFEM_VERIFY(sfc_version == 0,
5795 "Unsupported mesh file SFC version (" << sfc_version <<
"). " 5796 "Please update MFEM.");
5803 MFEM_VERIFY(ident ==
"elements",
"Invalid mesh file: " << ident);
5805 for (
int i = 0; i < count; i++)
5807 int rank, attr, geom, ref_type;
5808 input >> rank >> attr >> geom;
5813 MFEM_ASSERT(
elements.Size() == i+1,
"");
5819 CheckSupportedGeom(type);
5823 MFEM_VERIFY(ref_type >= 0 && ref_type < 8,
"");
5824 el.ref_type = ref_type;
5828 for (
int j = 0; j < ref_type_num_children[ref_type]; j++)
5830 input >> el.child[j];
5832 if (
Dim == 3 && ref_type != 7) {
Iso =
false; }
5836 for (
int j = 0; j <
GI[geom].
nv; j++)
5841 nodes.Alloc(
id,
id,
id);
5861 if (ident ==
"boundary")
5870 if (ident ==
"vertex_parents")
5879 if (ident ==
"root_state")
5883 for (
int i = 0; i < count; i++)
5893 if (ident ==
"coordinates")
5898 "Invalid mesh file: not all top-level nodes are covered by " 5899 "the 'coordinates' section of the mesh file.");
5902 else if (ident ==
"nodes")
5912 MFEM_ABORT(
"Invalid mesh file: either 'coordinates' or " 5913 "'nodes' must be present");
5917 nodes.UpdateUnused();
5918 for (
int i = 0; i <
elements.Size(); i++)
5938 int old_id = el.
child[i];
5940 int new_id =
elements.Append(tmp_elements[old_id]);
5941 el.
child[i] = new_id;
5965 if (
Dim == 3 && ref_type != 7) { iso =
false; }
5968 int nch = ref_type_num_children[ref_type];
5969 for (
int i = 0,
id; i < nch; i++)
5972 MFEM_VERIFY(
id >= 0,
"");
5974 "coarse element cannot be referenced before it is " 5975 "defined (id=" <<
id <<
").");
5978 MFEM_VERIFY(child.parent == -1,
5979 "element " <<
id <<
" cannot have two parents.");
5982 child.parent = elem;
5986 el.
geom = child.geom;
5998 for (
auto el = tmp_elements.
begin(); el != tmp_elements.
end(); ++el)
6000 if (el->parent == -1)
6008 for (
int i = 0; i < root_count; i++)
6021 MFEM_ASSERT(
elements.Size() == 0,
"");
6022 MFEM_ASSERT(
nodes.Size() == 0,
"");
6026 int count, attr, geom;
6031 MFEM_VERIFY(ident ==
"dimension",
"invalid mesh file");
6037 MFEM_VERIFY(ident ==
"elements",
"invalid mesh file");
6040 for (
int i = 0; i < count; i++)
6042 input >> attr >> geom;
6045 CheckSupportedGeom(type);
6049 MFEM_ASSERT(eid == i,
"");
6052 for (
int j = 0; j <
GI[geom].
nv; j++)
6057 nodes.Alloc(
id,
id,
id);
6065 MFEM_VERIFY(ident ==
"boundary",
"invalid mesh file");
6072 if (ident ==
"vertex_parents")
6088 if (ident ==
"coarse_elements")
6103 MFEM_VERIFY(ident ==
"vertices",
"invalid mesh file");
6106 input >> std::ws >> ident;
6107 if (ident !=
"nodes")
6114 for (
int i = 0; i < nvert; i++)
6119 MFEM_VERIFY(input.good(),
"unexpected EOF");
6140 nodes.UpdateUnused();
6142 for (
int i = 0; i <
elements.Size(); i++)
6154 file_leaf_elements = -1;
6155 for (
int i = 0; i <
elements.Size(); i++)
6159 file_leaf_elements[
elements[i].index] = i;
6162 MFEM_ASSERT(file_leaf_elements.
Min() >= 0,
"");
6183 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
6185 if (node->HasVertex())
6187 MFEM_ASSERT(node.index() >= 0,
"");
6188 MFEM_ASSERT(node.index() < order.
Size(),
"");
6189 MFEM_ASSERT(order[node.index()] == -1,
"");
6191 order[node.index()] = node->vert_index;
6195 MFEM_ASSERT(count == order.
Size(),
"");
6236 long mem = embeddings.MemoryUsage();
6239 mem += point_matrices[i].MemoryUsage();
6246 return nodes.MemoryUsage() +
6247 faces.MemoryUsage() +
6284 <<
ref_stack.MemoryUsage() <<
" ref_stack\n" 6288 <<
sizeof(*this) <<
" NCMesh" 6301 for (
int j = 0; j <
Dim; j++)
6307 if (elem->
node[k] >= 0)
6313 os << sum / count <<
" ";
6324 os <<
nodes.Size() <<
"\n";
6325 for (
auto node =
nodes.cbegin(); node !=
nodes.cend(); ++node)
6328 os << node.index() <<
" " 6329 << pos[0] <<
" " << pos[1] <<
" " << pos[2] <<
" " 6330 << node->p1 <<
" " << node->p2 <<
" " 6331 << node->vert_index <<
" " << node->edge_index <<
" " 6339 for (
int i = 0; i <
elements.Size(); i++)
6341 if (
elements[i].IsLeaf()) { nleaves++; }
6343 os << nleaves <<
"\n";
6344 for (
int i = 0; i <
elements.Size(); i++)
6351 for (
int j = 0; j < gi.
nv; j++)
6353 os << el.
node[j] <<
" ";
6361 os <<
faces.Size() <<
"\n";
6362 for (
auto face =
faces.cbegin(); face !=
faces.cend(); ++face)
6364 int elem = face->elem[0];
6365 if (elem < 0) { elem = face->elem[1]; }
6366 MFEM_ASSERT(elem >= 0,
"");
6378 for (
int i = 0; i < nfv; i++)
6380 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
Returns the edge-to-vertex Table (3D)
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)
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 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
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)
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)
double f(const Vector &xvec)
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
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
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