13 #include "../fem/fem.hpp"
14 #include "../general/sort_pairs.hpp"
38 for (
int i = 0; i <
ne; i++)
40 for (
int j = 0; j < 2; j++)
45 for (
int i = 0; i <
nf; i++)
50 for (
int j = 0; j <
nfv[i]; j++)
59 for (
int i = 0; i <
ne; i++)
79 Iso = vertex_parents ?
false :
true;
84 for (
int i = 0; i < mesh->
GetNE(); i++)
88 for (
int j = 0; j < nv; j++)
90 max_id = std::max(max_id, v[j]);
93 for (
int id = 0;
id <= max_id;
id++)
96 int node =
nodes.GetId(
id,
id);
97 MFEM_CONTRACT_VAR(node);
98 MFEM_ASSERT(node ==
id,
"");
110 for (
int i = 0; i < mesh->
GetNV(); i++)
117 for (
int i = 0; i < mesh->
GetNE(); i++)
125 "Element type " << geom <<
" not supported by NCMesh.");
132 MFEM_ASSERT(root_id == i,
"");
136 for (
int j = 0; j <
GI[
geom].
nv; j++)
138 root_elem.
node[j] = v[j];
150 for (
int i = 0; i < mesh->
GetNBE(); i++)
157 Face* face =
faces.Find(v[0], v[1], v[2], v[3]);
158 MFEM_VERIFY(face,
"boundary face not found.");
163 Face* face =
faces.Find(v[0], v[1], v[2]);
164 MFEM_VERIFY(face,
"boundary face not found.");
169 Face* face =
faces.Find(v[0], v[0], v[1], v[1]);
170 MFEM_VERIFY(face,
"boundary face not found.");
175 MFEM_ABORT(
"Unsupported boundary element geometry.");
190 , spaceDim(other.spaceDim)
195 , elements(other.elements)
230 for (
int i = 0; i <
elements.Size(); i++)
252 "vert_refc: " << (
int)
vert_refc <<
", edge_refc: "
259 int old_p1 = nd.
p1, old_p2 = nd.
p2;
262 nodes.Reparent(node, new_p1, new_p2);
264 MFEM_ASSERT(
shadow.FindId(old_p1, old_p2) < 0,
265 "shadow node already exists");
268 int sh =
shadow.GetId(old_p1, old_p2);
269 shadow[sh].vert_index = node;
274 int mid =
nodes.FindId(node1, node2);
275 if (mid < 0 &&
shadow.Size())
279 mid =
shadow.FindId(node1, node2);
282 mid =
shadow[mid].vert_index;
291 if (mid < 0) { mid =
nodes.GetId(node1, node2); }
299 if (midf >= 0) {
return midf; }
300 return nodes.GetId(en2, en4);
310 for (
int i = 0; i < gi.
nv; i++)
312 nodes[node[i]].vert_refc++;
316 for (
int i = 0; i < gi.
ne; i++)
318 const int* ev = gi.
edges[i];
319 nodes.Get(node[ev[0]], node[ev[1]])->edge_refc++;
323 for (
int i = 0; i < gi.
nf; i++)
325 const int* fv = gi.
faces[i];
326 faces.GetId(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
341 for (
int i = 0; i < gi.
nf; i++)
343 const int* fv = gi.
faces[i];
344 int face =
faces.FindId(node[fv[0]], node[fv[1]],
345 node[fv[2]], node[fv[3]]);
346 MFEM_ASSERT(face >= 0,
"face not found.");
347 faces[face].ForgetElement(elem);
355 for (
int i = 0; i < gi.
ne; i++)
357 const int* ev = gi.
edges[i];
359 MFEM_ASSERT(enode >= 0,
"edge not found.");
360 MFEM_ASSERT(
nodes.IdExists(enode),
"edge does not exist.");
361 if (!
nodes[enode].UnrefEdge())
368 for (
int i = 0; i < gi.
nv; i++)
370 if (!
nodes[node[i]].UnrefVertex())
372 nodes.Delete(node[i]);
382 for (
int i = 0; i < gi.
nf; i++)
385 MFEM_ASSERT(face,
"face not found.");
387 if (fattr) { face->
attribute = fattr[i]; }
393 for (
int i = 0; i < elemFaces.
Size(); i++)
395 if (
faces[elemFaces[i]].Unused())
397 faces.Delete(elemFaces[i]);
404 if (elem[0] < 0) { elem[0] = e; }
405 else if (elem[1] < 0) { elem[1] = e; }
406 else { MFEM_ABORT(
"can't have 3 elements in Face::elem[]."); }
411 if (elem[0] == e) { elem[0] = -1; }
412 else if (elem[1] == e) { elem[1] = -1; }
413 else { MFEM_ABORT(
"element " << e <<
" not found in Face::elem[]."); }
419 const int* fv = gi.
faces[face_no];
420 int* node = elem.
node;
421 return faces.Find(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
428 MFEM_ASSERT(elem[1] < 0,
"not a single element face.");
433 MFEM_ASSERT(elem[1] >= 0,
"no elements in face.");
442 : geom(geom), ref_type(0), tet_type(0), flag(0),
index(-1)
443 , rank(0), attribute(attr), parent(-1)
445 for (
int i = 0; i < 8; i++) {
node[i] = -1; }
454 int n4,
int n5,
int n6,
int n7,
456 int fattr0,
int fattr1,
int fattr2,
457 int fattr3,
int fattr4,
int fattr5)
469 for (
int i = 0; i < gi_hex.
nf; i++)
471 const int* fv = gi_hex.
faces[i];
484 int n3,
int n4,
int n5,
486 int fattr0,
int fattr1,
487 int fattr2,
int fattr3,
int fattr4)
499 for (
int i = 0; i < gi_wedge.
nf; i++)
501 const int* fv = gi_wedge.
faces[i];
516 int fattr0,
int fattr1,
int fattr2,
int fattr3)
527 for (
int i = 0; i < gi_tet.
nf; i++)
529 const int* fv = gi_tet.
faces[i];
543 int eattr0,
int eattr1,
int eattr2,
int eattr3)
554 for (
int i = 0; i < gi_quad.
nf; i++)
556 const int* fv = gi_quad.
faces[i];
568 int attr,
int eattr0,
int eattr1,
int eattr2)
578 for (
int i = 0; i < gi_tri.
nf; i++)
580 const int* fv = gi_tri.
faces[i];
593 {
return node == n[0] || node == n[3] || node == n[4] || node == n[7]; }
596 {
return node == n[1] || node == n[2] || node == n[5] || node == n[6]; }
599 {
return node == n[0] || node == n[1] || node == n[4] || node == n[5]; }
602 {
return node == n[2] || node == n[3] || node == n[6] || node == n[7]; }
605 {
return node == n[0] || node == n[1] || node == n[2] || node == n[3]; }
608 {
return node == n[4] || node == n[5] || node == n[6] || node == n[7]; }
611 {
return node == n[0] || node == n[1] || node == n[2]; }
614 {
return node == n[3] || node == n[4] || node == n[5]; }
620 Face* face =
faces.Find(vn1, vn2, vn3, vn4);
621 if (!face) {
return; }
625 MFEM_ASSERT(!el.
ref_type,
"element already refined.");
648 MFEM_ABORT(
"Inconsistent element/face structure.");
665 MFEM_ABORT(
"Inconsistent element/face structure.");
670 MFEM_ABORT(
"Unsupported geometry.")
683 int ev1 = vn1, ev2 = vn4;
691 vn2 = mid[0]; vn3 = mid[2];
695 vn3 = mid[1]; vn4 = mid[3];
699 const Face *face =
faces.Find(vn1, vn2, vn3, vn4);
700 MFEM_ASSERT(face != NULL,
"Face not found: "
701 << vn1 <<
", " << vn2 <<
", " << vn3 <<
", " << vn4
702 <<
" (edge " << ev1 <<
"-" << ev2 <<
").");
711 for (
int i = 0; i < cousins.
Size(); i++)
730 for (
int i = 0, j; i < eid.
Size(); i++)
732 int elem = eid[i].element;
733 for (j = 0; j < nref; j++)
735 if (refs[j].
index == elem) {
break; }
748 int mid12,
int mid34,
int level)
776 if (mid23 >= 0 && mid41 >= 0)
778 int midf =
nodes.FindId(mid23, mid41);
807 for (
int i = 0; i <
reparents.Size(); i++)
843 int en1,
int en2,
int en3,
int en4,
int midf)
861 if (!ref_type) {
return; }
867 char remaining = ref_type & ~el.
ref_type;
870 for (
int i = 0; i < 8; i++)
888 for (
int i = 0; i < 8; i++) { child[i] = -1; }
893 for (
int i = 0; i < gi.
nf; i++)
895 const int* fv = gi.
faces[i];
896 Face* face =
faces.Find(no[fv[0]], no[fv[1]], no[fv[2]], no[fv[3]]);
925 no[4], mid45, mid67, no[7], attr,
926 fa[0], fa[1], -1, fa[3], fa[4], fa[5]);
929 mid45, no[5], no[6], mid67, attr,
930 fa[0], fa[1], fa[2], fa[3], -1, fa[5]);
937 else if (ref_type == 2)
945 no[4], no[5], mid56, mid74, attr,
946 fa[0], fa[1], fa[2], -1, fa[4], fa[5]);
949 mid74, mid56, no[6], no[7], attr,
950 fa[0], -1, fa[2], fa[3], fa[4], fa[5]);
957 else if (ref_type == 4)
965 mid04, mid15, mid26, mid37, attr,
966 fa[0], fa[1], fa[2], fa[3], fa[4], -1);
969 no[4], no[5], no[6], no[7], attr,
970 -1, fa[1], fa[2], fa[3], fa[4], fa[5]);
977 else if (ref_type == 3)
993 no[4], mid45, midf5, mid74, attr,
994 fa[0], fa[1], -1, -1, fa[4], fa[5]);
997 mid45, no[5], mid56, midf5, attr,
998 fa[0], fa[1], fa[2], -1, -1, fa[5]);
1001 midf5, mid56, no[6], mid67, attr,
1002 fa[0], -1, fa[2], fa[3], -1, fa[5]);
1005 mid74, midf5, mid67, no[7], attr,
1006 fa[0], -1, -1, fa[3], fa[4], fa[5]);
1013 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
1014 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
1016 else if (ref_type == 5)
1032 mid04, midf1, midf3, mid37, attr,
1033 fa[0], fa[1], -1, fa[3], fa[4], -1);
1036 midf1, mid15, mid26, midf3, attr,
1037 fa[0], fa[1], fa[2], fa[3], -1, -1);
1040 mid45, no[5], no[6], mid67, attr,
1041 -1, fa[1], fa[2], fa[3], -1, fa[5]);
1044 no[4], mid45, mid67, no[7], attr,
1045 -1, fa[1], -1, fa[3], fa[4], fa[5]);
1052 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
1053 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
1055 else if (ref_type == 6)
1071 mid04, mid15, midf2, midf4, attr,
1072 fa[0], fa[1], fa[2], -1, fa[4], -1);
1075 midf4, midf2, mid26, mid37, attr,
1076 fa[0], -1, fa[2], fa[3], fa[4], -1);
1079 no[4], no[5], mid56, mid74, attr,
1080 -1, fa[1], fa[2], -1, fa[4], fa[5]);
1083 mid74, mid56, no[6], no[7], attr,
1084 -1, -1, fa[2], fa[3], fa[4], fa[5]);
1091 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
1092 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
1094 else if (ref_type == 7)
1121 mid04, midf1, midel, midf4, attr,
1122 fa[0], fa[1], -1, -1, fa[4], -1);
1125 midf1, mid15, midf2, midel, attr,
1126 fa[0], fa[1], fa[2], -1, -1, -1);
1129 midel, midf2, mid26, midf3, attr,
1130 fa[0], -1, fa[2], fa[3], -1, -1);
1133 midf4, midel, midf3, mid37, attr,
1134 fa[0], -1, -1, fa[3], fa[4], -1);
1137 no[4], mid45, midf5, mid74, attr,
1138 -1, fa[1], -1, -1, fa[4], fa[5]);
1141 mid45, no[5], mid56, midf5, attr,
1142 -1, fa[1], fa[2], -1, -1, fa[5]);
1145 midf5, mid56, no[6], mid67, attr,
1146 -1, -1, fa[2], fa[3], -1, fa[5]);
1149 mid74, midf5, mid67, no[7], attr,
1150 -1, -1, -1, fa[3], fa[4], fa[5]);
1152 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
1153 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
1154 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
1155 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
1156 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
1157 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
1161 MFEM_ABORT(
"invalid refinement type.");
1164 if (ref_type != 7) {
Iso =
false; }
1194 child[0] =
NewWedge(no[0], mid01, mid20,
1195 no[3], mid34, mid53, attr,
1196 fa[0], fa[1], fa[2], -1, fa[4]);
1198 child[1] =
NewWedge(mid01, no[1], mid12,
1199 mid34, no[4], mid45, attr,
1200 fa[0], fa[1], fa[2], fa[3], -1);
1202 child[2] =
NewWedge(mid20, mid12, no[2],
1203 mid53, mid45, no[5], attr,
1204 fa[0], fa[1], -1, fa[3], fa[4]);
1206 child[3] =
NewWedge(mid12, mid20, mid01,
1207 mid45, mid53, mid34, attr,
1208 fa[0], fa[1], -1, -1, -1);
1214 else if (ref_type == 4)
1220 child[0] =
NewWedge(no[0], no[1], no[2],
1221 mid03, mid14, mid25, attr,
1222 fa[0], -1, fa[2], fa[3], fa[4]);
1224 child[1] =
NewWedge(mid03, mid14, mid25,
1225 no[3], no[4], no[5], attr,
1226 -1, fa[1], fa[2], fa[3], fa[4]);
1232 else if (ref_type > 4)
1252 child[0] =
NewWedge(no[0], mid01, mid20,
1253 mid03, midf2, midf4, attr,
1254 fa[0], -1, fa[2], -1, fa[4]);
1256 child[1] =
NewWedge(mid01, no[1], mid12,
1257 midf2, mid14, midf3, attr,
1258 fa[0], -1, fa[2], fa[3], -1);
1260 child[2] =
NewWedge(mid20, mid12, no[2],
1261 midf4, midf3, mid25, attr,
1262 fa[0], -1, -1, fa[3], fa[4]);
1264 child[3] =
NewWedge(mid12, mid20, mid01,
1265 midf3, midf4, midf2, attr,
1266 fa[0], -1, -1, -1, -1);
1268 child[4] =
NewWedge(mid03, midf2, midf4,
1269 no[3], mid34, mid53, attr,
1270 -1, fa[1], fa[2], -1, fa[4]);
1272 child[5] =
NewWedge(midf2, mid14, midf3,
1273 mid34, no[4], mid45, attr,
1274 -1, fa[1], fa[2], fa[3], -1);
1276 child[6] =
NewWedge(midf4, midf3, mid25,
1277 mid53, mid45, no[5], attr,
1278 -1, fa[1], -1, fa[3], fa[4]);
1280 child[7] =
NewWedge(midf3, midf4, midf2,
1281 mid45, mid53, mid34, attr,
1282 -1, fa[1], -1, -1, -1);
1284 CheckIsoFace(no[0], no[1], no[4], no[3], mid01, mid14, mid34, mid03, midf2);
1285 CheckIsoFace(no[1], no[2], no[5], no[4], mid12, mid25, mid45, mid14, midf3);
1286 CheckIsoFace(no[2], no[0], no[3], no[5], mid20, mid03, mid53, mid25, midf4);
1290 MFEM_ABORT(
"invalid refinement type.");
1293 if (ref_type != 7) {
Iso =
false; }
1321 -1, fa[1], fa[2], fa[3]);
1324 fa[0], -1, fa[2], fa[3]);
1327 fa[0], fa[1], -1, fa[3]);
1330 fa[0], fa[1], fa[2], -1);
1389 int mid01 =
nodes.GetId(no[0], no[1]);
1390 int mid23 =
nodes.GetId(no[2], no[3]);
1393 attr, fa[0], -1, fa[2], fa[3]);
1396 attr, fa[0], fa[1], fa[2], -1);
1398 else if (ref_type == 2)
1400 int mid12 =
nodes.GetId(no[1], no[2]);
1401 int mid30 =
nodes.GetId(no[3], no[0]);
1404 attr, fa[0], fa[1], -1, fa[3]);
1407 attr, -1, fa[1], fa[2], fa[3]);
1409 else if (ref_type == 3)
1411 int mid01 =
nodes.GetId(no[0], no[1]);
1412 int mid12 =
nodes.GetId(no[1], no[2]);
1413 int mid23 =
nodes.GetId(no[2], no[3]);
1414 int mid30 =
nodes.GetId(no[3], no[0]);
1416 int midel =
nodes.GetId(mid01, mid23);
1419 attr, fa[0], -1, -1, fa[3]);
1422 attr, fa[0], fa[1], -1, -1);
1425 attr, -1, fa[1], fa[2], -1);
1428 attr, -1, -1, fa[2], fa[3]);
1432 MFEM_ABORT(
"Invalid refinement type.");
1435 if (ref_type != 3) {
Iso =
false; }
1442 int mid01 =
nodes.GetId(no[0], no[1]);
1443 int mid12 =
nodes.GetId(no[1], no[2]);
1444 int mid20 =
nodes.GetId(no[2], no[0]);
1446 child[0] =
NewTriangle(no[0], mid01, mid20, attr, fa[0], -1, fa[2]);
1447 child[1] =
NewTriangle(mid01, no[1], mid12, attr, fa[0], fa[1], -1);
1448 child[2] =
NewTriangle(mid20, mid12, no[2], attr, -1, fa[1], fa[2]);
1449 child[3] =
NewTriangle(mid12, mid20, mid01, attr, -1, -1, -1);
1453 MFEM_ABORT(
"Unsupported element geometry.");
1457 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1470 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1479 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1488 std::memcpy(el.
child, child,
sizeof(el.
child));
1496 for (
int i = refinements.
Size()-1; i >= 0; i--)
1524 #if defined(MFEM_DEBUG) && !defined(MFEM_USE_MPI)
1525 mfem::out <<
"Refined " << refinements.
Size() <<
" + " << nforced
1526 <<
" elements" << std::endl;
1553 MFEM_ASSERT(ch != -1,
"");
1568 MFEM_ABORT(
"Unsupported element geometry.");
1580 std::memcpy(child, el.
child,
sizeof(child));
1583 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1594 for (
int i = 0; i < 8; i++) { el.
node[i] = -1; }
1599 for (
int i = 0; i < 8; i++)
1604 for (
int i = 0; i < 6; i++)
1609 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1614 MFEM_ASSERT(prism_deref_table[rt1][0] != -1,
"invalid prism refinement");
1615 for (
int i = 0; i < 6; i++)
1622 for (
int i = 0; i < 5; i++)
1627 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1632 for (
int i = 0; i < 4; i++)
1639 ch2.
node[fv[2]], ch2.
node[fv[3]])->attribute;
1644 for (
int i = 0; i < 4; i++)
1649 for (
int i = 0; i < 4; i++)
1654 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1659 for (
int i = 0; i < 3; i++)
1665 ch.
node[fv[2]], ch.
node[fv[3]])->attribute;
1670 MFEM_ABORT(
"Unsupported element geometry.");
1682 for (
int i = 0; i < 8 && child[i] >= 0; i++)
1705 int total = 0, ref = 0, ghost = 0;
1706 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1714 if (!ref && ghost < total)
1717 int next_row = list.
Size() ? (list.
Last().from + 1) : 0;
1718 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1726 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
1743 int size = list.
Size() ? (list.
Last().from + 1) : 0;
1752 for (
int i = 0; i < deref_table.
Size(); i++)
1754 const int* fine = deref_table.
GetRow(i), size = deref_table.
RowSize(i);
1758 for (
int j = 0; j < size; j++)
1763 for (
int k = 0; k <
Dim; k++)
1765 if ((parent.
ref_type & (1 << k)) &&
1766 splits[k] >= max_nc_level)
1779 MFEM_VERIFY(
Dim < 3 ||
Iso,
1780 "derefinement of 3D anisotropic meshes not implemented yet.");
1788 for (
int i = 0; i < derefs.
Size(); i++)
1790 int row = derefs[i];
1792 "invalid derefinement number.");
1807 for (
int i = 0; i < fine_coarse.
Size(); i++)
1821 for (
int i = 0; i < nfine; i++)
1832 for (
int i = 0; i < 8 && prn.
child[i] >= 0; i++)
1839 fine_coarse[ch.
index] = parent;
1853 if (node->HasVertex()) { node->vert_index =
NVertices++; }
1880 for (
int i = 0; i < 4; i++)
1882 int ch = quad_hilbert_child_order[state][i];
1883 int st = quad_hilbert_child_state[state][i];
1889 for (
int i = 0; i < 8; i++)
1891 int ch = hex_hilbert_child_order[state][i];
1892 int st = hex_hilbert_child_state[state][i];
1898 for (
int i = 0; i < 8; i++)
1939 node_order = (
char*) quad_hilbert_child_order;
1944 node_order = (
char*) hex_hilbert_child_order;
1951 int entry_node = -2;
1954 for (
int i = 0; i < root_count; i++)
1959 if (v_in < 0) { v_in = 0; }
1962 bool shared[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1963 if (i+1 < root_count)
1966 for (
int j = 0; j < nch; j++)
1969 if (node >= 0) { shared[node] =
true; }
1974 int state =
Dim*v_in;
1975 for (
int j = 0; j <
Dim; j++)
1977 if (shared[(
int) node_order[nch*(state + j) + nch-1]])
1986 entry_node =
RetrieveNode(el, node_order[nch*state + nch-1]);
2000 MFEM_ABORT(
"invalid geometry");
2019 MFEM_VERIFY(tv.
visited ==
false,
"cyclic vertex dependencies.");
2025 for (
int i = 0; i < 3; i++)
2027 tv.
pos[i] = (pos1[i] + pos2[i]) * 0.5;
2040 for (
int i = 0; i < mesh.
vertices.Size(); i++)
2059 if (
IsGhost(nc_elem)) {
continue; }
2061 const int* node = nc_elem.
node;
2068 for (
int j = 0; j < gi.
nv; j++)
2070 elem->GetVertices()[j] =
nodes[node[j]].vert_index;
2074 for (
int k = 0; k < gi.
nf; k++)
2076 const int* fv = gi.
faces[k];
2077 const int nfv = gi.
nfv[k];
2078 const Face* face =
faces.Find(node[fv[0]], node[fv[1]],
2079 node[fv[2]], node[fv[3]]);
2087 for (
int j = 0; j < 4; j++)
2089 quad->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2096 MFEM_ASSERT(nfv == 3,
"");
2099 for (
int j = 0; j < 3; j++)
2101 tri->GetVertices()[j] =
nodes[node[fv[j]]].vert_index;
2109 for (
int j = 0; j < 2; j++)
2111 segment->GetVertices()[j] =
nodes[node[fv[2*j]]].vert_index;
2128 for (
int i = 0; i < edge_vertex->
Size(); i++)
2130 const int *ev = edge_vertex->
GetRow(i);
2133 MFEM_ASSERT(node && node->
HasEdge(),
2134 "edge (" << ev[0] <<
"," << ev[1] <<
") not found, "
2142 for (
int i = 0; i <
NFaces; i++)
2144 const int* fv = mesh->
GetFace(i)->GetVertices();
2145 const int nfv = mesh->
GetFace(i)->GetNVertices();
2158 MFEM_ASSERT(nfv == 3,
"");
2166 MFEM_ASSERT(nfv == 2,
"");
2169 face =
faces.Find(n0, n0, n1, n1);
2173 const int *ev = edge_vertex->
GetRow(i);
2174 MFEM_ASSERT((ev[0] == fv[0] && ev[1] == fv[1]) ||
2175 (ev[1] == fv[0] && ev[0] == fv[1]),
"");
2178 MFEM_VERIFY(face,
"face not found.");
2189 MFEM_ASSERT(
Dim >= 3,
"");
2198 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3, mid[3] = e4; }
2201 int midf1 = -1, midf2 = -1;
2206 if (midf1 >= 0 && midf1 == midf2)
2209 if (nd.
p1 != e1 && nd.
p2 != e1) { midf1 = -1; }
2210 if (nd.
p1 != e2 && nd.
p2 != e2) { midf2 = -1; }
2214 MFEM_ASSERT(!(midf1 >= 0 && midf2 >= 0),
"incorrectly split face!");
2216 if (midf1 < 0 && midf2 < 0)
2218 if (mid) { mid[4] = -1; }
2221 else if (midf1 >= 0)
2223 if (mid) { mid[4] = midf1; }
2228 if (mid) { mid[4] = midf2; }
2235 int e1 =
nodes.FindId(v1, v2);
2236 if (e1 < 0 || !
nodes[e1].HasVertex()) {
return false; }
2238 int e2 =
nodes.FindId(v2, v3);
2239 if (e2 < 0 || !
nodes[e2].HasVertex()) {
return false; }
2241 int e3 =
nodes.FindId(v3, v1);
2242 if (e3 < 0 || !
nodes[e3].HasVertex()) {
return false; }
2244 if (mid) { mid[0] = e1, mid[1] = e2, mid[2] = e3; }
2252 for (
int i = 0; i < 8; i++)
2254 if (el.
node[i] == node) {
return i; }
2256 MFEM_ABORT(
"Node not found.");
2262 for (
int i = 0; i <
GI[el.
Geom()].
nv; i++)
2266 if (abort) { MFEM_ABORT(
"Node not found."); }
2275 for (
int i = 0; i < gi.
ne; i++)
2277 const int* ev = gi.
edges[i];
2278 int n0 = el.
node[ev[0]];
2279 int n1 = el.
node[ev[1]];
2280 if ((n0 == vn0 && n1 == vn1) ||
2281 (n0 == vn1 && n1 == vn0)) {
return i; }
2284 if (abort) { MFEM_ABORT(
"Edge (" << vn0 <<
", " << vn1 <<
") not found"); }
2291 for (
int i = 0; i < gi.
nf; i++)
2293 const int* fv = gi.
faces[i];
2294 if ((a == fv[0] || a == fv[1] || a == fv[2] || a == fv[3]) &&
2295 (b == fv[0] || b == fv[1] || b == fv[2] || b == fv[3]) &&
2296 (c == fv[0] || c == fv[1] || c == fv[2] || c == fv[3]))
2301 MFEM_ABORT(
"Face not found.");
2314 int nfv = (v3 >= 0) ? 4 : 3;
2320 for (
int i = 0, j; i < nfv; i++)
2322 for (j = 0; j < nfv; j++)
2324 if (fv[i] == master[j])
2327 for (
int k = 0; k < mat.
Height(); k++)
2329 mat(k,i) = tmp(k,j);
2334 MFEM_ASSERT(j != nfv,
"node not found.");
2346 Face* fa =
faces.Find(vn0, vn1, vn2, vn3);
2361 eface[0] = eface[2] = fa;
2362 eface[1] = eface[3] = fa;
2375 Point pmid0(pm(0), pm(1)), pmid2(pm(2), pm(3));
2378 PointMatrix(pm(0), pmid0, pmid2, pm(3)), level+1, ef[0]);
2381 PointMatrix(pmid0, pm(1), pm(2), pmid2), level+1, ef[1]);
2383 eface[1] = ef[1][1];
2384 eface[3] = ef[0][3];
2385 eface[0] = eface[2] = NULL;
2387 else if (split == 2)
2389 Point pmid1(pm(1), pm(2)), pmid3(pm(3), pm(0));
2392 PointMatrix(pm(0), pm(1), pmid1, pmid3), level+1, ef[0]);
2395 PointMatrix(pmid3, pmid1, pm(2), pm(3)), level+1, ef[1]);
2397 eface[0] = ef[0][0];
2398 eface[2] = ef[1][2];
2399 eface[1] = eface[3] = NULL;
2410 const int fi[3][2] = {{0, 0}, {1, 3}, {2, 0}};
2411 if (!ef[0][fi[split][0]] && !ef[1][fi[split][1]])
2421 MFEM_ASSERT(eid.
Size() > 0,
"edge prism not found");
2422 MFEM_ASSERT(eid.
Size() < 2,
"non-unique edge prism");
2427 eid[0].element, eid[0].local, eid[0].geom));
2432 Point mid0(pm(0), pm(1)), mid2(pm(2), pm(3));
2433 int v1 =
nodes[mid[0]].vert_index;
2434 int v2 =
nodes[mid[2]].vert_index;
2435 ((v1 < v2) ?
PointMatrix(mid0, mid2, mid2, mid0) :
2436 PointMatrix(mid2, mid0, mid0, mid2)).GetMatrix(mat);
2440 Point mid1(pm(1), pm(2)), mid3(pm(3), pm(0));
2441 int v1 =
nodes[mid[1]].vert_index;
2442 int v2 =
nodes[mid[3]].vert_index;
2443 ((v1 < v2) ?
PointMatrix(mid1, mid3, mid3, mid1) :
2444 PointMatrix(mid3, mid1, mid1, mid3)).GetMatrix(mat);
2453 int mid =
nodes.FindId(vn0, vn1);
2454 if (mid < 0) {
return; }
2472 int v0index =
nodes[vn0].vert_index;
2473 int v1index =
nodes[vn1].vert_index;
2515 Point pmid0(pm(0), pm(1)), pmid1(pm(1), pm(2)), pmid2(pm(2), pm(0));
2545 if (
Dim < 3) {
return; }
2552 processed_faces = 0;
2559 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
2562 for (
int j = 0; j < gi.
nf; j++)
2566 for (
int k = 0; k < 4; k++)
2571 int face =
faces.FindId(node[0], node[1], node[2], node[3]);
2572 MFEM_ASSERT(face >= 0,
"face not found!");
2578 if (processed_faces[face]) {
continue; }
2579 processed_faces[face] = 1;
2584 if (fa.
elem[0] >= 0 && fa.
elem[1] >= 0)
2614 for (
int i = sb; i < se; i++)
2629 int mid =
nodes.FindId(vn0, vn1);
2630 if (mid < 0) {
return; }
2633 if (nd.
HasEdge() && level > 0)
2645 int v0index =
nodes[vn0].vert_index;
2646 int v1index =
nodes[vn1].vert_index;
2647 if (v0index > v1index) { sl.
edge_flags |= 2; }
2651 double tmid = (t0 + t1) / 2;
2665 processed_edges = 0;
2676 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
2679 for (
int j = 0; j < gi.
ne; j++)
2682 const int* ev = gi.
edges[j];
2683 int node[2] = { el.
node[ev[0]], el.
node[ev[1]] };
2685 int enode =
nodes.FindId(node[0], node[1]);
2686 MFEM_ASSERT(enode >= 0,
"edge node not found!");
2689 MFEM_ASSERT(nd.
HasEdge(),
"edge not found!");
2697 int face =
faces.FindId(node[0], node[0], node[1], node[1]);
2698 MFEM_ASSERT(face >= 0,
"face not found!");
2710 if (processed_edges[enode]) {
continue; }
2711 processed_edges[enode] = 1;
2714 double t0 = 0.0, t1 = 1.0;
2715 int v0index =
nodes[node[0]].vert_index;
2716 int v1index =
nodes[node[1]].vert_index;
2717 int flags = (v0index > v1index) ? 1 : 0;
2731 for (
int i = sb; i < se; i++)
2748 int local = edge_local[sl.
index];
2765 processed_vertices = 0;
2773 for (
int j = 0; j <
GI[el.
Geom()].
nv; j++)
2775 int node = el.
node[j];
2783 if (processed_vertices[index]) {
continue; }
2784 processed_vertices[
index] = 1;
2794 oriented_matrix = point_matrix;
2798 MFEM_ASSERT(oriented_matrix.
Height() == 1 &&
2799 oriented_matrix.
Width() == 2,
"not an edge point matrix");
2803 oriented_matrix(0,0) = 1.0 - oriented_matrix(0,0);
2804 oriented_matrix(0,1) = 1.0 - oriented_matrix(0,1);
2808 std::swap(oriented_matrix(0,0), oriented_matrix(0,1));
2826 slaves.swap(empty.
slaves);
2828 inv_index.DeleteAll();
2833 return conforming.size() + masters.size() + slaves.size();
2838 if (!inv_index.Size())
2841 for (
unsigned i = 0; i < conforming.size(); i++)
2843 max_index = std::max(conforming[i].index, max_index);
2845 for (
unsigned i = 0; i < masters.size(); i++)
2847 max_index = std::max(masters[i].index, max_index);
2849 for (
unsigned i = 0; i < slaves.size(); i++)
2851 if (slaves[i].index < 0) {
continue; }
2852 max_index = std::max(slaves[i].index, max_index);
2855 inv_index.SetSize(max_index + 1);
2858 for (
unsigned i = 0; i < conforming.size(); i++)
2860 inv_index[conforming[i].index] = (i << 2);
2862 for (
unsigned i = 0; i < masters.size(); i++)
2864 inv_index[masters[i].index] = (i << 2) + 1;
2866 for (
unsigned i = 0; i < slaves.size(); i++)
2868 if (slaves[i].index < 0) {
continue; }
2869 inv_index[slaves[i].index] = (i << 2) + 2;
2873 MFEM_ASSERT(index >= 0 && index < inv_index.Size(),
"");
2874 int key = inv_index[
index];
2878 MFEM_VERIFY(key >= 0,
"entity not found.");
2882 *type = (key >= 0) ? (key & 0x3) : -1;
2885 if (*type < 0) {
return invalid; }
2891 case 0:
return conforming[key >> 2];
2892 case 1:
return masters[key >> 2];
2893 case 2:
return slaves[key >> 2];
2894 default: MFEM_ABORT(
"internal error");
return conforming[0];
2903 int mid =
nodes.FindId(v0, v1);
2904 if (mid >= 0 &&
nodes[mid].HasVertex())
2918 for (
int i = 0; i < 3; i++)
2975 int** JJ =
new int*[nrows];
2985 MFEM_ASSERT(!el.
ref_type,
"not a leaf element.");
2988 int* node = el.
node;
2991 for (
int j = 0; j < gi.
ne; j++)
2993 const int* ev = gi.
edges[j];
2999 for (
int j = 0; j < gi.
nf; j++)
3001 const int* fv = gi.
faces[j];
3005 node[fv[2]], node[fv[3]], indices);
3018 int size = indices.
Size();
3020 JJ[i] =
new int[size];
3021 std::memcpy(JJ[i], indices.
GetData(), size *
sizeof(int));
3026 for (
int i = 0; i < nrows; i++)
3037 for (
int i = 0; i < nrows; i++)
3039 int cnt = I[i+1] - I[i];
3040 std::memcpy(J+nnz, JJ[i], cnt *
sizeof(
int));
3067 MFEM_VERIFY(elem_set.
Size() == nleaves,
"");
3076 for (
int i = 0; i < nleaves; i++)
3082 for (
int j = 0; j < nv; j++)
3089 for (
int j = 0; j < nv; j++)
3091 vmark[el.
node[j]] = 1;
3102 neighbor_set->
SetSize(nleaves);
3106 for (
int i = 0; i < nleaves; i++)
3114 for (
int j = 0; j < nv; j++)
3116 if (vmark[v[j]]) { hit =
true;
break; }
3123 for (
int j = 0; j < nv; j++)
3125 if (vmark[el.
node[j]]) { hit =
true;
break; }
3132 if (neighbor_set) { (*neighbor_set)[i] = 1; }
3138 static bool sorted_lists_intersect(
const int*
a,
const int*
b,
int na,
int nb)
3140 if (!na || !nb) {
return false; }
3141 int a_last = a[na-1], b_last = b[nb-1];
3142 if (*b < *a) {
goto l2; }
3144 if (a_last < *b) {
return false; }
3145 while (*a < *b) { a++; }
3146 if (*a == *b) {
return true; }
3148 if (b_last < *a) {
return false; }
3149 while (*b < *a) { b++; }
3150 if (*a == *b) {
return true; }
3173 while (stack.
Size())
3182 for (
int i = 0; i < nv; i++)
3188 for (
int i = 0; i < nv; i++)
3195 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
3206 int nv1 = vert.
Size();
3211 for (
int i = 0; i < search_set->
Size(); i++)
3213 int testme = (*search_set)[i];
3220 bool hit = sorted_lists_intersect(v1, v2, nv1, nv2);
3225 for (
int j = 0; j < nv; j++)
3227 hit = sorted_lists_intersect(&el.
node[j], v1, 1, nv1);
3232 if (hit) { neighbors.
Append(testme); }
3246 for (
int i = 0; i < elems.
Size(); i++)
3252 for (
int j = 0; j < nv; j++)
3258 for (
int j = 0; j < nv; j++)
3260 vmark[el.
node[j]] = 1;
3270 for (
int i = 0; i < search_set->
Size(); i++)
3272 int testme = (*search_set)[i];
3278 for (
int j = 0; j < nv; j++)
3280 if (vmark[v[j]]) { hit =
true;
break; }
3286 for (
int j = 0; j < nv; j++)
3288 if (vmark[el.
node[j]]) { hit =
true;
break; }
3292 if (hit) { expanded.
Append(testme); }
3298 for (
int i = 0; i < 3; i++)
3300 dst[i] = (src[i]*s[i] >> 1) + t[i];
3309 if (el.
parent < 0) {
return elem; }
3312 MFEM_ASSERT(pa.
ref_type,
"internal error");
3315 while (ch < 8 && pa.
child[ch] != elem) { ch++; }
3316 MFEM_ASSERT(ch < 8,
"internal error");
3318 MFEM_ASSERT(geom_parent[el.
Geom()],
"unsupported geometry");
3320 tr.
Apply(coord, coord);
3331 return (pt[0] >= 0) && (pt[0] <=
T_ONE) &&
3332 (pt[1] >= 0) && (pt[1] <=
T_ONE);
3335 return (pt[0] >= 0) && (pt[0] <=
T_ONE) &&
3336 (pt[1] >= 0) && (pt[1] <=
T_ONE) &&
3337 (pt[2] >= 0) && (pt[2] <=
T_ONE);
3340 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <=
T_ONE);
3343 return (pt[0] >= 0) && (pt[1] >= 0) && (pt[0] + pt[1] <=
T_ONE) &&
3344 (pt[2] >= 0) && (pt[2] <=
T_ONE);
3347 MFEM_ABORT(
"unsupported geometry");
3363 for (
int ch = 0; ch < 8 && el.
child[ch] >= 0; ch++)
3366 tr.
Apply(coord, tcoord);
3368 if (RefPointInside(el.
Geom(), tcoord))
3380 MFEM_ASSERT(geom_corners[el.
Geom()],
"unsupported geometry");
3381 std::memcpy(coord, geom_corners[el.
Geom()][local],
sizeof(coord));
3395 for (
int i = 0; i < np; i++)
3397 for (
int j = 0; j < points[0].dim; j++)
3399 point_matrix(j, i) = points[i].coord[j];
3411 Point(0, 0, 0),
Point(1, 0, 0),
Point(0, 1, 0),
Point(0, 0, 1)
3418 Point(0, 0, 0),
Point(1, 0, 0),
Point(1, 1, 0),
Point(0, 1, 0),
3419 Point(0, 0, 1),
Point(1, 0, 1),
Point(1, 1, 1),
Point(0, 1, 1)
3432 MFEM_ABORT(
"unsupported geometry " << geom);
3444 int ref_type = *ref_path++;
3445 int child = *ref_path++;
3453 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
3454 Point mid67(pm(6), pm(7)), mid45(pm(4), pm(5));
3459 pm(4), mid45, mid67, pm(7));
3461 else if (child == 1)
3464 mid45, pm(5), pm(6), mid67);
3467 else if (ref_type == 2)
3469 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
3470 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
3475 pm(4), pm(5), mid56, mid74);
3477 else if (child == 1)
3480 mid74, mid56, pm(6), pm(7));
3483 else if (ref_type == 4)
3485 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
3486 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
3491 mid04, mid15, mid26, mid37);
3493 else if (child == 1)
3496 pm(4), pm(5), pm(6), pm(7));
3499 else if (ref_type == 3)
3501 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
3502 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
3503 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
3504 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
3506 Point midf0(mid23, mid12, mid01, mid30);
3507 Point midf5(mid45, mid56, mid67, mid74);
3512 pm(4), mid45, midf5, mid74);
3514 else if (child == 1)
3517 mid45, pm(5), mid56, midf5);
3519 else if (child == 2)
3522 midf5, mid56, pm(6), mid67);
3524 else if (child == 3)
3527 mid74, midf5, mid67, pm(7));
3530 else if (ref_type == 5)
3532 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
3533 Point mid45(pm(4), pm(5)), mid67(pm(6), pm(7));
3534 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
3535 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
3537 Point midf1(mid01, mid15, mid45, mid04);
3538 Point midf3(mid23, mid37, mid67, mid26);
3543 mid04, midf1, midf3, mid37);
3545 else if (child == 1)
3548 midf1, mid15, mid26, midf3);
3550 else if (child == 2)
3553 mid45, pm(5), pm(6), mid67);
3555 else if (child == 3)
3558 pm(4), mid45, mid67, pm(7));
3561 else if (ref_type == 6)
3563 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
3564 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
3565 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
3566 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
3568 Point midf2(mid12, mid26, mid56, mid15);
3569 Point midf4(mid30, mid04, mid74, mid37);
3574 mid04, mid15, midf2, midf4);
3576 else if (child == 1)
3579 midf4, midf2, mid26, mid37);
3581 else if (child == 2)
3584 pm(4), pm(5), mid56, mid74);
3586 else if (child == 3)
3589 mid74, mid56, pm(6), pm(7));
3592 else if (ref_type == 7)
3594 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
3595 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
3596 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
3597 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
3598 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
3599 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
3601 Point midf0(mid23, mid12, mid01, mid30);
3602 Point midf1(mid01, mid15, mid45, mid04);
3603 Point midf2(mid12, mid26, mid56, mid15);
3604 Point midf3(mid23, mid37, mid67, mid26);
3605 Point midf4(mid30, mid04, mid74, mid37);
3606 Point midf5(mid45, mid56, mid67, mid74);
3608 Point midel(midf1, midf3);
3613 mid04, midf1, midel, midf4);
3615 else if (child == 1)
3618 midf1, mid15, midf2, midel);
3620 else if (child == 2)
3623 midel, midf2, mid26, midf3);
3625 else if (child == 3)
3628 midf4, midel, midf3, mid37);
3630 else if (child == 4)
3633 pm(4), mid45, midf5, mid74);
3635 else if (child == 5)
3638 mid45, pm(5), mid56, midf5);
3640 else if (child == 6)
3643 midf5, mid56, pm(6), mid67);
3645 else if (child == 7)
3648 mid74, midf5, mid67, pm(7));
3656 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
3657 Point mid20(pm(2), pm(0)), mid34(pm(3), pm(4));
3658 Point mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
3662 pm =
PointMatrix(pm(0), mid01, mid20, pm(3), mid34, mid53);
3664 else if (child == 1)
3666 pm =
PointMatrix(mid01, pm(1), mid12, mid34, pm(4), mid45);
3668 else if (child == 2)
3670 pm =
PointMatrix(mid20, mid12, pm(2), mid53, mid45, pm(5));
3672 else if (child == 3)
3674 pm =
PointMatrix(mid12, mid20, mid01, mid45, mid53, mid34);
3677 else if (ref_type == 4)
3679 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
3683 pm =
PointMatrix(pm(0), pm(1), pm(2), mid03, mid14, mid25);
3685 else if (child == 1)
3687 pm =
PointMatrix(mid03, mid14, mid25, pm(3), pm(4), pm(5));
3690 else if (ref_type > 4)
3692 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
3693 Point mid34(pm(3), pm(4)), mid45(pm(4), pm(5)), mid53(pm(5), pm(3));
3694 Point mid03(pm(0), pm(3)), mid14(pm(1), pm(4)), mid25(pm(2), pm(5));
3696 Point midf2(mid01, mid14, mid34, mid03);
3697 Point midf3(mid12, mid25, mid45, mid14);
3698 Point midf4(mid20, mid03, mid53, mid25);
3702 pm =
PointMatrix(pm(0), mid01, mid20, mid03, midf2, midf4);
3704 else if (child == 1)
3706 pm =
PointMatrix(mid01, pm(1), mid12, midf2, mid14, midf3);
3708 else if (child == 2)
3710 pm =
PointMatrix(mid20, mid12, pm(2), midf4, midf3, mid25);
3712 else if (child == 3)
3714 pm =
PointMatrix(mid12, mid20, mid01, midf3, midf4, midf2);
3716 else if (child == 4)
3718 pm =
PointMatrix(mid03, midf2, midf4, pm(3), mid34, mid53);
3720 else if (child == 5)
3722 pm =
PointMatrix(midf2, mid14, midf3, mid34, pm(4), mid45);
3724 else if (child == 6)
3726 pm =
PointMatrix(midf4, midf3, mid25, mid53, mid45, pm(5));
3728 else if (child == 7)
3730 pm =
PointMatrix(midf3, midf4, midf2, mid45, mid53, mid34);
3736 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid02(pm(2), pm(0));
3737 Point mid03(pm(0), pm(3)), mid13(pm(1), pm(3)), mid23(pm(2), pm(3));
3743 else if (child == 1)
3747 else if (child == 2)
3751 else if (child == 3)
3755 else if (child == 4)
3759 else if (child == 5)
3763 else if (child == 6)
3767 else if (child == 7)
3776 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
3782 else if (child == 1)
3787 else if (ref_type == 2)
3789 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
3795 else if (child == 1)
3800 else if (ref_type == 3)
3802 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
3803 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
3804 Point midel(mid01, mid23);
3810 else if (child == 1)
3814 else if (child == 2)
3818 else if (child == 3)
3826 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
3832 else if (child == 1)
3836 else if (child == 2)
3840 else if (child == 3)
3848 for (
int i = 0; i < pm.
np; i++)
3850 for (
int j = 0; j < pm(i).dim; j++)
3852 matrix(j, i) = pm(i).coord[j];
3877 int &matrix = map[ref_path];
3878 if (!matrix) { matrix = map.size(); }
3881 emb.
parent = coarse_index;
3886 MFEM_ASSERT(el.
tet_type == 0,
"not implemented");
3889 ref_path.push_back(0);
3891 for (
int i = 0; i < 8; i++)
3893 if (el.
child[i] >= 0)
3895 ref_path[ref_path.length()-1] = i;
3899 ref_path.resize(ref_path.length()-2);
3906 "GetRefinementTransforms() must be preceded by MarkCoarseLevel()"
3914 std::string ref_path;
3915 ref_path.reserve(100);
3920 path_map[g][ref_path] = 1;
3928 used_geoms |= (1 <<
geom);
3933 if (used_geoms & (1 << g))
3942 RefPathMap::iterator it;
3943 for (it = path_map[g].begin(); it != path_map[g].end(); ++it)
3957 "GetDerefinementTransforms() must be preceded by Derefine().");
3973 int geom = code & 0xf;
3974 int ref_type_child = code >> 4;
3976 int &matrix = mat_no[
geom][ref_type_child];
3977 if (!matrix) { matrix = mat_no[
geom].size(); }
3984 if (
Geoms & (1 << g))
3993 for (
auto it = mat_no[geom].begin(); it != mat_no[
geom].end(); ++it)
3995 char path[3] = { 0, 0, 0 };
3997 int code = it->first;
4000 path[0] = code >> 4;
4001 path[1] = code & 0xf;
4024 : geom(g), num_children(n), children(c) { }
4026 bool operator<(
const RefType &other)
const
4028 if (geom < other.geom) {
return true; }
4029 if (geom > other.geom) {
return false; }
4030 if (num_children < other.num_children) {
return true; }
4031 if (num_children > other.num_children) {
return false; }
4032 for (
int i = 0; i < num_children; i++)
4034 if (children[i].one < other.children[i].one) {
return true; }
4035 if (children[i].one > other.children[i].one) {
return false; }
4048 const int fine_ne = embeddings.Size();
4050 for (
int i = 0; i < fine_ne; i++)
4052 coarse_ne = std::max(coarse_ne, embeddings[i].parent);
4056 coarse_to_ref_type.
SetSize(coarse_ne);
4057 coarse_to_fine.
SetDims(coarse_ne, fine_ne);
4062 for (
int i = 0; i < fine_ne; i++)
4064 cf_i[embeddings[i].parent+1]++;
4067 MFEM_ASSERT(cf_i.Last() == cf_j.
Size(),
"internal error");
4068 for (
int i = 0; i < fine_ne; i++)
4072 cf_j[cf_i[e.
parent]].two = i;
4075 std::copy_backward(cf_i.begin(), cf_i.end()-1, cf_i.end());
4077 for (
int i = 0; i < coarse_ne; i++)
4079 std::sort(&cf_j[cf_i[i]], cf_j.
GetData() + cf_i[i+1]);
4081 for (
int i = 0; i < fine_ne; i++)
4083 coarse_to_fine.
GetJ()[i] = cf_j[i].two;
4086 using internal::RefType;
4090 map<RefType,int> ref_type_map;
4091 for (
int i = 0; i < coarse_ne; i++)
4093 const int num_children = cf_i[i+1]-cf_i[i];
4094 MFEM_ASSERT(num_children > 0,
"");
4095 const int fine_el = cf_j[cf_i[i]].two;
4098 const RefType ref_type(geom, num_children, &cf_j[cf_i[i]]);
4099 pair<map<RefType,int>::iterator,
bool> res =
4100 ref_type_map.insert(
4101 pair<const RefType,int>(ref_type, (
int)ref_type_map.size()));
4102 coarse_to_ref_type[i] = res.first->second;
4105 ref_type_to_matrix.
MakeI((
int)ref_type_map.size());
4106 ref_type_to_geom.
SetSize((
int)ref_type_map.size());
4107 for (map<RefType,int>::iterator it = ref_type_map.begin();
4108 it != ref_type_map.end(); ++it)
4110 ref_type_to_matrix.
AddColumnsInRow(it->second, it->first.num_children);
4111 ref_type_to_geom[it->second] = it->first.geom;
4114 ref_type_to_matrix.
MakeJ();
4115 for (map<RefType,int>::iterator it = ref_type_map.begin();
4116 it != ref_type_map.end(); ++it)
4118 const RefType &rt = it->first;
4119 for (
int j = 0; j < rt.num_children; j++)
4121 ref_type_to_matrix.
AddConnection(it->second, rt.children[j].one);
4137 point_matrices[i].SetSize(0, 0, 0);
4139 embeddings.DeleteAll();
4147 if (point_matrices[i].SizeK()) {
return true; }
4155 static int sgn(
int x)
4157 return (x < 0) ? -1 : (x > 0) ? 1 : 0;
4160 static void HilbertSfc2D(
int x,
int y,
int ax,
int ay,
int bx,
int by,
4163 int w = std::abs(ax + ay);
4164 int h = std::abs(bx + by);
4166 int dax = sgn(ax), day = sgn(ay);
4167 int dbx = sgn(bx), dby = sgn(by);
4171 for (
int i = 0; i < w; i++, x += dax, y += day)
4180 for (
int i = 0; i < h; i++, x += dbx, y += dby)
4188 int ax2 = ax/2, ay2 = ay/2;
4189 int bx2 = bx/2, by2 = by/2;
4191 int w2 = std::abs(ax2 + ay2);
4192 int h2 = std::abs(bx2 + by2);
4196 if ((w2 & 0x1) && (w > 2))
4198 ax2 += dax, ay2 += day;
4201 HilbertSfc2D(x, y, ax2, ay2, bx, by, coords);
4202 HilbertSfc2D(x+ax2, y+ay2, ax-ax2, ay-ay2, bx, by, coords);
4206 if ((h2 & 0x1) && (h > 2))
4208 bx2 += dbx, by2 += dby;
4211 HilbertSfc2D(x, y, bx2, by2, ax2, ay2, coords);
4212 HilbertSfc2D(x+bx2, y+by2, ax, ay, bx-bx2, by-by2, coords);
4213 HilbertSfc2D(x+(ax-dax)+(bx2-dbx), y+(ay-day)+(by2-dby),
4214 -bx2, -by2, -(ax-ax2), -(ay-ay2), coords);
4218 static void HilbertSfc3D(
int x,
int y,
int z,
4219 int ax,
int ay,
int az,
4220 int bx,
int by,
int bz,
4221 int cx,
int cy,
int cz,
4224 int w = std::abs(ax + ay + az);
4225 int h = std::abs(bx + by + bz);
4226 int d = std::abs(cx + cy + cz);
4228 int dax = sgn(ax), day = sgn(ay), daz = sgn(az);
4229 int dbx = sgn(bx), dby = sgn(by), dbz = sgn(bz);
4230 int dcx = sgn(cx), dcy = sgn(cy), dcz = sgn(cz);
4233 if (h == 1 && d == 1)
4235 for (
int i = 0; i < w; i++, x += dax, y += day, z += daz)
4243 if (w == 1 && d == 1)
4245 for (
int i = 0; i < h; i++, x += dbx, y += dby, z += dbz)
4253 if (w == 1 && h == 1)
4255 for (
int i = 0; i < d; i++, x += dcx, y += dcy, z += dcz)
4264 int ax2 = ax/2, ay2 = ay/2, az2 = az/2;
4265 int bx2 = bx/2, by2 = by/2, bz2 = bz/2;
4266 int cx2 = cx/2, cy2 = cy/2, cz2 = cz/2;
4268 int w2 = std::abs(ax2 + ay2 + az2);
4269 int h2 = std::abs(bx2 + by2 + bz2);
4270 int d2 = std::abs(cx2 + cy2 + cz2);
4273 if ((w2 & 0x1) && (w > 2))
4275 ax2 += dax, ay2 += day, az2 += daz;
4277 if ((h2 & 0x1) && (h > 2))
4279 bx2 += dbx, by2 += dby, bz2 += dbz;
4281 if ((d2 & 0x1) && (d > 2))
4283 cx2 += dcx, cy2 += dcy, cz2 += dcz;
4287 if ((2*w > 3*h) && (2*w > 3*d))
4289 HilbertSfc3D(x, y, z,
4292 cx, cy, cz, coords);
4294 HilbertSfc3D(x+ax2, y+ay2, z+az2,
4295 ax-ax2, ay-ay2, az-az2,
4297 cx, cy, cz, coords);
4302 HilbertSfc3D(x, y, z,
4305 ax2, ay2, az2, coords);
4307 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4309 bx-bx2, by-by2, bz-bz2,
4310 cx, cy, cz, coords);
4312 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4313 y+(ay-day)+(by2-dby),
4314 z+(az-daz)+(bz2-dbz),
4317 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4322 HilbertSfc3D(x, y, z,
4325 bx, by, bz, coords);
4327 HilbertSfc3D(x+cx2, y+cy2, z+cz2,
4330 cx-cx2, cy-cy2, cz-cz2, coords);
4332 HilbertSfc3D(x+(ax-dax)+(cx2-dcx),
4333 y+(ay-day)+(cy2-dcy),
4334 z+(az-daz)+(cz2-dcz),
4336 -(ax-ax2), -(ay-ay2), -(az-az2),
4337 bx, by, bz, coords);
4342 HilbertSfc3D(x, y, z,
4345 ax2, ay2, az2, coords);
4347 HilbertSfc3D(x+bx2, y+by2, z+bz2,
4350 bx-bx2, by-by2, bz-bz2, coords);
4352 HilbertSfc3D(x+(bx2-dbx)+(cx-dcx),
4353 y+(by2-dby)+(cy-dcy),
4354 z+(bz2-dbz)+(cz-dcz),
4357 -(cx-cx2), -(cy-cy2), -(cz-cz2), coords);
4359 HilbertSfc3D(x+(ax-dax)+bx2+(cx-dcx),
4360 y+(ay-day)+by2+(cy-dcy),
4361 z+(az-daz)+bz2+(cz-dcz),
4363 -(ax-ax2), -(ay-ay2), -(az-az2),
4364 bx-bx2, by-by2, bz-bz2, coords);
4366 HilbertSfc3D(x+(ax-dax)+(bx2-dbx),
4367 y+(ay-day)+(by2-dby),
4368 z+(az-daz)+(bz2-dbz),
4371 -(ax-ax2), -(ay-ay2), -(az-az2), coords);
4378 coords.
Reserve(2*width*height);
4380 if (width >= height)
4382 HilbertSfc2D(0, 0, width, 0, 0, height, coords);
4386 HilbertSfc2D(0, 0, 0, height, width, 0, coords);
4394 coords.
Reserve(3*width*height*depth);
4396 if (width >= height && width >= depth)
4398 HilbertSfc3D(0, 0, 0,
4401 0, 0, depth, coords);
4403 else if (height >= width && height >= depth)
4405 HilbertSfc3D(0, 0, 0,
4408 0, 0, depth, coords);
4412 HilbertSfc3D(0, 0, 0,
4415 0, height, 0, coords);
4423 bool oriented)
const
4427 const int* ev = gi.
edges[(int) edge_id.
local];
4429 int n0 = el.
node[ev[0]], n1 = el.
node[ev[1]];
4430 if (n0 > n1) { std::swap(n0, n1); }
4432 vert_index[0] =
nodes[n0].vert_index;
4433 vert_index[1] =
nodes[n1].vert_index;
4435 if (oriented && vert_index[0] > vert_index[1])
4437 std::swap(vert_index[0], vert_index[1]);
4445 const int* ev = gi.
edges[(int) edge_id.
local];
4447 int v0 =
nodes[el.
node[ev[0]]].vert_index;
4448 int v1 =
nodes[el.
node[ev[1]]].vert_index;
4450 return ((v0 < v1 && ev[0] > ev[1]) || (v0 > v1 && ev[0] < ev[1])) ? -1 : 1;
4454 int vert_index[4],
int edge_index[4],
4455 int edge_orientation[4])
const
4457 MFEM_ASSERT(
Dim >= 3,
"");
4462 const int *fv = gi.
faces[(int) face_id.
local];
4463 const int nfv = gi.
nfv[(
int) face_id.
local];
4465 vert_index[3] = edge_index[3] = -1;
4466 edge_orientation[3] = 0;
4468 for (
int i = 0; i < nfv; i++)
4470 vert_index[i] =
nodes[el.
node[fv[i]]].vert_index;
4473 for (
int i = 0; i < nfv; i++)
4476 if (j >= nfv) { j = 0; }
4478 int n1 = el.
node[fv[i]];
4479 int n2 = el.
node[fv[j]];
4482 MFEM_ASSERT(en != NULL,
"edge not found.");
4485 edge_orientation[i] = (vert_index[i] < vert_index[j]) ? 1 : -1;
4493 MFEM_ASSERT(node >= 0,
"edge node not found.");
4496 int p1 = nd.
p1, p2 = nd.
p2;
4497 MFEM_ASSERT(p1 != p2,
"invalid edge node.");
4501 int n1p1 = n1.
p1, n1p2 = n1.
p2;
4502 int n2p1 = n2.p1, n2p2 = n2.p2;
4504 if ((n2p1 != n2p2) && (p1 == n2p1 || p1 == n2p2))
4508 if (n2.HasEdge()) {
return p2; }
4512 if ((n1p1 != n1p2) && (p2 == n1p1 || p2 == n1p2))
4516 if (n1.
HasEdge()) {
return p1; }
4526 MFEM_ASSERT(node >= 0 &&
nodes[node].HasEdge(),
"(v1, v2) is not an edge.");
4529 return (master >= 0) ?
nodes[master].edge_index : -1;
4535 int depth = 0, parent;
4536 while ((parent =
elements[elem].parent) != -1)
4547 int parent, reduction = 1;
4548 while ((parent =
elements[elem].parent) != -1)
4550 if (
elements[parent].ref_type & 1) { reduction *= 2; }
4551 if (
elements[parent].ref_type & 2) { reduction *= 2; }
4552 if (
elements[parent].ref_type & 4) { reduction *= 2; }
4568 for (
int i = 0; i < gi.
nf; i++)
4570 const int* fv = gi.
faces[i];
4573 MFEM_ASSERT(face,
"face not found");
4574 faces[i] = face->
index;
4586 int elem = fa.
elem[0];
4587 if (elem < 0) { elem = fa.
elem[1]; }
4588 MFEM_ASSERT(elem >= 0,
"Face has no elements?");
4597 for (
int i = 0; i < 4; i++)
4599 node[i] = el.
node[fv[i]];
4616 if (bdr_attr_is_ess[
faces[face].attribute - 1])
4620 int nfv = (node[3] < 0) ? 3 : 4;
4622 for (
int j = 0; j < nfv; j++)
4626 int enode =
nodes.FindId(node[j], node[(j+1) % nfv]);
4627 MFEM_ASSERT(enode >= 0 &&
nodes[enode].HasEdge(),
"Edge not found.");
4656 bdr_vertices.
Sort();
4663 static int max4(
int a,
int b,
int c,
int d)
4665 return std::max(std::max(a, b), std::max(c, d));
4667 static int max6(
int a,
int b,
int c,
int d,
int e,
int f)
4669 return std::max(max4(a, b, c, d), std::max(e, f));
4671 static int max8(
int a,
int b,
int c,
int d,
int e,
int f,
int g,
int h)
4673 return std::max(max4(a, b, c, d), max4(e, f, g, h));
4678 int mid =
nodes.FindId(vn1, vn2);
4679 if (mid < 0 || !
nodes[mid].HasVertex()) {
return 0; }
4687 faces.FindId(vn1, vn2, vn3) < 0)
4701 int& h_level,
int& v_level)
const
4703 int hl1, hl2, vl1, vl2;
4709 h_level = v_level = 0;
4715 h_level = std::max(hl1, hl2);
4716 v_level = std::max(vl1, vl2) + 1;
4722 h_level = std::max(hl1, hl2) + 1;
4723 v_level = std::max(vl1, vl2);
4730 const int* node = el.
node;
4734 for (
int i = 0; i < gi.
ne; i++)
4736 const int* ev = gi.
edges[i];
4743 for (
int i = 0; i < gi.
nf; i++)
4745 const int* fv = gi.
faces[i];
4749 node[fv[2]], node[fv[3]],
4750 flevel[i][1], flevel[i][0]);
4763 splits[0] = max8(flevel[0][0], flevel[1][0], flevel[3][0], flevel[5][0],
4764 elevel[0], elevel[2], elevel[4], elevel[6]);
4766 splits[1] = max8(flevel[0][1], flevel[2][0], flevel[4][0], flevel[5][1],
4767 elevel[1], elevel[3], elevel[5], elevel[7]);
4769 splits[2] = max8(flevel[1][1], flevel[2][1], flevel[3][1], flevel[4][1],
4770 elevel[8], elevel[9], elevel[10], elevel[11]);
4774 splits[0] = splits[1] =
4776 max6(flevel[0][0], flevel[1][0], 0,
4777 flevel[2][0], flevel[3][0], flevel[4][0]),
4778 max6(elevel[0], elevel[1], elevel[2],
4779 elevel[3], elevel[4], elevel[5]));
4781 splits[2] = max6(flevel[2][1], flevel[3][1], flevel[4][1],
4782 elevel[6], elevel[7], elevel[8]);
4786 splits[0] = std::max(
4787 max4(flevel[0][0], flevel[1][0], flevel[2][0], flevel[3][0]),
4788 max6(elevel[0], elevel[1], elevel[2],
4789 elevel[3], elevel[4], elevel[5]));
4791 splits[1] = splits[0];
4792 splits[2] = splits[0];
4796 splits[0] = std::max(elevel[0], elevel[2]);
4797 splits[1] = std::max(elevel[1], elevel[3]);
4801 splits[0] = std::max(elevel[0], std::max(elevel[1], elevel[2]));
4802 splits[1] = splits[0];
4806 MFEM_ABORT(
"Unsupported element geometry.");
4820 for (
int k = 0; k <
Dim; k++)
4822 if (splits[k] > max_level)
4824 ref_type |= (1 << k);
4842 MFEM_VERIFY(max_nc_level >= 1,
"'max_nc_level' must be 1 or greater.");
4849 if (!refinements.
Size()) {
break; }
4861 if (node->HasVertex() && node->p1 != node->p2) { nv++; }
4868 if (node->HasVertex() && node->p1 != node->p2)
4876 out << node->vert_index <<
" "
4889 input >>
id >> p1 >> p2;
4890 MFEM_VERIFY(input,
"problem reading vertex parents.");
4892 MFEM_VERIFY(
nodes.IdExists(
id),
"vertex " <<
id <<
" not found.");
4893 MFEM_VERIFY(
nodes.IdExists(p1),
"parent " << p1 <<
" not found.");
4894 MFEM_VERIFY(
nodes.IdExists(p2),
"parent " << p2 <<
" not found.");
4897 nodes.Reparent(
id, p1, p2);
4906 int num_top_level = 0;
4909 if (node->p1 == node->p2)
4911 MFEM_VERIFY(node.index() == node->p1,
"invalid top-level vertex.");
4912 MFEM_VERIFY(node->HasVertex(),
"top-level vertex not found.");
4913 MFEM_VERIFY(node->vert_index == node->p1,
"bad top-level vertex index");
4914 num_top_level = std::max(num_top_level, node->p1 + 1);
4919 for (
int i = 0; i < num_top_level; i++)
4921 std::memcpy(&
top_vertex_pos[3*i], mvertices[i](), 3*
sizeof(
double));
4930 int child_id[8], nch = 0;
4931 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
4935 MFEM_ASSERT(nch == ref_type_num_children[(
int) el.
ref_type],
"");
4938 for (
int i = 0; i < nch; i++)
4940 out <<
" " << child_id[i];
4972 for (
int i = 0; i < 8 && el.
child[i] >= 0; i++)
4974 int old_id = el.
child[i];
4976 int new_id =
elements.Append(tmp_elements[old_id]);
4977 index_map[old_id] = new_id;
4978 el.
child[i] = new_id;
5002 if (
Dim == 3 && ref_type != 7) { iso =
false; }
5005 int nch = ref_type_num_children[ref_type];
5006 for (
int i = 0,
id; i < nch; i++)
5009 MFEM_VERIFY(
id >= 0,
"");
5012 "coarse element cannot be referenced before it is "
5013 "defined (id=" <<
id <<
").");
5016 MFEM_VERIFY(child.parent == -1,
5017 "element " <<
id <<
" cannot have two parents.");
5020 child.parent = elem;
5024 el.
geom = child.geom;
5042 if (el->parent == -1)
5045 index_map[el.index()] = new_id;
5051 for (
int i = 0; i < root_count; i++)
5059 for (
int i = 0; i < 2; i++)
5061 if (face->elem[i] >= 0)
5063 face->elem[i] = index_map[face->elem[i]];
5064 MFEM_ASSERT(face->elem[i] >= 0,
"");
5095 pmsize = slaves[0].point_matrix.MemoryUsage();
5098 return conforming.capacity() *
sizeof(
MeshId) +
5099 masters.capacity() *
sizeof(
Master) +
5100 slaves.capacity() *
sizeof(
Slave) +
5101 slaves.size() * pmsize;
5106 long mem = embeddings.MemoryUsage();
5109 mem += point_matrices[i].MemoryUsage();
5116 return nodes.MemoryUsage() +
5117 faces.MemoryUsage() +
5152 <<
ref_stack.MemoryUsage() <<
" ref_stack\n"
5156 <<
sizeof(*this) <<
" NCMesh"
5164 static const double MiB = 1024.*1024.;
5166 "NCMesh statistics:\n"
5167 "------------------\n"
5168 " mesh and space dimensions : " <<
Dim <<
", " <<
spaceDim <<
"\n"
5169 " isotropic only : " << (
Iso ?
"yes" :
"no") <<
"\n"
5170 " number of Nodes : " << std::setw(9)
5171 <<
nodes.Size() <<
" + [ " << std::setw(9)
5172 <<
nodes.MemoryUsage()/MiB <<
" MiB ]\n"
5173 " free " << std::setw(9)
5174 <<
nodes.NumFreeIds() <<
"\n"
5175 " number of Faces : " << std::setw(9)
5176 <<
faces.Size() <<
" + [ " << std::setw(9)
5177 <<
faces.MemoryUsage()/MiB <<
" MiB ]\n"
5178 " free " << std::setw(9)
5179 <<
faces.NumFreeIds() <<
"\n"
5180 " number of Elements : " << std::setw(9)
5184 " free " << std::setw(9)
5186 " number of root elements : " << std::setw(9)
5188 " number of leaf elements : " << std::setw(9)
5190 " number of vertices : " << std::setw(9)
5192 " number of faces : " << std::setw(9)
5195 " conforming " << std::setw(9)
5197 " master " << std::setw(9)
5199 " slave " << std::setw(9)
5201 " number of edges : " << std::setw(9)
5204 " conforming " << std::setw(9)
5206 " master " << std::setw(9)
5208 " slave " << std::setw(9)
5210 " total memory : " << std::setw(17)
5211 <<
"[ " << std::setw(9) <<
MemoryUsage()/MiB <<
" MiB ]\n"
5222 for (
int j = 0; j <
Dim; j++)
5226 for (
int k = 0; k < 8; k++)
5228 if (elem->
node[k] >= 0)
5234 out << sum / count <<
" ";
5245 out <<
nodes.Size() <<
"\n";
5249 out << node.index() <<
" "
5250 << pos[0] <<
" " << pos[1] <<
" " << pos[2] <<
" "
5251 << node->p1 <<
" " << node->p2 <<
" "
5252 << node->vert_index <<
" " << node->edge_index <<
" "
5260 for (
int i = 0; i <
elements.Size(); i++)
5265 out << nleaves <<
"\n";
5266 for (
int i = 0; i <
elements.Size(); i++)
5271 out << gi.
nv <<
" ";
5272 for (
int j = 0; j < gi.
nv; j++)
5274 out << el.
node[j] <<
" ";
5281 out <<
faces.Size() <<
"\n";
5284 int elem = face->elem[0];
5285 if (elem < 0) { elem = face->elem[1]; }
5286 MFEM_ASSERT(elem >= 0,
"");
5298 for (
int i = 0; i < nfv; i++)
5300 out <<
" " << el.
node[fv[i]];
NCList face_list
lazy-initialized list of faces, see GetFaceList
void CollectLeafElements(int elem, int state)
bool CubeFaceTop(int node, int *n)
NCList edge_list
lazy-initialized list of edges, see GetEdgeList
NCMesh(const Mesh *mesh, std::istream *vertex_parents=NULL)
Geometry::Type GetGeometryType() const
bool TraverseTriFace(int vn0, int vn1, int vn2, const PointMatrix &pm, int level)
int Size() const
Logical size of the array.
static void GridSfcOrdering3D(int width, int height, int depth, Array< int > &coords)
void CheckAnisoPrism(int vn1, int vn2, int vn3, int vn4, const Refinement *refs, int nref)
CoarseFineTransformations transforms
storage for data returned by Get[De]RefinementTransforms()
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)
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)
int GetFaceVerticesEdges(const MeshId &face_id, int vert_index[4], int edge_index[4], int edge_orientation[4]) const
Array< double > top_vertex_pos
coordinates of top-level vertices (organized as triples)
Table * GetEdgeVertexTable() const
Returns the edge-to-vertex Table (3D)
bool TriFaceSplit(int v1, int v2, int v3, int mid[3]=NULL) const
void SetDerefMatrixCodes(int parent, Array< int > &fine_coarse)
const CoarseFineTransformations & GetDerefinementTransforms()
virtual int GetNEdges() const =0
void AddColumnsInRow(int r, int ncol)
Array< Triple< int, int, int > > reparents
scheduled node reparents (tmp)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
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).
Array< Element * > boundary
void CollectTriFaceVertices(int v0, int v1, int v2, Array< int > &indices)
char tet_type
tetrahedron split type, currently always 0
virtual void LimitNCLevel(int max_nc_level)
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 TraverseQuadFace(int vn0, int vn1, int vn2, int vn3, const PointMatrix &pm, int level, Face *eface[4])
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 SetDims(int rows, int nnz)
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 GetMeshComponents(Mesh &mesh) const
Fill Mesh::{vertices,elements,boundary} for the current finest level.
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.
NCList vertex_list
lazy-initialized list of vertices, see GetVertexList
void InitDerefTransforms()
static PointMatrix pm_prism_identity
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 (char for storage only)
void InitRootState(int root_count)
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
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)
virtual int GetNumGhostVertices() const
static PointMatrix pm_tri_identity
bool operator<(const Pair< A, B > &p, const Pair< A, B > &q)
Comparison operator for class Pair, based on the first element only.
void CountSplits(int elem, int splits[3]) const
Geometry::Type Geom() 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
Geometry::Type GetElementBaseGeometry(int i) 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])
bool CubeFaceBack(int node, int *n)
static const PointMatrix & GetGeomIdentity(Geometry::Type geom)
void DeleteAll()
Delete 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.
const MeshId & LookUp(int index, int *type=NULL) const
virtual void OnMeshUpdated(Mesh *mesh)
void DebugLeafOrder(std::ostream &out) const
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)
static int find_local_face(int geom, int a, int b, int c)
Array< Refinement > ref_stack
stack of scheduled refinements (temporary)
void CollectIncidentElements(int elem, const RefCoord coord[3], Array< int > &list) const
void ReferenceElement(int elem)
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
virtual bool IsGhost(const Element &el) const
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)
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)
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 Append(const T &el)
Append element to array, resize if necessary.
void GetMatrix(DenseMatrix &point_matrix) const
int AddElement(const Element &el)
virtual void Derefine(const Array< int > &derefs)
void QuadFaceSplitLevel(int vn1, int vn2, int vn3, int vn4, int &h_level, int &v_level) const
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 AddConnection(int r, int c)
void RegisterFaces(int elem, int *fattr=NULL)
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 FindMidEdgeNode(int node1, int node2) const
int parent
parent element, -1 if this is a root element, -2 if free
Data type triangle element.
const Element * GetElement(int i) const
signed char local
local number within 'element'
virtual void ElementSharesFace(int elem, int local, int face)
void Sort()
Sorts the array. This requires operator< to be defined for T.
virtual void ElementSharesVertex(int elem, int local, int vnode)
int Size() const
Returns the number of TYPE I elements.
bool CubeFaceFront(int node, int *n)
A class for non-conforming AMR on higher-order hexahedral, prismatic, quadrilateral or triangular mes...
int GetElementSizeReduction(int i) const
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)
void TraverseTetEdge(int vn0, int vn1, const Point &p0, const Point &p1)
static GeomInfo GI[Geometry::NumGeom]
void Clear(bool hard=false)
Data type tetrahedron element.
NCMesh::RefCoord RefCoord
void ReparentNode(int node, int new_p1, int new_p2)
int NewTriangle(int n0, int n1, int n2, int attr, int eattr0, int eattr1, int eattr2)
void DeleteUnusedFaces(const Array< int > &elemFaces)
int SpaceDimension() const
bool Iso
true if the mesh only contains isotropic refinements
std::map< std::string, int > RefPathMap
std::vector< Slave > slaves
virtual void BuildFaceList()
Nonconforming edge/face within a bigger edge/face.
void DerefineElement(int elem)
void GetElementFacesAttributes(int i, Array< int > &faces, Array< int > &fattr) const
Return the faces and face attributes of leaf element 'i'.
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
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
void RegisterElement(int e)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
mfem::Element * NewMeshElement(int geom) const
bool PrismFaceBottom(int node, int *n)
void DeleteLast()
Delete the last entry.
Helper struct for defining a connectivity table, see Table::MakeFromList.
void UpdateLeafElements()
Array< Element * > elements
int TriFaceSplitLevel(int vn1, int vn2, int vn3) const
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()
void BuildElementToVertexTable()
int GetNV() const
Returns number of vertices. Vertices are only at the corners of elements, where you would expect them...
void Apply(const RefCoord src[3], RefCoord dst[3]) const
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)
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
int EdgeSplitLevel(int vn1, int vn2) const
void SetIJ(int *newI, int *newJ, int newsize=-1)
Replace the I and J arrays with the given newI and newJ arrays.
void Initialize(const mfem::Element *elem)
void FindVertexCousins(int elem, int local, Array< int > &cousins) const
int QuadFaceSplitType(int v1, int v2, int v3, int v4, int mid[5]=NULL) const
Array< int > free_element_ids
bool CubeFaceBottom(int node, int *n)
int index(int i, int j, int nx, int ny)
virtual int GetNVertices() const =0
int parent
Element index in the coarse mesh.
virtual void AssignLeafIndices()
static PointMatrix pm_hex_identity
void FindEdgeElements(int vn1, int vn2, int vn3, int vn4, Array< MeshId > &prisms) const
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.
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'.
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).
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()
virtual void ElementSharesEdge(int elem, int local, int enode)
int GetElementDepth(int i) const
Return the distance of leaf 'i' from the root.
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)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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)
Abstract data type element.
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.
virtual Type GetType() const =0
Returns element's type.
const double * CalcVertexPos(int node) const
int rank
processor number (ParNCMesh), -1 if undefined/unknown
int node[8]
element corners (if ref_type == 0)
int GetVertexRootCoord(int elem, RefCoord coord[3]) const
const Element * GetBdrElement(int i) const
DenseMatrix point_matrix
position within the master edge/face
Defines the position of a fine element within a coarse element.
virtual void Refine(const Array< Refinement > &refinements)
int matrix
Index into the DenseTensor corresponding to the parent Geometry::Type stored in CoarseFineTransformat...
Array< char > face_geom
face geometry by face index, set by OnMeshUpdated
int GetEdgeMaster(int v1, int v2) const