13 #include "../fem/fem.hpp"
36 for (
int i = 0; i <
ne; i++)
38 for (
int j = 0; j < 2; j++)
43 for (
int i = 0; i <
nf; i++)
45 for (
int j = 0; j <
nfv; j++)
54 for (
int i = 0; i <
ne; i++)
73 Iso = vertex_parents ?
false :
true;
78 for (
int i = 0; i < mesh->
GetNE(); i++)
82 for (
int j = 0; j < nv; j++)
84 max_id = std::max(max_id, v[j]);
87 for (
int id = 0;
id <= max_id;
id++)
90 int node =
nodes.GetId(
id,
id);
91 MFEM_CONTRACT_VAR(node);
92 MFEM_ASSERT(node ==
id,
"");
104 for (
int i = 0; i < mesh->
GetNV(); i++)
121 MFEM_ABORT(
"only triangles, quads and hexes are supported by NCMesh.");
129 MFEM_ASSERT(root_id == i,
"");
133 for (
int j = 0; j <
GI[
geom].
nv; j++)
135 root_elem.
node[j] = v[j];
147 for (
int i = 0; i < mesh->
GetNBE(); i++)
154 Face* face =
faces.Find(v[0], v[1], v[2], v[3]);
155 MFEM_VERIFY(face,
"boundary face not found.");
160 Face* face =
faces.Find(v[0], v[0], v[1], v[1]);
161 MFEM_VERIFY(face,
"boundary face not found.");
166 MFEM_ABORT(
"only segment and quadrilateral boundary "
167 "elements are supported by NCMesh.");
205 for (
int i = 0; i <
elements.Size(); i++)
227 "vert_refc: " << (
int)
vert_refc <<
", edge_refc: "
238 for (
int i = 0; i < gi.
nv; i++)
240 nodes[node[i]].vert_refc++;
244 for (
int i = 0; i < gi.
ne; i++)
246 const int* ev = gi.
edges[i];
247 nodes.Get(node[ev[0]], node[ev[1]])->edge_refc++;
251 for (
int i = 0; i < gi.
nf; i++)
253 const int* fv = gi.
faces[i];
254 faces.GetId(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
269 for (
int i = 0; i < gi.
nf; i++)
271 const int* fv = gi.
faces[i];
272 int face =
faces.FindId(node[fv[0]], node[fv[1]],
273 node[fv[2]], node[fv[3]]);
274 MFEM_ASSERT(face >= 0,
"face not found.");
275 faces[face].ForgetElement(elem);
283 for (
int i = 0; i < gi.
ne; i++)
285 const int* ev = gi.
edges[i];
287 MFEM_ASSERT(enode >= 0,
"edge not found.");
288 MFEM_ASSERT(
nodes.IdExists(enode),
"edge does not exist.");
289 if (!
nodes[enode].UnrefEdge())
296 for (
int i = 0; i < gi.
nv; i++)
298 if (!
nodes[node[i]].UnrefVertex())
300 nodes.Delete(node[i]);
310 for (
int i = 0; i < gi.
nf; i++)
313 MFEM_ASSERT(face,
"face not found.");
315 if (fattr) { face->
attribute = fattr[i]; }
321 for (
int i = 0; i < elemFaces.
Size(); i++)
323 if (
faces[elemFaces[i]].Unused())
325 faces.Delete(elemFaces[i]);
332 if (elem[0] < 0) { elem[0] = e; }
333 else if (elem[1] < 0) { elem[1] = e; }
334 else { MFEM_ABORT(
"can't have 3 elements in Face::elem[]."); }
339 if (elem[0] == e) { elem[0] = -1; }
340 else if (elem[1] == e) { elem[1] = -1; }
341 else { MFEM_ABORT(
"element " << e <<
" not found in Face::elem[]."); }
347 const int* fv = gi.
faces[face_no];
348 int* node = elem.
node;
349 return faces.Find(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
356 MFEM_ASSERT(elem[1] < 0,
"not a single element face.");
361 MFEM_ASSERT(elem[1] >= 0,
"no elements in face.");
368 int mid =
nodes.FindId(node1, node2);
369 if (mid < 0 && Dim >= 3 && !
Iso)
396 int n1p1 = n1.
p1, n1p2 = n1.
p2;
397 int n2p1 = n2.p1, n2p2 = n2.p2;
399 if ((n1p1 != n1p2) && (n2p1 != n2p2))
404 if (a1 < 0 || a2 < 0)
411 if (a1 >= 0 && a2 >= 0)
413 mid =
nodes.FindId(a1, a2);
424 : geom(geom), ref_type(0), flag(0), index(-1), rank(0), attribute(attr)
427 for (
int i = 0; i < 8; i++) {
node[i] = -1; }
436 int n4,
int n5,
int n6,
int n7,
438 int fattr0,
int fattr1,
int fattr2,
439 int fattr3,
int fattr4,
int fattr5)
466 int eattr0,
int eattr1,
int eattr2,
int eattr3)
490 int attr,
int eattr0,
int eattr1,
int eattr2)
517 if (mid < 0) { mid =
nodes.GetId(vn1, vn2); }
524 int midf =
nodes.FindId(en1, en3);
525 if (midf >= 0) {
return midf; }
526 return nodes.GetId(en2, en4);
531 {
return node == n[0] || node == n[3] || node == n[4] || node == n[7]; }
534 {
return node == n[1] || node == n[2] || node == n[5] || node == n[6]; }
537 {
return node == n[0] || node == n[1] || node == n[4] || node == n[5]; }
540 {
return node == n[2] || node == n[3] || node == n[6] || node == n[7]; }
543 {
return node == n[0] || node == n[1] || node == n[2] || node == n[3]; }
546 {
return node == n[4] || node == n[5] || node == n[6] || node == n[7]; }
552 Face* face =
faces.Find(vn1, vn2, vn3, vn4);
553 if (!face) {
return; }
556 MFEM_ASSERT(!
elements[elem].ref_type,
"element already refined.");
578 MFEM_ABORT(
"inconsistent element/face structure.");
584 int mid12,
int mid34,
int level)
610 int mid23 =
nodes.FindId(vn2, vn3);
611 int mid41 =
nodes.FindId(vn4, vn1);
612 if (mid23 >= 0 && mid41 >= 0)
614 int midf =
nodes.FindId(mid23, mid41);
617 nodes.Reparent(midf, mid12, mid34);
650 int en1,
int en2,
int en3,
int en4,
int midf)
668 if (!ref_type) {
return; }
674 char remaining = ref_type & ~el.
ref_type;
677 for (
int i = 0; i < 8; i++)
688 for (
int i = 0; i < 8; i++) { child[i] = -1; }
693 for (
int i = 0; i < gi.
nf; i++)
695 const int* fv = gi.
faces[i];
696 Face* face =
faces.Find(no[fv[0]], no[fv[1]], no[fv[2]], no[fv[3]]);
725 no[4], mid45, mid67, no[7], attr,
726 fa[0], fa[1], -1, fa[3], fa[4], fa[5]);
729 mid45, no[5], no[6], mid67, attr,
730 fa[0], fa[1], fa[2], fa[3], -1, fa[5]);
737 else if (ref_type == 2)
745 no[4], no[5], mid56, mid74, attr,
746 fa[0], fa[1], fa[2], -1, fa[4], fa[5]);
749 mid74, mid56, no[6], no[7], attr,
750 fa[0], -1, fa[2], fa[3], fa[4], fa[5]);
757 else if (ref_type == 4)
765 mid04, mid15, mid26, mid37, attr,
766 fa[0], fa[1], fa[2], fa[3], fa[4], -1);
769 no[4], no[5], no[6], no[7], attr,
770 -1, fa[1], fa[2], fa[3], fa[4], fa[5]);
777 else if (ref_type == 3)
793 no[4], mid45, midf5, mid74, attr,
794 fa[0], fa[1], -1, -1, fa[4], fa[5]);
797 mid45, no[5], mid56, midf5, attr,
798 fa[0], fa[1], fa[2], -1, -1, fa[5]);
801 midf5, mid56, no[6], mid67, attr,
802 fa[0], -1, fa[2], fa[3], -1, fa[5]);
805 mid74, midf5, mid67, no[7], attr,
806 fa[0], -1, -1, fa[3], fa[4], fa[5]);
813 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
814 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
816 else if (ref_type == 5)
832 mid04, midf1, midf3, mid37, attr,
833 fa[0], fa[1], -1, fa[3], fa[4], -1);
836 midf1, mid15, mid26, midf3, attr,
837 fa[0], fa[1], fa[2], fa[3], -1, -1);
840 mid45, no[5], no[6], mid67, attr,
841 -1, fa[1], fa[2], fa[3], -1, fa[5]);
844 no[4], mid45, mid67, no[7], attr,
845 -1, fa[1], -1, fa[3], fa[4], fa[5]);
852 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
853 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
855 else if (ref_type == 6)
871 mid04, mid15, midf2, midf4, attr,
872 fa[0], fa[1], fa[2], -1, fa[4], -1);
875 midf4, midf2, mid26, mid37, attr,
876 fa[0], -1, fa[2], fa[3], fa[4], -1);
879 no[4], no[5], mid56, mid74, attr,
880 -1, fa[1], fa[2], -1, fa[4], fa[5]);
883 mid74, mid56, no[6], no[7], attr,
884 -1, -1, fa[2], fa[3], fa[4], fa[5]);
891 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
892 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
894 else if (ref_type == 7)
921 mid04, midf1, midel, midf4, attr,
922 fa[0], fa[1], -1, -1, fa[4], -1);
925 midf1, mid15, midf2, midel, attr,
926 fa[0], fa[1], fa[2], -1, -1, -1);
929 midel, midf2, mid26, midf3, attr,
930 fa[0], -1, fa[2], fa[3], -1, -1);
933 midf4, midel, midf3, mid37, attr,
934 fa[0], -1, -1, fa[3], fa[4], -1);
937 no[4], mid45, midf5, mid74, attr,
938 -1, fa[1], -1, -1, fa[4], fa[5]);
941 mid45, no[5], mid56, midf5, attr,
942 -1, fa[1], fa[2], -1, -1, fa[5]);
945 midf5, mid56, no[6], mid67, attr,
946 -1, -1, fa[2], fa[3], -1, fa[5]);
949 mid74, midf5, mid67, no[7], attr,
950 -1, -1, -1, fa[3], fa[4], fa[5]);
952 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
953 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
954 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
955 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
956 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
957 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
961 MFEM_ABORT(
"invalid refinement type.");
964 if (ref_type != 7) {
Iso =
false; }
972 int mid01 =
nodes.GetId(no[0], no[1]);
973 int mid23 =
nodes.GetId(no[2], no[3]);
976 attr, fa[0], -1, fa[2], fa[3]);
979 attr, fa[0], fa[1], fa[2], -1);
981 else if (ref_type == 2)
983 int mid12 =
nodes.GetId(no[1], no[2]);
984 int mid30 =
nodes.GetId(no[3], no[0]);
987 attr, fa[0], fa[1], -1, fa[3]);
990 attr, -1, fa[1], fa[2], fa[3]);
992 else if (ref_type == 3)
994 int mid01 =
nodes.GetId(no[0], no[1]);
995 int mid12 =
nodes.GetId(no[1], no[2]);
996 int mid23 =
nodes.GetId(no[2], no[3]);
997 int mid30 =
nodes.GetId(no[3], no[0]);
999 int midel =
nodes.GetId(mid01, mid23);
1002 attr, fa[0], -1, -1, fa[3]);
1005 attr, fa[0], fa[1], -1, -1);
1008 attr, -1, fa[1], fa[2], -1);
1011 attr, -1, -1, fa[2], fa[3]);
1015 MFEM_ABORT(
"Invalid refinement type.");
1018 if (ref_type != 3) {
Iso =
false; }
1025 int mid01 =
nodes.GetId(no[0], no[1]);
1026 int mid12 =
nodes.GetId(no[1], no[2]);
1027 int mid20 =
nodes.GetId(no[2], no[0]);
1029 child[0] =
NewTriangle(no[0], mid01, mid20, attr, fa[0], -1, fa[2]);
1030 child[1] =
NewTriangle(mid01, no[1], mid12, attr, fa[0], fa[1], -1);
1031 child[2] =
NewTriangle(mid20, mid12, no[2], attr, -1, fa[1], fa[2]);
1032 child[3] =
NewTriangle(mid01, mid12, mid20, attr, -1, -1, -1);
1036 MFEM_ABORT(
"Unsupported element geometry.");
1040 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1053 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1062 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1079 for (
int i = refinements.
Size()-1; i >= 0; i--)
1107 #if defined(MFEM_DEBUG) && !defined(MFEM_USE_MPI)
1108 mfem::out <<
"Refined " << refinements.
Size() <<
" + " << nforced
1109 <<
" elements" << std::endl;
1125 memcpy(child, el.
child,
sizeof(child));
1128 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1140 const int table[7][8 + 6] =
1142 { 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0 },
1143 { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1 },
1144 { 0, 1, 2, 3, 0, 1, 2, 3, 1, 1, 1, 3, 3, 3 },
1145 { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1 },
1146 { 0, 1, 1, 0, 3, 2, 2, 3, 1, 1, 1, 3, 3, 3 },
1147 { 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 0, 3, 3, 3 },
1148 { 0, 1, 2, 3, 4, 5, 6, 7, 1, 1, 1, 7, 7, 7 }
1150 for (
int i = 0; i < 8; i++)
1154 for (
int i = 0; i < 6; i++)
1159 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1164 const int table[3][4 + 4] =
1166 { 0, 1, 1, 0, 1, 1, 0, 0 },
1167 { 0, 0, 1, 1, 0, 0, 1, 1 },
1168 { 0, 1, 2, 3, 1, 1, 3, 3 }
1170 for (
int i = 0; i < 4; i++)
1174 for (
int i = 0; i < 4; i++)
1179 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1184 for (
int i = 0; i < 3; i++)
1190 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1195 MFEM_ABORT(
"Unsupported element geometry.");
1207 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1230 int total = 0, ref = 0, ghost = 0;
1231 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1239 if (!ref && ghost < total)
1242 int next_row = list.
Size() ? (list.
Last().from + 1) : 0;
1243 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1251 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1268 int size = list.
Size() ? (list.
Last().from + 1) : 0;
1277 for (
int i = 0; i < deref_table.
Size(); i++)
1279 const int* fine = deref_table.
GetRow(i), size = deref_table.
RowSize(i);
1283 for (
int j = 0; j < size; j++)
1288 for (
int k = 0; k <
Dim; k++)
1290 if ((parent.
ref_type & (1 << k)) &&
1291 splits[k] >= max_nc_level)
1304 MFEM_VERIFY(
Dim < 3 ||
Iso,
1305 "derefinement of 3D anisotropic meshes not implemented yet.");
1313 for (
int i = 0; i < derefs.
Size(); i++)
1315 int row = derefs[i];
1317 "invalid derefinement number.");
1332 for (
int i = 0; i < fine_coarse.
Size(); i++)
1343 for (
int i = 0; i < nfine; i++)
1357 for (
int i = 0; i < 8 && prn.
child[i] >= 0; i++)
1362 int code = (prn.
ref_type << 3) + i;
1364 fine_coarse[ch.
index] = parent;
1378 if (node->HasVertex()) { node->vert_index =
NVertices++; }
1390 static char quad_hilbert_child_order[8][4] =
1392 {0,1,2,3}, {0,3,2,1}, {1,2,3,0}, {1,0,3,2},
1393 {2,3,0,1}, {2,1,0,3}, {3,0,1,2}, {3,2,1,0}
1395 static char quad_hilbert_child_state[8][4] =
1397 {1,0,0,5}, {0,1,1,4}, {3,2,2,7}, {2,3,3,6},
1398 {5,4,4,1}, {4,5,5,0}, {7,6,6,3}, {6,7,7,2}
1400 static char hex_hilbert_child_order[24][8] =
1402 {0,1,2,3,7,6,5,4}, {0,3,7,4,5,6,2,1}, {0,4,5,1,2,6,7,3},
1403 {1,0,3,2,6,7,4,5}, {1,2,6,5,4,7,3,0}, {1,5,4,0,3,7,6,2},
1404 {2,1,5,6,7,4,0,3}, {2,3,0,1,5,4,7,6}, {2,6,7,3,0,4,5,1},
1405 {3,0,4,7,6,5,1,2}, {3,2,1,0,4,5,6,7}, {3,7,6,2,1,5,4,0},
1406 {4,0,1,5,6,2,3,7}, {4,5,6,7,3,2,1,0}, {4,7,3,0,1,2,6,5},
1407 {5,1,0,4,7,3,2,6}, {5,4,7,6,2,3,0,1}, {5,6,2,1,0,3,7,4},
1408 {6,2,3,7,4,0,1,5}, {6,5,1,2,3,0,4,7}, {6,7,4,5,1,0,3,2},
1409 {7,3,2,6,5,1,0,4}, {7,4,0,3,2,1,5,6}, {7,6,5,4,0,1,2,3}
1411 static char hex_hilbert_child_state[24][8] =
1413 {1,2,2,7,7,21,21,17}, {2,0,0,22,22,16,16,8}, {0,1,1,15,15,6,6,23},
1414 {4,5,5,10,10,18,18,14}, {5,3,3,19,19,13,13,11}, {3,4,4,12,12,9,9,20},
1415 {8,7,7,17,17,23,23,2}, {6,8,8,0,0,15,15,22}, {7,6,6,21,21,1,1,16},
1416 {11,10,10,14,14,20,20,5}, {9,11,11,3,3,12,12,19}, {10,9,9,18,18,4,4,13},
1417 {13,14,14,5,5,19,19,10}, {14,12,12,20,20,11,11,4}, {12,13,13,9,9,3,3,18},
1418 {16,17,17,2,2,22,22,7}, {17,15,15,23,23,8,8,1}, {15,16,16,6,6,0,0,21},
1419 {20,19,19,11,11,14,14,3}, {18,20,20,4,4,10,10,12}, {19,18,18,13,13,5,5,9},
1420 {23,22,22,8,8,17,17,0}, {21,23,23,1,1,7,7,15}, {22,21,21,16,16,2,2,6}
1437 for (
int i = 0; i < 4; i++)
1439 int ch = quad_hilbert_child_order[state][i];
1440 int st = quad_hilbert_child_state[state][i];
1446 for (
int i = 0; i < 8; i++)
1448 int ch = hex_hilbert_child_order[state][i];
1449 int st = hex_hilbert_child_state[state][i];
1455 for (
int i = 0; i < 8; i++)
1495 MFEM_ABORT(
"invalid geometry");
1514 MFEM_VERIFY(tv.
visited ==
false,
"cyclic vertex dependencies.");
1520 for (
int i = 0; i < 3; i++)
1522 tv.
pos[i] = (pos1[i] + pos2[i]) * 0.5;
1537 for (
int i = 0; i < mvertices.
Size(); i++)
1556 if (
IsGhost(nc_elem)) {
continue; }
1558 const int* node = nc_elem.
node;
1565 for (
int j = 0; j < gi.
nv; j++)
1567 elem->GetVertices()[j] =
nodes[node[j]].vert_index;
1571 for (
int k = 0; k < gi.
nf; k++)
1573 const int* fv = gi.
faces[k];
1574 const Face* face =
faces.Find(node[fv[0]], node[fv[1]],
1575 node[fv[2]], node[fv[3]]);
1582 for (
int j = 0; j < 4; j++)
1592 for (
int j = 0; j < 2; j++)
1596 mboundary.
Append(segment);
1608 for (
int i = 0; i < edge_vertex->
Size(); i++)
1610 const int *ev = edge_vertex->
GetRow(i);
1613 MFEM_ASSERT(node && node->
HasEdge(),
"edge not found.");
1620 const int* fv = mesh->
GetFace(i)->GetVertices();
1624 MFEM_ASSERT(mesh->
GetFace(i)->GetNVertices() == 4,
"");
1630 MFEM_ASSERT(mesh->
GetFace(i)->GetNVertices() == 2,
"");
1632 face =
faces.Find(n0, n0, n1, n1);
1636 const int *ev = edge_vertex->
GetRow(i);
1637 MFEM_ASSERT((ev[0] == fv[0] && ev[1] == fv[1]) ||
1638 (ev[1] == fv[0] && ev[0] == fv[1]),
"");
1641 MFEM_ASSERT(face,
"face not found.");
1655 MFEM_ASSERT(
Dim >= 3,
"");
1658 int e1 =
nodes.FindId(v1, v2);
1659 int e2 =
nodes.FindId(v2, v3);
1660 int e3 = (e1 >= 0 &&
nodes[e1].HasVertex()) ?
nodes.FindId(v3, v4) : -1;
1661 int e4 = (e2 >= 0 &&
nodes[e2].HasVertex()) ?
nodes.FindId(v4, v1) : -1;
1664 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3, mid[3] = e4; }
1667 int midf1 = -1, midf2 = -1;
1668 if (e1 >= 0 && e3 >= 0) { midf1 =
nodes.FindId(e1, e3); }
1669 if (e2 >= 0 && e4 >= 0) { midf2 =
nodes.FindId(e2, e4); }
1672 MFEM_ASSERT(!(midf1 >= 0 && midf2 >= 0),
"incorrectly split face!");
1674 if (midf1 < 0 && midf2 < 0) {
return 0; }
1675 else if (midf1 >= 0) {
return 1; }
1681 for (
int i = 0; i < 8; i++)
1683 if (el.
node[i] == node) {
return i; }
1685 MFEM_ABORT(
"Node not found.");
1693 for (
int i = 0; i < gi.
ne; i++)
1695 const int* ev = gi.
edges[i];
1696 int n0 = el.
node[ev[0]];
1697 int n1 = el.
node[ev[1]];
1698 if ((n0 == vn0 && n1 == vn1) ||
1699 (n0 == vn1 && n1 == vn0)) {
return i; }
1701 MFEM_ABORT(
"Edge not found");
1707 for (
int i = 0; i < 6; i++)
1710 if ((a == fv[0] || a == fv[1] || a == fv[2] || a == fv[3]) &&
1711 (b == fv[0] || b == fv[1] || b == fv[2] || b == fv[3]) &&
1712 (c == fv[0] || c == fv[1] || c == fv[2] || c == fv[3]))
1717 MFEM_ABORT(
"Face not found.");
1735 for (
int i = 0, j; i < 4; i++)
1737 for (j = 0; j < 4; j++)
1739 if (fv[i] == master[j])
1742 for (
int k = 0; k < mat.
Height(); k++)
1744 mat(k,i) = tmp(k,j);
1749 MFEM_ASSERT(j != 4,
"node not found.");
1760 Face* fa =
faces.Find(vn0, vn1, vn2, vn3);
1783 Point mid0(pm(0), pm(1)), mid2(pm(2), pm(3));
1791 else if (split == 2)
1793 Point mid1(pm(1), pm(2)), mid3(pm(3), pm(0));
1808 if (
Dim < 3) {
return; }
1811 processed_faces = 0;
1818 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
1821 for (
int j = 0; j < gi.
nf; j++)
1825 for (
int k = 0; k < 4; k++)
1830 int face =
faces.FindId(node[0], node[1], node[2], node[3]);
1831 MFEM_ASSERT(face >= 0,
"face not found!");
1837 if (processed_faces[face]) {
continue; }
1838 processed_faces[face] = 1;
1841 if (fa.
elem[0] >= 0 && fa.
elem[1] >= 0)
1853 TraverseFace(node[0], node[1], node[2], node[3], pm, 0);
1862 for (
int i = sb; i < se; i++)
1877 int mid =
nodes.FindId(vn0, vn1);
1878 if (mid < 0) {
return; }
1881 if (nd.
HasEdge() && level > 0)
1893 int v0index =
nodes[vn0].vert_index;
1894 int v1index =
nodes[vn1].vert_index;
1895 if (v0index > v1index) { sl.
edge_flags |= 2; }
1900 Face* fa =
faces.Find(vn0, vn0, vn1, vn1);
1901 MFEM_ASSERT(fa != NULL,
"");
1908 double tmid = (t0 + t1) / 2;
1922 processed_edges = 0;
1933 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
1936 for (
int j = 0; j < gi.
ne; j++)
1939 const int* ev = gi.
edges[j];
1940 int node[2] = { el.
node[ev[0]], el.
node[ev[1]] };
1942 int enode =
nodes.FindId(node[0], node[1]);
1943 MFEM_ASSERT(enode >= 0,
"edge node not found!");
1946 MFEM_ASSERT(nd.
HasEdge(),
"edge not found!");
1954 int face =
faces.FindId(node[0], node[0], node[1], node[1]);
1955 MFEM_ASSERT(face >= 0,
"face not found!");
1967 if (processed_edges[enode]) {
continue; }
1968 processed_edges[enode] = 1;
1971 double t0 = 0.0, t1 = 1.0;
1972 int v0index =
nodes[node[0]].vert_index;
1973 int v1index =
nodes[node[1]].vert_index;
1974 int flags = (v0index > v1index) ? 1 : 0;
1987 for (
int i = sb; i < se; i++)
2004 int local = edge_local[sl.
index];
2021 processed_vertices = 0;
2029 for (
int j = 0; j <
GI[(int) el.
geom].
nv; j++)
2031 int node = el.
node[j];
2039 if (processed_vertices[index]) {
continue; }
2040 processed_vertices[index] = 1;
2050 oriented_matrix = point_matrix;
2054 MFEM_ASSERT(oriented_matrix.
Height() == 1 &&
2055 oriented_matrix.
Width() == 2,
"not an edge point matrix");
2059 oriented_matrix(0,0) = 1.0 - oriented_matrix(0,0);
2060 oriented_matrix(0,1) = 1.0 - oriented_matrix(0,1);
2064 std::swap(oriented_matrix(0,0), oriented_matrix(0,1));
2082 slaves.swap(empty.
slaves);
2084 inv_index.DeleteAll();
2089 return conforming.size() + masters.size() + slaves.size();
2094 if (!inv_index.Size())
2097 for (
unsigned i = 0; i < conforming.size(); i++)
2099 max_index = std::max(conforming[i].index, max_index);
2101 for (
unsigned i = 0; i < masters.size(); i++)
2103 max_index = std::max(masters[i].index, max_index);
2105 for (
unsigned i = 0; i < slaves.size(); i++)
2107 max_index = std::max(slaves[i].index, max_index);
2110 inv_index.SetSize(max_index + 1);
2113 for (
unsigned i = 0; i < conforming.size(); i++)
2115 inv_index[conforming[i].index] = (i << 2);
2117 for (
unsigned i = 0; i < masters.size(); i++)
2119 inv_index[masters[i].index] = (i << 2) + 1;
2121 for (
unsigned i = 0; i < slaves.size(); i++)
2123 inv_index[slaves[i].index] = (i << 2) + 2;
2127 MFEM_ASSERT(index >= 0 && index < inv_index.Size(),
"");
2128 int key = inv_index[index];
2129 MFEM_VERIFY(key >= 0,
"entity not found.");
2131 if (type) { *type = key & 0x3; }
2135 case 0:
return conforming[key >> 2];
2136 case 1:
return masters[key >> 2];
2137 case 2:
return slaves[key >> 2];
2138 default: MFEM_ABORT(
"internal error");
return conforming[0];
2147 int mid =
nodes.FindId(v0, v1);
2148 if (mid >= 0 &&
nodes[mid].HasVertex())
2184 int* I =
new int[nrows + 1];
2185 int** JJ =
new int*[nrows];
2195 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
2198 int* node = el.
node;
2201 for (
int j = 0; j < gi.
ne; j++)
2203 const int* ev = gi.
edges[j];
2209 for (
int j = 0; j < gi.
nf; j++)
2211 const int* fv = gi.
faces[j];
2213 node[fv[2]], node[fv[3]], indices);
2220 int size = indices.
Size();
2222 JJ[i] =
new int[size];
2223 memcpy(JJ[i], indices.
GetData(), size *
sizeof(int));
2228 for (
int i = 0; i < nrows; i++)
2237 int *J =
new int[nnz];
2239 for (
int i = 0; i < nrows; i++)
2241 int cnt = I[i+1] - I[i];
2242 memcpy(J+nnz, JJ[i], cnt *
sizeof(
int));
2269 MFEM_VERIFY(elem_set.
Size() == nleaves,
"");
2278 for (
int i = 0; i < nleaves; i++)
2284 for (
int j = 0; j < nv; j++)
2291 for (
int j = 0; j < nv; j++)
2293 vmark[el.
node[j]] = 1;
2304 neighbor_set->
SetSize(nleaves);
2308 for (
int i = 0; i < nleaves; i++)
2316 for (
int j = 0; j < nv; j++)
2318 if (vmark[v[j]]) { hit =
true;
break; }
2325 for (
int j = 0; j < nv; j++)
2327 if (vmark[el.
node[j]]) { hit =
true;
break; }
2334 if (neighbor_set) { (*neighbor_set)[i] = 1; }
2340 static bool sorted_lists_intersect(
const int* a,
const int* b,
int na,
int nb)
2342 if (!na || !nb) {
return false; }
2343 int a_last = a[na-1], b_last = b[nb-1];
2344 if (*b < *a) {
goto l2; }
2346 if (a_last < *b) {
return false; }
2347 while (*a < *b) { a++; }
2348 if (*a == *b) {
return true; }
2350 if (b_last < *a) {
return false; }
2351 while (*b < *a) { b++; }
2352 if (*a == *b) {
return true; }
2375 while (stack.
Size())
2384 for (
int i = 0; i < nv; i++)
2390 for (
int i = 0; i < nv; i++)
2397 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
2408 int nv1 = vert.
Size();
2413 for (
int i = 0; i < search_set->
Size(); i++)
2415 int testme = (*search_set)[i];
2422 bool hit = sorted_lists_intersect(v1, v2, nv1, nv2);
2427 for (
int j = 0; j < nv; j++)
2429 hit = sorted_lists_intersect(&el.
node[j], v1, 1, nv1);
2434 if (hit) { neighbors.
Append(testme); }
2448 for (
int i = 0; i < elems.
Size(); i++)
2454 for (
int j = 0; j < nv; j++)
2460 for (
int j = 0; j < nv; j++)
2462 vmark[el.
node[j]] = 1;
2472 for (
int i = 0; i < search_set->
Size(); i++)
2474 int testme = (*search_set)[i];
2480 for (
int j = 0; j < nv; j++)
2482 if (vmark[v[j]]) { hit =
true;
break; }
2488 for (
int j = 0; j < nv; j++)
2490 if (vmark[el.
node[j]]) { hit =
true;
break; }
2494 if (hit) { expanded.
Append(testme); }
2504 for (
int i = 0; i < np; i++)
2506 for (
int j = 0; j < points[0].dim; j++)
2508 point_matrix(j, i) = points[i].coord[j];
2520 Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
2521 Point(0, 0, 1),
Point(1, 0, 1),
Point(1, 1, 1),
Point(0, 1, 1)
2532 MFEM_ABORT(
"unsupported geometry.");
2543 int ref_type = *ref_path++;
2544 int child = *ref_path++;
2550 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
2551 Point mid67(pm(6), pm(7)), mid45(pm(4), pm(5));
2556 pm(4), mid45, mid67, pm(7));
2558 else if (child == 1)
2561 mid45, pm(5), pm(6), mid67);
2564 else if (ref_type == 2)
2566 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
2567 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
2572 pm(4), pm(5), mid56, mid74);
2574 else if (child == 1)
2577 mid74, mid56, pm(6), pm(7));
2580 else if (ref_type == 4)
2582 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
2583 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
2588 mid04, mid15, mid26, mid37);
2590 else if (child == 1)
2593 pm(4), pm(5), pm(6), pm(7));
2596 else if (ref_type == 3)
2598 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
2599 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
2600 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
2601 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
2603 Point midf0(mid23, mid12, mid01, mid30);
2604 Point midf5(mid45, mid56, mid67, mid74);
2609 pm(4), mid45, midf5, mid74);
2611 else if (child == 1)
2614 mid45, pm(5), mid56, midf5);
2616 else if (child == 2)
2619 midf5, mid56, pm(6), mid67);
2621 else if (child == 3)
2624 mid74, midf5, mid67, pm(7));
2627 else if (ref_type == 5)
2629 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
2630 Point mid45(pm(4), pm(5)), mid67(pm(6), pm(7));
2631 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
2632 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
2634 Point midf1(mid01, mid15, mid45, mid04);
2635 Point midf3(mid23, mid37, mid67, mid26);
2640 mid04, midf1, midf3, mid37);
2642 else if (child == 1)
2645 midf1, mid15, mid26, midf3);
2647 else if (child == 2)
2650 mid45, pm(5), pm(6), mid67);
2652 else if (child == 3)
2655 pm(4), mid45, mid67, pm(7));
2658 else if (ref_type == 6)
2660 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
2661 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
2662 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
2663 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
2665 Point midf2(mid12, mid26, mid56, mid15);
2666 Point midf4(mid30, mid04, mid74, mid37);
2671 mid04, mid15, midf2, midf4);
2673 else if (child == 1)
2676 midf4, midf2, mid26, mid37);
2678 else if (child == 2)
2681 pm(4), pm(5), mid56, mid74);
2683 else if (child == 3)
2686 mid74, mid56, pm(6), pm(7));
2689 else if (ref_type == 7)
2691 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
2692 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
2693 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
2694 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
2695 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
2696 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
2698 Point midf0(mid23, mid12, mid01, mid30);
2699 Point midf1(mid01, mid15, mid45, mid04);
2700 Point midf2(mid12, mid26, mid56, mid15);
2701 Point midf3(mid23, mid37, mid67, mid26);
2702 Point midf4(mid30, mid04, mid74, mid37);
2703 Point midf5(mid45, mid56, mid67, mid74);
2705 Point midel(midf1, midf3);
2710 mid04, midf1, midel, midf4);
2712 else if (child == 1)
2715 midf1, mid15, midf2, midel);
2717 else if (child == 2)
2720 midel, midf2, mid26, midf3);
2722 else if (child == 3)
2725 midf4, midel, midf3, mid37);
2727 else if (child == 4)
2730 pm(4), mid45, midf5, mid74);
2732 else if (child == 5)
2735 mid45, pm(5), mid56, midf5);
2737 else if (child == 6)
2740 midf5, mid56, pm(6), mid67);
2742 else if (child == 7)
2745 mid74, midf5, mid67, pm(7));
2753 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
2759 else if (child == 1)
2764 else if (ref_type == 2)
2766 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
2772 else if (child == 1)
2777 else if (ref_type == 3)
2779 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
2780 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
2781 Point midel(mid01, mid23);
2787 else if (child == 1)
2791 else if (child == 2)
2795 else if (child == 3)
2803 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
2809 else if (child == 1)
2813 else if (child == 2)
2817 else if (child == 3)
2825 for (
int i = 0; i < pm.
np; i++)
2827 for (
int j = 0; j < pm(i).dim; j++)
2829 matrix(j, i) = pm(i).coord[j];
2854 int &matrix = map[ref_path];
2855 if (!matrix) { matrix = map.size(); }
2858 emb.
parent = coarse_index;
2864 ref_path.push_back(0);
2866 for (
int i = 0; i < 8; i++)
2868 if (el.
child[i] >= 0)
2870 ref_path[ref_path.length()-1] = i;
2874 ref_path.resize(ref_path.length()-2);
2881 "GetRefinementTransforms() must be preceded by MarkCoarseLevel()"
2888 std::string ref_path;
2889 ref_path.reserve(100);
2906 for (RefPathMap::iterator it = map.begin(); it != map.end(); ++it)
2918 "GetDerefinementTransforms() must be preceded by Derefine().");
2922 std::map<int, int> mat_no;
2931 int &matrix = mat_no[code];
2932 if (!matrix) { matrix = mat_no.size(); }
2943 std::map<int, int>::iterator it;
2944 for (it = mat_no.begin(); it != mat_no.end(); ++it)
2947 int code = it->first;
2948 path[0] = code >> 3;
2974 int n0 = el.
node[ev[0]], n1 = el.
node[ev[1]];
2975 if (n0 > n1) { std::swap(n0, n1); }
2977 vert_index[0] =
nodes[n0].vert_index;
2978 vert_index[1] =
nodes[n1].vert_index;
2980 if (vert_index[0] > vert_index[1])
2982 std::swap(vert_index[0], vert_index[1]);
2992 int v0 =
nodes[el.
node[ev[0]]].vert_index;
2993 int v1 =
nodes[el.
node[ev[1]]].vert_index;
2995 return ((v0 < v1 && ev[0] > ev[1]) || (v0 > v1 && ev[0] < ev[1])) ? -1 : 1;
2999 int vert_index[4],
int edge_index[4],
3000 int edge_orientation[4])
const
3005 for (
int i = 0; i < 4; i++)
3007 vert_index[i] =
nodes[el.
node[fv[i]]].vert_index;
3010 for (
int i = 0; i < 4; i++)
3012 int j = (i+1) & 0x3;
3013 int n1 = el.
node[fv[i]];
3014 int n2 = el.
node[fv[j]];
3017 MFEM_ASSERT(en != NULL,
"edge not found.");
3020 edge_orientation[i] = (vert_index[i] < vert_index[j]) ? 1 : -1;
3026 MFEM_ASSERT(node >= 0,
"edge node not found.");
3029 int p1 = nd.
p1, p2 = nd.
p2;
3030 MFEM_ASSERT(p1 != p2,
"invalid edge node.");
3034 int n1p1 = n1.
p1, n1p2 = n1.
p2;
3035 int n2p1 = n2.p1, n2p2 = n2.p2;
3037 if ((n2p1 != n2p2) && (p1 == n2p1 || p1 == n2p2))
3041 if (n2.HasEdge()) {
return p2; }
3045 if ((n1p1 != n1p2) && (p2 == n1p1 || p2 == n1p2))
3049 if (n1.
HasEdge()) {
return p1; }
3059 MFEM_ASSERT(node >= 0 &&
nodes[node].HasEdge(),
"(v1, v2) is not an edge.");
3062 return (master >= 0) ?
nodes[master].edge_index : -1;
3068 int depth = 0, parent;
3069 while ((parent =
elements[elem].parent) != -1)
3084 int elem = fa.
elem[0];
3085 if (elem < 0) { elem = fa.
elem[1]; }
3086 MFEM_ASSERT(elem >= 0,
"Face has no elements?");
3094 for (
int i = 0; i < 4; i++)
3096 node[i] = el.
node[fv[i]];
3113 if (bdr_attr_is_ess[
faces[face].attribute - 1])
3118 for (
int j = 0; j < 4; j++)
3122 int enode =
nodes.FindId(node[j], node[(j+1) % 4]);
3123 MFEM_ASSERT(enode >= 0 &&
nodes[enode].HasEdge(),
"Edge not found.");
3152 bdr_vertices.
Sort();
3161 int mid =
nodes.FindId(vn1, vn2);
3162 if (mid < 0 || !
nodes[mid].HasVertex()) {
return 0; }
3167 int& h_level,
int& v_level)
const
3169 int hl1, hl2, vl1, vl2;
3175 h_level = v_level = 0;
3181 h_level = std::max(hl1, hl2);
3182 v_level = std::max(vl1, vl2) + 1;
3188 h_level = std::max(hl1, hl2) + 1;
3189 v_level = std::max(vl1, vl2);
3193 static int max8(
int a,
int b,
int c,
int d,
int e,
int f,
int g,
int h)
3195 return std::max(std::max(std::max(a, b), std::max(c, d)),
3196 std::max(std::max(e, f), std::max(g, h)));
3202 const int* node = el.
node;
3206 for (
int i = 0; i < gi.
ne; i++)
3208 const int* ev = gi.
edges[i];
3215 for (
int i = 0; i < gi.
nf; i++)
3217 const int* fv = gi.
faces[i];
3218 FaceSplitLevel(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]],
3219 flevel[i][1], flevel[i][0]);
3222 splits[0] = max8(flevel[0][0], flevel[1][0], flevel[3][0], flevel[5][0],
3223 elevel[0], elevel[2], elevel[4], elevel[6]);
3225 splits[1] = max8(flevel[0][1], flevel[2][0], flevel[4][0], flevel[5][1],
3226 elevel[1], elevel[3], elevel[5], elevel[7]);
3228 splits[2] = max8(flevel[1][1], flevel[2][1], flevel[3][1], flevel[4][1],
3229 elevel[8], elevel[9], elevel[10], elevel[11]);
3233 splits[0] = std::max(elevel[0], elevel[2]);
3234 splits[1] = std::max(elevel[1], elevel[3]);
3238 splits[0] = std::max(elevel[0], std::max(elevel[1], elevel[2]));
3239 splits[1] = splits[0];
3243 MFEM_ABORT(
"Unsupported element geometry.");
3257 for (
int k = 0; k <
Dim; k++)
3259 if (splits[k] > max_level)
3261 ref_type |= (1 << k);
3279 MFEM_VERIFY(max_nc_level >= 1,
"'max_nc_level' must be 1 or greater.");
3286 if (!refinements.
Size()) {
break; }
3298 if (node->HasVertex() && node->p1 != node->p2) { nv++; }
3305 if (node->HasVertex() && node->p1 != node->p2)
3313 out << node->vert_index <<
" "
3326 input >>
id >> p1 >> p2;
3327 MFEM_VERIFY(input,
"problem reading vertex parents.");
3329 MFEM_VERIFY(
nodes.IdExists(
id),
"vertex " <<
id <<
" not found.");
3330 MFEM_VERIFY(
nodes.IdExists(p1),
"parent " << p1 <<
" not found.");
3331 MFEM_VERIFY(
nodes.IdExists(p2),
"parent " << p2 <<
" not found.");
3334 nodes.Reparent(
id, p1, p2);
3343 int num_top_level = 0;
3346 if (node->p1 == node->p2)
3348 MFEM_VERIFY(node.index() == node->p1,
"invalid top-level vertex.");
3349 MFEM_VERIFY(node->HasVertex(),
"top-level vertex not found.");
3350 MFEM_VERIFY(node->vert_index == node->p1,
"bad top-level vertex index");
3351 num_top_level = std::max(num_top_level, node->p1 + 1);
3356 for (
int i = 0; i < num_top_level; i++)
3362 static int ref_type_num_children[8] = { 0, 2, 2, 4, 2, 4, 4, 8 };
3369 int child_id[8], nch = 0;
3370 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
3374 MFEM_ASSERT(nch == ref_type_num_children[(
int) el.
ref_type],
"");
3377 for (
int i = 0; i < nch; i++)
3379 out <<
" " << child_id[i];
3411 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
3413 int old_id = el.
child[i];
3415 int new_id =
elements.Append(tmp_elements[old_id]);
3416 index_map[old_id] = new_id;
3417 el.
child[i] = new_id;
3441 if (
Dim == 3 && ref_type != 7) { iso =
false; }
3444 int nch = ref_type_num_children[ref_type];
3445 for (
int i = 0,
id; i < nch; i++)
3448 MFEM_VERIFY(
id >= 0,
"");
3451 "coarse element cannot be referenced before it is "
3452 "defined (id=" <<
id <<
").");
3455 MFEM_VERIFY(child.parent == -1,
3456 "element " <<
id <<
" cannot have two parents.");
3459 child.parent = elem;
3463 el.
geom = child.geom;
3481 if (el->parent == -1)
3484 index_map[el.index()] = new_id;
3498 for (
int i = 0; i < 2; i++)
3500 if (face->elem[i] >= 0)
3502 face->elem[i] = index_map[face->elem[i]];
3503 MFEM_ASSERT(face->elem[i] >= 0,
"");
3531 pmsize = slaves[0].point_matrix.MemoryUsage();
3534 return conforming.capacity() *
sizeof(
MeshId) +
3535 masters.capacity() *
sizeof(
Master) +
3536 slaves.capacity() *
sizeof(
Slave) +
3537 slaves.size() * pmsize;
3542 return point_matrices.MemoryUsage() + embeddings.MemoryUsage();
3547 return nodes.MemoryUsage() +
3548 faces.MemoryUsage() +
3581 <<
ref_stack.MemoryUsage() <<
" ref_stack\n"
3585 <<
sizeof(*this) <<
" NCMesh"
3593 static const double MiB = 1024.*1024.;
3595 "NCMesh statistics:\n"
3596 "------------------\n"
3597 " mesh and space dimensions : " <<
Dim <<
", " <<
spaceDim <<
"\n"
3598 " isotropic only : " << (
Iso ?
"yes" :
"no") <<
"\n"
3599 " number of Nodes : " << std::setw(9)
3600 <<
nodes.Size() <<
" + [ " << std::setw(9)
3601 <<
nodes.MemoryUsage()/MiB <<
" MiB ]\n"
3602 " free " << std::setw(9)
3603 <<
nodes.NumFreeIds() <<
"\n"
3604 " number of Faces : " << std::setw(9)
3605 <<
faces.Size() <<
" + [ " << std::setw(9)
3606 <<
faces.MemoryUsage()/MiB <<
" MiB ]\n"
3607 " free " << std::setw(9)
3608 <<
faces.NumFreeIds() <<
"\n"
3609 " number of Elements : " << std::setw(9)
3613 " free " << std::setw(9)
3615 " number of root elements : " << std::setw(9) <<
root_count <<
"\n"
3616 " number of leaf elements : " << std::setw(9)
3618 " number of vertices : " << std::setw(9)
3620 " number of faces : " << std::setw(9)
3623 " conforming " << std::setw(9)
3625 " master " << std::setw(9)
3627 " slave " << std::setw(9)
3629 " number of edges : " << std::setw(9)
3632 " conforming " << std::setw(9)
3634 " master " << std::setw(9)
3636 " slave " << std::setw(9)
3638 " total memory : " << std::setw(17)
3639 <<
"[ " << std::setw(9) <<
MemoryUsage()/MiB <<
" MiB ]\n"
3648 out <<
nodes.Size() <<
"\n";
3652 out << node.index() <<
" "
3653 << pos[0] <<
" " << pos[1] <<
" " << pos[2] <<
" "
3654 << node->p1 <<
" " << node->p2 <<
" "
3655 << node->vert_index <<
" " << node->edge_index <<
" "
3663 for (
int i = 0; i <
elements.Size(); i++)
3668 out << nleaves <<
"\n";
3669 for (
int i = 0; i <
elements.Size(); i++)
3674 out << gi.
nv <<
" ";
3675 for (
int j = 0; j < gi.
nv; j++)
3677 out << el.
node[j] <<
" ";
3684 out <<
faces.Size() <<
"\n";
3687 int elem = face->elem[0];
3688 if (elem < 0) { elem = face->elem[1]; }
3689 MFEM_ASSERT(elem >= 0,
"");
3698 for (
int i = 0; i < 4; i++)
3700 out <<
" " << el.
node[fv[i]];
NCList face_list
lazy-initialized list of faces, see GetFaceList
void CollectLeafElements(int elem, int state)
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
NCMesh(const Mesh *mesh, std::istream *vertex_parents=NULL)
int Size() const
Logical size of the array.
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
int NewQuadrilateral(int n0, int n1, int n2, int n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
int elem[2]
up to 2 elements sharing the face
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
char ref_type
refinement XYZ bit mask (7 = full isotropic)
Array< double > top_vertex_pos
Table * GetEdgeVertexTable() const
Returns the edge-to-vertex Table (3D)
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
const CoarseFineTransformations & GetDerefinementTransforms()
virtual int GetNEdges() const =0
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void PrintVertexParents(std::ostream &out) const
I/O: Print the "vertex_parents" section of the mesh file (ver. >= 1.1).
void GetPointMatrix(int geom, const char *ref_path, DenseMatrix &matrix)
virtual void LimitNCLevel(int max_nc_level)
void GetFaceVerticesEdges(const MeshId &face_id, int vert_index[4], int edge_index[4], int edge_orientation[4]) const
Return Mesh vertex and edge indices of a face identified by 'face_id'.
int GetNBE() const
Returns number of boundary elements.
virtual void Trim()
Save memory by releasing all non-essential and cached data.
int index
element number in the Mesh, -1 if refined
void CopyElements(int elem, const BlockArray< Element > &tmp_elements, Array< int > &index_map)
void ForceRefinement(int vn1, int vn2, int vn3, int vn4)
virtual int GetNumGhostElements() const
Lists all edges/faces in the nonconforming mesh.
void GetMeshComponents(Array< mfem::Vertex > &mvertices, Array< mfem::Element * > &melements, Array< mfem::Element * > &mboundary) const
Return the basic Mesh arrays for the current finest level.
int Size() const
Return the number of items actually stored.
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Copy(Array ©) const
Create a copy of the current array.
void TraverseEdge(int vn0, int vn1, double t0, double t1, int flags, int level)
T * GetData()
Returns the data.
void ClearTransforms()
Free all internal data created by the above three functions.
Table derefinements
possible derefinements, see GetDerefinementTable
Data type dense matrix using column-major storage.
void CollectFaceVertices(int v0, int v1, int v2, int v3, Array< int > &indices)
NCList vertex_list
lazy-initialized list of vertices, see GetVertexList
void InitDerefTransforms()
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
char geom
Geometry::Type of the element.
void GetEdgeVertices(const MeshId &edge_id, int vert_index[2]) const
Return Mesh vertex indices of an edge identified by 'edge_id'.
int GetEdgeNCOrientation(const MeshId &edge_id) const
void SetSize(int i, int j, int k)
int GetNE() const
Returns number of elements.
void OrientedPointMatrix(DenseMatrix &oriented_matrix) const
Return the point matrix oriented according to the master and slave edges.
const Element * GetFace(int i) const
void CheckAnisoFace(int vn1, int vn2, int vn3, int vn4, int mid12, int mid34, int level=0)
virtual int GetNumGhostVertices() const
static PointMatrix pm_tri_identity
void CountSplits(int elem, int splits[3]) const
void CollectDerefinements(int elem, Array< Connection > &list)
std::vector< MeshId > conforming
Data type quadrilateral element.
void GetLimitRefinements(Array< Refinement > &refinements, int max_level)
int PrintMemoryDetail() const
int spaceDim
dimensions of the elements and the vertex coordinates
Array< int > vertex_nodeId
int attribute
boundary element attribute, -1 if internal face
void DebugDump(std::ostream &out) const
void FindFaceNodes(int face, int node[4])
int GetGeometryType() const
void DeleteAll()
Delete whole array.
int index
Mesh element number.
const NCList & GetFaceList()
Return the current list of conforming and nonconforming faces.
const MeshId & LookUp(int index, int *type=NULL) const
virtual void ElementSharesEdge(int elem, int enode)
virtual void OnMeshUpdated(Mesh *mesh)
void CollectEdgeVertices(int v0, int v1, Array< int > &indices)
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
virtual bool IsGhost(const Element &el) const
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void CheckIsoFace(int vn1, int vn2, int vn3, int vn4, int en1, int en2, int en3, int en4, int midf)
Data type hexahedron element.
Face * GetFace(Element &elem, int face_no)
void TraverseRefinements(int elem, int coarse_index, std::string &ref_path, RefPathMap &map)
virtual const int * GetEdgeVertices(int) const =0
int PrintElements(std::ostream &out, int elem, int &coarse_id) 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 Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int local
local number within 'element'
int FindAltParents(int node1, int node2)
int Append(const T &el)
Append element to array, resize if necessary.
void GetMatrix(DenseMatrix &point_matrix) const
int AddElement(const Element &el)
bool NodeSetY1(int node, int *n)
virtual void Derefine(const Array< int > &derefs)
void FindNeighbors(int elem, Array< int > &neighbors, const Array< int > *search_set=NULL)
std::vector< Master > masters
Array< int > coarse_elements
state of leaf_elements before Refine(), set by MarkCoarseLevel()
virtual void UpdateVertices()
update Vertex::index and vertex_nodeId
void RegisterFaces(int elem, int *fattr=NULL)
Element(int geom, int attr)
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
virtual void BuildEdgeList()
const CoarseFineTransformations & GetRefinementTransforms()
int GetAttribute() const
Return element's attribute.
void LoadCoarseElements(std::istream &input)
I/O: Load the element refinement hierarchy from a 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
Data type triangle element.
const Element * GetElement(int i) const
void Sort()
Sorts the array. This requires operator< to be defined for T.
int Size() const
Returns the number of TYPE I elements.
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
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.
static GeomInfo GI[Geometry::NumGeom]
void Clear(bool hard=false)
bool NodeSetY2(int node, int *n)
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
void DeleteUnusedFaces(const Array< int > &elemFaces)
virtual void ElementSharesFace(int elem, int face)
int SpaceDimension() const
bool Iso
true if the mesh only contains isotropic refinements
std::map< std::string, int > RefPathMap
int FaceSplitType(int v1, int v2, int v3, int v4, int mid[4]=NULL) const
std::vector< Slave > slaves
virtual void BuildFaceList()
Nonconforming edge/face within a bigger edge/face.
void DerefineElement(int elem)
int ReorderFacePointMat(int v0, int v1, int v2, int v3, int elem, DenseMatrix &mat) const
void SetVertexPositions(const Array< mfem::Vertex > &vertices)
I/O: Set positions of all vertices (used by mesh loader).
int edge_flags
edge orientation flags
void RegisterElement(int e)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
static const PointMatrix & GetGeomIdentity(int geom)
mfem::Element * NewMeshElement(int geom) const
void DeleteLast()
Delete the last entry.
Helper struct for defining a connectivity table, see Table::MakeFromList.
void UpdateLeafElements()
bool NodeSetZ2(int node, int *n)
static GeomInfo & gi_quad
void BuildElementToVertexTable()
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
bool NodeSetZ1(int node, int *n)
void ForgetElement(int e)
int GetMidFaceNode(int en1, int en2, int en3, int en4)
void RefineElement(int elem, char ref_type)
virtual int GetNFaces(int &nFaceVertices) const =0
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)
Array< int > boundary_faces
subset of all faces, set by BuildFaceList
int child[8]
2-8 children (if ref_type != 0)
Array< int > leaf_elements
static PointMatrix pm_quad_identity
void TraverseFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level)
int EdgeSplitLevel(int vn1, int vn2) const
void SetIJ(int *newI, int *newJ, int newsize=-1)
static int find_element_edge(const Element &el, int vn0, int vn1)
void Initialize(const mfem::Element *elem)
Array< int > free_element_ids
bool NodeSetX2(int node, int *n)
virtual int GetNVertices() const =0
int parent
element index in the coarse mesh
void SetAttribute(const int attr)
Set element's attribute.
virtual void AssignLeafIndices()
virtual void ElementSharesVertex(int elem, int vnode)
static PointMatrix pm_hex_identity
static int find_hex_face(int a, int b, int c)
virtual const int * GetFaceVertices(int fi) const =0
virtual void CheckDerefinementNCLevel(const Table &deref_table, Array< int > &level_ok, int max_nc_level)
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
void FindSetNeighbors(const Array< char > &elem_set, Array< int > *neighbors, Array< char > *neighbor_set=NULL)
int GetNEdges() const
Return the number of edges.
long MemoryUsage() const
Return total number of bytes allocated.
void PrintCoarseElements(std::ostream &out) const
I/O: Print the "coarse_elements" section of the mesh file (ver. >= 1.1).
virtual void BuildVertexList()
const NCList & GetEdgeList()
Return the current list of conforming and nonconforming edges.
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void UpdateElementToVertexTable()
int GetElementDepth(int i) const
Return the distance of leaf 'i' from the root.
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)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
static int find_node(const Element &el, int node)
void LoadVertexParents(std::istream &input)
int GetMidEdgeNode(int vn1, int vn2)
Abstract data type element.
void UnrefElement(int elem, Array< int > &elemFaces)
Data type line segment element.
void PrintStats(std::ostream &out=mfem::out) const
int GetSingleElement() const
Return one of elem[0] or elem[1] and make sure the other is -1.
const double * CalcVertexPos(int node) const
int rank
processor number (ParNCMesh), -1 if undefined/unknown
bool NodeSetX1(int node, int *n)
int node[8]
element corners (if ref_type == 0)
const Element * GetBdrElement(int i) const
virtual int GetType() const =0
Returns element's type.
DenseMatrix point_matrix
position within the master edge/face
Defines the position of a fine element within a coarse element.
void RefElement(int elem)
void FaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
virtual void Refine(const Array< Refinement > &refinements)
int matrix
index into CoarseFineTransformations::point_matrices
int GetEdgeMaster(int v1, int v2) const