13 #include "../fem/fem.hpp"
31 GeomInfo() : initialized(false) {}
32 void Initialize(
const Element* elem);
41 void GeomInfo::Initialize(
const Element* elem)
43 if (initialized)
return;
45 nv = elem->GetNVertices();
46 ne = elem->GetNEdges();
47 nf = elem->GetNFaces(nfv);
49 for (
int i = 0; i < ne; i++)
50 for (
int j = 0; j < 2; j++)
51 edges[i][j] = elem->GetEdgeVertices(i)[j];
53 for (
int i = 0; i < nf; i++)
54 for (
int j = 0; j < nfv; j++)
55 faces[i][j] = elem->GetFaceVertices(i)[j];
69 for (
int i = 0; i < mesh->
GetNE(); i++)
79 mfem_error(
"NCMesh: only triangles, quads and hexes are supported.");
83 GI[geom].Initialize(elem);
89 for (
int j = 0; j < GI[geom].nv; j++)
97 const double* pos = mesh->
GetVertex(v[j]);
102 nc_elem->
node[j] = node;
114 for (
int i = 0; i < mesh->
GetNBE(); i++)
122 node[i] =
nodes.Peek(v[i], v[i]);
124 MFEM_ABORT(
"Boundary elements inconsistent.");
129 Face* face =
faces.Peek(node[0], node[1], node[2], node[3]);
131 MFEM_ABORT(
"Boundary face not found.");
137 Edge* edge =
nodes.Peek(node[0], node[1])->edge;
139 MFEM_ABORT(
"Boundary edge not found.");
144 mfem_error(
"NCMesh: only segment and quadrilateral boundary "
145 "elements are supported.");
161 for (
int i = 0; i < 8; i++)
177 MFEM_ASSERT(
vertex,
"NCMesh::Node::RefVertex: can't create vertex here.");
183 if (!edge) edge =
new Edge;
189 MFEM_ASSERT(vertex,
"Cannot unref a nonexistent vertex.");
190 if (!vertex->Unref()) vertex = NULL;
191 if (!vertex && !edge) nodes.
Delete(
this);
196 MFEM_ASSERT(
this,
"Node not found.");
197 MFEM_ASSERT(edge,
"Cannot unref a nonexistent edge.");
198 if (!edge->Unref()) edge = NULL;
199 if (!vertex && !edge) nodes.
Delete(
this);
204 MFEM_ASSERT(!vertex && !edge,
"Node was not unreffed properly.");
205 if (vertex)
delete vertex;
206 if (edge)
delete edge;
212 GeomInfo& gi = GI[elem->
geom];
215 for (
int i = 0; i < gi.nv; i++)
216 node[i]->RefVertex();
219 for (
int i = 0; i < gi.ne; i++)
221 const int* ev = gi.edges[i];
222 nodes.Get(node[ev[0]], node[ev[1]])->RefEdge();
226 for (
int i = 0; i < gi.nf; i++)
228 const int* fv = gi.faces[i];
229 faces.Get(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]])->Ref();
238 GeomInfo& gi = GI[elem->
geom];
241 for (
int i = 0; i < gi.nf; i++)
243 const int* fv = gi.faces[i];
244 Face* face =
faces.Peek(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
250 for (
int i = 0; i < gi.ne; i++)
252 const int* ev = gi.edges[i];
258 for (
int i = 0; i < gi.nv; i++)
266 else if (elem[1] == NULL)
269 MFEM_ASSERT(0,
"Can't have 3 elements in Face::elem[2].");
276 else if (elem[1] == e)
279 MFEM_ASSERT(0,
"Element not found in Face::elem[2].");
285 GeomInfo& gi = GI[elem->
geom];
287 for (
int i = 0; i < gi.nf; i++)
289 const int* fv = gi.faces[i];
290 Face* face =
faces.Peek(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]]);
299 MFEM_ASSERT(!elem[1],
"Not a single element face.");
304 MFEM_ASSERT(elem[1],
"No elements in face.");
337 if ((v1->
p1 != v1->
p2) && (v2->
p1 != v2->
p2))
350 mid =
nodes.Peek(w1, w2);
360 : geom(geom), attribute(attr), ref_type(0), index(-1)
374 int fattr0,
int fattr1,
int fattr2,
375 int fattr3,
int fattr4,
int fattr5)
384 for (
int i = 0; i < gi_hex.nf; i++)
386 const int* fv = gi_hex.faces[i];
401 int eattr0,
int eattr1,
int eattr2,
int eattr3)
409 for (
int i = 0; i < gi_quad.ne; i++)
411 const int* ev = gi_quad.edges[i];
414 edge[i] = node->
edge;
427 int attr,
int eattr0,
int eattr1,
int eattr2)
435 for (
int i = 0; i < gi_tri.ne; i++)
437 const int* ev = gi_tri.edges[i];
440 edge[i] = node->
edge;
453 "NCMesh::NewVertex: missing parent vertices.");
457 for (
int i = 0; i < 3; i++)
467 if (!mid) mid =
nodes.Get(v1, v2);
492 midf =
nodes.Get(e2, e4);
500 {
return node == n[0] || node == n[3] || node == n[4] || node == n[7]; }
503 {
return node == n[1] || node == n[2] || node == n[5] || node == n[6]; }
506 {
return node == n[0] || node == n[1] || node == n[4] || node == n[5]; }
509 {
return node == n[2] || node == n[3] || node == n[6] || node == n[7]; }
512 {
return node == n[0] || node == n[1] || node == n[2] || node == n[3]; }
515 {
return node == n[4] || node == n[5] || node == n[6] || node == n[7]; }
525 MFEM_ASSERT(!elem->
ref_type,
"Element already refined.");
546 MFEM_ASSERT(0,
"Inconsistent element/face structure.");
551 Node* mid12,
Node* mid34,
int level)
584 nodes.Reparent(midf, mid12->
id, mid34->
id);
618 if (!ref_type)
return;
623 int remaining = ref_type & ~elem->
ref_type;
626 for (
int i = 0; i < 8; i++)
637 memset(child, 0,
sizeof(child));
644 for (
int i = 0; i < gi_hex.nf; i++)
646 const int* fv = gi_hex.faces[i];
647 Face* face =
faces.Peek(no[fv[0]], no[fv[1]], no[fv[2]], no[fv[3]]);
673 no[4], mid45, mid67, no[7], attr,
674 fa[0], fa[1], -1, fa[3], fa[4], fa[5]);
677 mid45, no[5], no[6], mid67, attr,
678 fa[0], fa[1], fa[2], fa[3], -1, fa[5]);
685 else if (ref_type == 2)
693 no[4], no[5], mid56, mid74, attr,
694 fa[0], fa[1], fa[2], -1, fa[4], fa[5]);
697 mid74, mid56, no[6], no[7], attr,
698 fa[0], -1, fa[2], fa[3], fa[4], fa[5]);
705 else if (ref_type == 4)
713 mid04, mid15, mid26, mid37, attr,
714 fa[0], fa[1], fa[2], fa[3], fa[4], -1);
717 no[4], no[5], no[6], no[7], attr,
718 -1, fa[1], fa[2], fa[3], fa[4], fa[5]);
725 else if (ref_type == 3)
741 no[4], mid45, midf5, mid74, attr,
742 fa[0], fa[1], -1, -1, fa[4], fa[5]);
745 mid45, no[5], mid56, midf5, attr,
746 fa[0], fa[1], fa[2], -1, -1, fa[5]);
749 midf5, mid56, no[6], mid67, attr,
750 fa[0], -1, fa[2], fa[3], -1, fa[5]);
753 mid74, midf5, mid67, no[7], attr,
754 fa[0], -1, -1, fa[3], fa[4], fa[5]);
761 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
762 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
764 else if (ref_type == 5)
780 mid04, midf1, midf3, mid37, attr,
781 fa[0], fa[1], -1, fa[3], fa[4], -1);
784 midf1, mid15, mid26, midf3, attr,
785 fa[0], fa[1], fa[2], fa[3], -1, -1);
788 mid45, no[5], no[6], mid67, attr,
789 -1, fa[1], fa[2], fa[3], -1, fa[5]);
792 no[4], mid45, mid67, no[7], attr,
793 -1, fa[1], -1, fa[3], fa[4], fa[5]);
800 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
801 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
803 else if (ref_type == 6)
819 mid04, mid15, midf2, midf4, attr,
820 fa[0], fa[1], fa[2], -1, fa[4], -1);
823 midf4, midf2, mid26, mid37, attr,
824 fa[0], -1, fa[2], fa[3], fa[4], -1);
827 no[4], no[5], mid56, mid74, attr,
828 -1, fa[1], fa[2], -1, fa[4], fa[5]);
831 mid74, mid56, no[6], no[7], attr,
832 -1, -1, fa[2], fa[3], fa[4], fa[5]);
839 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
840 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
842 else if (ref_type == 7)
869 mid04, midf1, midel, midf4, attr,
870 fa[0], fa[1], -1, -1, fa[4], -1);
873 midf1, mid15, midf2, midel, attr,
874 fa[0], fa[1], fa[2], -1, -1, -1);
877 midel, midf2, mid26, midf3, attr,
878 fa[0], -1, fa[2], fa[3], -1, -1);
881 midf4, midel, midf3, mid37, attr,
882 fa[0], -1, -1, fa[3], fa[4], -1);
885 no[4], mid45, midf5, mid74, attr,
886 -1, fa[1], -1, -1, fa[4], fa[5]);
889 mid45, no[5], mid56, midf5, attr,
890 -1, fa[1], fa[2], -1, -1, fa[5]);
893 midf5, mid56, no[6], mid67, attr,
894 -1, -1, fa[2], fa[3], -1, fa[5]);
897 mid74, midf5, mid67, no[7], attr,
898 -1, -1, -1, fa[3], fa[4], fa[5]);
900 CheckIsoFace(no[3], no[2], no[1], no[0], mid23, mid12, mid01, mid30, midf0);
901 CheckIsoFace(no[0], no[1], no[5], no[4], mid01, mid15, mid45, mid04, midf1);
902 CheckIsoFace(no[1], no[2], no[6], no[5], mid12, mid26, mid56, mid15, midf2);
903 CheckIsoFace(no[2], no[3], no[7], no[6], mid23, mid37, mid67, mid26, midf3);
904 CheckIsoFace(no[3], no[0], no[4], no[7], mid30, mid04, mid74, mid37, midf4);
905 CheckIsoFace(no[4], no[5], no[6], no[7], mid45, mid56, mid67, mid74, midf5);
908 MFEM_ABORT(
"Invalid refinement type.");
913 int ea0 =
nodes.Peek(no[0], no[1])->edge->attribute;
914 int ea1 =
nodes.Peek(no[1], no[2])->edge->attribute;
915 int ea2 =
nodes.Peek(no[2], no[3])->edge->attribute;
916 int ea3 =
nodes.Peek(no[3], no[0])->edge->attribute;
926 attr, ea0, -1, ea2, ea3);
929 attr, ea0, ea1, ea2, -1);
931 else if (ref_type == 2)
937 attr, ea0, ea1, -1, ea3);
940 attr, -1, ea1, ea2, ea3);
942 else if (ref_type == 3)
952 attr, ea0, -1, -1, ea3);
955 attr, ea0, ea1, -1, -1);
958 attr, -1, ea1, ea2, -1);
961 attr, -1, -1, ea2, ea3);
964 MFEM_ABORT(
"Invalid refinement type.");
969 int ea0 =
nodes.Peek(no[0], no[1])->edge->attribute;
970 int ea1 =
nodes.Peek(no[1], no[2])->edge->attribute;
971 int ea2 =
nodes.Peek(no[2], no[0])->edge->attribute;
978 child[0] =
NewTriangle(no[0], mid01, mid20, attr, ea0, -1, ea2);
979 child[1] =
NewTriangle(mid01, no[1], mid12, attr, ea0, ea1, -1);
980 child[2] =
NewTriangle(mid20, mid12, no[2], attr, -1, ea1, ea2);
981 child[3] =
NewTriangle(mid01, mid12, mid20, attr, -1, -1, -1);
984 MFEM_ABORT(
"Unsupported element geometry.");
987 for (
int i = 0; i < 8; i++)
995 for (
int i = 0; i < 8; i++)
1001 memcpy(elem->
child, child,
sizeof(elem->
child));
1008 for (
int i = refinements.
Size()-1; i >= 0; i--)
1035 std::cout <<
"Refined " << refinements.
Size() <<
" + " << nforced
1036 <<
" elements" << std::endl;
1055 it->vertex->index = num_vert++;
1078 for (
int i = 0; i < 8; i++)
1101 vertices[i++].SetCoords(it->vertex->pos);
1110 GeomInfo& gi = GI[nc_elem->
geom];
1114 switch (nc_elem->
geom)
1123 for (
int j = 0; j < gi.nv; j++)
1129 for (
int k = 0; k < gi.nf; k++)
1131 const int* fv = gi.faces[k];
1132 Face* face =
faces.Peek(node[fv[0]], node[fv[1]],
1133 node[fv[2]], node[fv[3]]);
1138 for (
int j = 0; j < 4; j++)
1147 for (
int k = 0; k < gi.ne; k++)
1149 const int* ev = gi.edges[k];
1150 Edge* edge =
nodes.Peek(node[ev[0]], node[ev[1]])->edge;
1155 for (
int j = 0; j < 2; j++)
1158 boundary.
Append(segment);
1170 for (
int i = 0; i < edge_vertex->
Size(); i++)
1172 const int *ev = edge_vertex->
GetRow(i);
1175 MFEM_ASSERT(node && node->
edge,
"Edge not found.");
1182 for (
int i = 0; i < mesh->
GetNFaces(); i++)
1184 const int* fv = mesh->
GetFace(i)->GetVertices();
1188 MFEM_ASSERT(face,
"Face not found.");
1202 Node* e3 = e1 ?
nodes.Peek(v3, v4) : NULL;
1203 Node* e4 = e2 ?
nodes.Peek(v4, v1) : NULL;
1206 if (mid) mid[0] = e1, mid[1] = e2, mid[2] = e3, mid[3] = e4;
1209 Node *midf1 = NULL, *midf2 = NULL;
1210 if (e1 && e3) midf1 =
nodes.Peek(e1, e3);
1211 if (e2 && e4) midf2 =
nodes.Peek(e2, e4);
1214 MFEM_ASSERT(!(midf1 && midf2),
"Incorrectly split face!");
1216 if (!midf1 && !midf2)
1227 for (
int i = 0; i < 8; i++)
1228 if (elem->
node[i] == node)
1231 MFEM_ABORT(
"Node not found.");
1235 static int find_hex_face(
int a,
int b,
int c)
1237 for (
int i = 0; i < 6; i++)
1239 const int* fv = gi_hex.faces[i];
1240 if ((a == fv[0] || a == fv[1] || a == fv[2] || a == fv[3]) &&
1241 (b == fv[0] || b == fv[1] || b == fv[2] || b == fv[3]) &&
1242 (c == fv[0] || c == fv[1] || c == fv[2] || c == fv[3]))
1247 MFEM_ABORT(
"Face not found.");
1259 int fi = find_hex_face(master[0], master[1], master[2]);
1260 const int* fv = gi_hex.faces[fi];
1263 for (
int i = 0, j; i < 4; i++)
1265 for (j = 0; j < 4; j++)
1266 if (fv[i] == master[j])
1269 for (
int k = 0; k < pm.
Height(); k++)
1274 MFEM_ASSERT(j != 4,
"Node not found.");
1281 return (sign = 1.0, dof);
1283 return (sign = -1.0, -1 - dof);
1290 for (
int i = 0; i < slave_dofs.
Size(); i++)
1298 for (
int j = 0; j < master_dofs.
Size(); j++)
1300 double coef = I(i, j);
1301 if (std::abs(coef) > 1e-12)
1304 int mdof =
decode_dof(master_dofs[j], msign);
1319 if (mid->
edge && level > 0)
1325 if (slave_dofs.
Size() > 0)
1333 pm(0,0) = t0, pm(0,1) = t1;
1352 double tmid = (t0 + t1) / 2;
1364 Face* face =
faces.Peek(v0, v1, v2, v3);
1371 if (slave_dofs.
Size() > 0)
1387 face_fe->GetLocalInterpolation(face_T, I);
1402 Point mid0(pm(0), pm(1)), mid2(pm(2), pm(3));
1406 master_dofs, level+1);
1410 master_dofs, level+1);
1412 else if (split == 2)
1414 Point mid1(pm(1), pm(2)), mid3(pm(3), pm(0));
1418 master_dofs, level+1);
1422 master_dofs, level+1);
1432 if (master_dofs.
Size() > 0)
1436 double t0 = 0.0, t1 = 1.0;
1437 if (node[0]->vertex->index > node[1]->
vertex->
index)
1450 if (master_dofs.
Size() > 0)
1456 ConstrainFace(node[0], node[1], node[2], node[3], pm, master_dofs, 0);
1477 this->space =
space;
1483 MFEM_ASSERT(!elem->
ref_type,
"Not a leaf element.");
1484 GeomInfo& gi = GI[elem->
geom];
1487 for (
int j = 0; j < gi.ne; j++)
1489 const int* ev = gi.edges[j];
1490 Node* node[2] = { elem->
node[ev[0]], elem->
node[ev[1]] };
1492 Node* edge =
nodes.Peek(node[0], node[1]);
1493 MFEM_ASSERT(edge && edge->
edge,
"Edge not found!");
1501 for (
int j = 0; j < gi.nf; j++)
1504 const int* fv = gi.faces[j];
1505 for (
int k = 0; k < 4; k++)
1506 node[k] = elem->
node[fv[k]];
1508 Face* face =
faces.Peek(node[0], node[1], node[2], node[3]);
1509 MFEM_ASSERT(face,
"Face not found!");
1511 if (face->ref_count == 1 && !face->Boundary())
1522 int n_true_dofs = 0;
1523 for (
int i = 0; i < n_dofs; i++)
1531 if (n_true_dofs == n_dofs)
1544 int *cR_I =
new int[n_true_dofs+1];
1545 double *cR_A =
new double[n_true_dofs];
1546 cR_J =
new int[n_true_dofs];
1547 for (
int i = 0; i < n_true_dofs; i++)
1552 cR_I[n_true_dofs] = n_true_dofs;
1553 cR =
new SparseMatrix(cR_I, cR_J, cR_A, n_true_dofs, n_dofs);
1560 for (
int i = 0, true_dof = 0; i < n_dofs; i++)
1567 cP->
Add(i, true_dof++, 1.0);
1574 int n_finalized = n_true_dofs;
1580 for (
int i = 0; i < n_dofs; i++)
1591 cP->
AddRow(i, cols, srow);
1604 if (n_finalized != n_dofs)
1605 MFEM_ABORT(
"Error creating cP matrix.");
1621 point_matrix.
SetSize(points[0].dim, np);
1622 for (
int i = 0; i < np; i++)
1623 for (
int j = 0; j < points[0].dim; j++)
1624 point_matrix(j, i) = points[i].coord[j];
1645 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
1646 Point mid67(pm(6), pm(7)), mid45(pm(4), pm(5));
1650 pm(4), mid45, mid67, pm(7)));
1654 mid45, pm(5), pm(6), mid67));
1658 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
1659 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
1663 pm(4), pm(5), mid56, mid74));
1667 mid74, mid56, pm(6), pm(7)));
1671 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
1672 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
1676 mid04, mid15, mid26, mid37));
1680 pm(4), pm(5), pm(6), pm(7)));
1684 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
1685 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
1686 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
1687 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
1689 Point midf0(mid23, mid12, mid01, mid30);
1690 Point midf5(mid45, mid56, mid67, mid74);
1694 pm(4), mid45, midf5, mid74));
1698 mid45, pm(5), mid56, midf5));
1702 midf5, mid56, pm(6), mid67));
1706 mid74, midf5, mid67, pm(7)));
1710 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
1711 Point mid45(pm(4), pm(5)), mid67(pm(6), pm(7));
1712 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
1713 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
1715 Point midf1(mid01, mid15, mid45, mid04);
1716 Point midf3(mid23, mid37, mid67, mid26);
1720 mid04, midf1, midf3, mid37));
1724 midf1, mid15, mid26, midf3));
1728 mid45, pm(5), pm(6), mid67));
1732 pm(4), mid45, mid67, pm(7)));
1736 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
1737 Point mid56(pm(5), pm(6)), mid74(pm(7), pm(4));
1738 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
1739 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
1741 Point midf2(mid12, mid26, mid56, mid15);
1742 Point midf4(mid30, mid04, mid74, mid37);
1746 mid04, mid15, midf2, midf4));
1750 midf4, midf2, mid26, mid37));
1754 pm(4), pm(5), mid56, mid74));
1758 mid74, mid56, pm(6), pm(7)));
1762 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
1763 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
1764 Point mid45(pm(4), pm(5)), mid56(pm(5), pm(6));
1765 Point mid67(pm(6), pm(7)), mid74(pm(7), pm(4));
1766 Point mid04(pm(0), pm(4)), mid15(pm(1), pm(5));
1767 Point mid26(pm(2), pm(6)), mid37(pm(3), pm(7));
1769 Point midf0(mid23, mid12, mid01, mid30);
1770 Point midf1(mid01, mid15, mid45, mid04);
1771 Point midf2(mid12, mid26, mid56, mid15);
1772 Point midf3(mid23, mid37, mid67, mid26);
1773 Point midf4(mid30, mid04, mid74, mid37);
1774 Point midf5(mid45, mid56, mid67, mid74);
1776 Point midel(midf1, midf3);
1780 mid04, midf1, midel, midf4));
1784 midf1, mid15, midf2, midel));
1788 midel, midf2, mid26, midf3));
1792 midf4, midel, midf3, mid37));
1796 pm(4), mid45, midf5, mid74));
1800 mid45, pm(5), mid56, midf5));
1804 midf5, mid56, pm(6), mid67));
1808 mid74, midf5, mid67, pm(7)));
1815 Point mid01(pm(0), pm(1)), mid23(pm(2), pm(3));
1825 Point mid12(pm(1), pm(2)), mid30(pm(3), pm(0));
1835 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2));
1836 Point mid23(pm(2), pm(3)), mid30(pm(3), pm(0));
1837 Point midel(mid01, mid23);
1854 Point mid01(pm(0), pm(1)), mid12(pm(1), pm(2)), mid20(pm(2), pm(0));
1873 MFEM_ABORT(
"You need to call MarkCoarseLevel before calling Refine and "
1874 "GetFineTransformations.");
1887 (
Point(0,0,0),
Point(1,0,0),
Point(1,1,0),
Point(0,1,0),
1888 Point(0,0,1),
Point(1,0,1),
Point(1,1,1),
Point(0,1,1));
1902 MFEM_ABORT(
"Bad geometry.");
1920 MFEM_ASSERT(n != NULL && n->
p1 != n->
p2,
"Invalid node.");
1925 if ((n2->
p1 != n2->
p2) && (n1->
id == n2->
p1 || n1->
id == n2->
p2))
1934 if ((n1->
p1 != n1->
p2) && (n2->
id == n1->
p1 || n2->
id == n1->
p2))
1950 MFEM_ASSERT(n->
edge != NULL,
"Invalid edge.");
1951 return (n->
edge->
index != master_edge) ? master_edge : -1;
1955 int& h_level,
int& v_level)
1957 int hl1, hl2, vl1, vl2;
1963 h_level = v_level = 0;
1969 h_level = std::max(hl1, hl2);
1970 v_level = std::max(vl1, vl2) + 1;
1976 h_level = std::max(hl1, hl2) + 1;
1977 v_level = std::max(vl1, vl2);
1981 static int max4(
int a,
int b,
int c,
int d)
1983 return std::max(std::max(a, b), std::max(c, d));
1989 GeomInfo& gi = GI[elem->
geom];
1995 for (
int i = 0; i < gi.nf; i++)
1997 const int* fv = gi.faces[i];
1998 FaceSplitLevel(node[fv[0]], node[fv[1]], node[fv[2]], node[fv[3]],
1999 level[i][1], level[i][0]);
2002 splits[0] = max4(level[0][0], level[1][0], level[3][0], level[5][0]);
2003 splits[1] = max4(level[0][1], level[2][0], level[4][0], level[5][1]);
2004 splits[2] = max4(level[1][1], level[2][1], level[3][1], level[4][1]);
2010 MFEM_ABORT(
"'max_level' must be 1 or greater.");
2021 for (
int k = 0; k < 3; k++)
2022 if (splits[k] > max_level)
2023 ref_type |= (1 << k);
2031 if (!refinements.
Size())
break;
2042 for (
int i = 0; i < 8; i++)
2055 int num_vert = 0, num_edges = 0;
2058 if (it->vertex) num_vert++;
2059 if (it->edge) num_edges++;
2062 return num_elem *
sizeof(
Element) +
2063 num_vert *
sizeof(
Vertex) +
2064 num_edges *
sizeof(
Edge) +
2065 nodes.MemoryUsage() +
2066 faces.MemoryUsage() +
Abstract class for Finite Elements.
void ReorderFacePointMat(Node *v0, Node *v1, Node *v2, Node *v3, Element *elem, DenseMatrix &pm)
void LimitNCLevel(int max_level)
int Size() const
Logical size of the array.
Element * NewHexahedron(Node *n0, Node *n1, Node *n2, Node *n3, Node *n4, Node *n5, Node *n6, Node *n7, int attr, int fattr0, int fattr1, int fattr2, int fattr3, int fattr4, int fattr5)
void Add(const int i, const int j, const double a)
DepList dep_list
list of other DOFs this DOF depends on
void GetVerticesElementsBoundary(Array< mfem::Vertex > &vertices, Array< mfem::Element * > &elements, Array< mfem::Element * > &boundary)
int GetNDofs() const
Returns number of degrees of freedom.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
Table * GetEdgeVertexTable() const
Returns the edge-to-vertex Table (3D)
int index
edge number in the Mesh
Array< Element * > coarse_elements
Iterator over items contained in the HashTable.
bool finalized
true if cP matrix row is known for this DOF
FiniteElementSpace * space
FineTransform * GetFineTransforms()
SparseMatrix * GetInterpolation(FiniteElementSpace *space, SparseMatrix **cR_ptr=NULL)
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
Node * PeekAltParents(Node *v1, Node *v2)
int GetNBE() const
Returns number of boundary elements.
void SetEdgeIndicesFromMesh(Mesh *mesh)
Array< RefStackItem > ref_stack
stack of scheduled refinements
int attribute
boundary element attribute, -1 if internal edge
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
void RefElementNodes(Element *elem)
static int find_node(Element *elem, Node *node)
void GetLeafElements(Element *e)
int GetNE() const
Returns number of elements.
const Element * GetFace(int i) const
int index
vertex number in the Mesh
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
void ConstrainEdge(Node *v0, Node *v1, double t0, double t1, Array< int > &master_dofs, int level)
bool DofFinalizable(DofData &vd)
void ProcessMasterEdge(Node *node[2], Node *edge)
Data type quadrilateral element.
void Delete(ItemT *item)
Remove an item from the hash table and also delete the item itself.
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
Vertex * NewVertex(Node *v1, Node *v2)
bool NodeSetY1(Node *node, Node **n)
Array< int > vertex_nodeId
int attribute
boundary element attribute, -1 if internal face
int GetGeometryType() const
int index
Mesh element number.
Element * NewQuadrilateral(Node *n0, Node *n1, Node *n2, Node *n3, int attr, int eattr0, int eattr1, int eattr2, int eattr3)
virtual void GetFaceDofs(int i, Array< int > &dofs) const
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
Data type hexahedron element.
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
void ConstrainFace(Node *v0, Node *v1, Node *v2, Node *v3, const PointMatrix &pm, Array< int > &master_dofs, int level)
int index
face number in the Mesh
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
void ProcessMasterFace(Node *node[4], Face *face)
int Append(const T &el)
Append element to array, resize if necessary.
void GetMatrix(DenseMatrix &point_matrix) const
void CheckAnisoFace(Node *v1, Node *v2, Node *v3, Node *v4, Node *mid12, Node *mid34, int level=0)
DofData * dof_data
DOF temporary data.
void RegisterElement(Element *e)
void AddDependencies(Array< int > &master_dofs, Array< int > &slave_dofs, DenseMatrix &I)
Element(int geom, int attr)
int GetAttribute() const
Return element's attribute.
Data type triangle element.
const Element * GetElement(int i) const
int decode_dof(int dof, double &sign)
int CountElements(Element *elem)
int Size() const
Returns the number of TYPE I elements.
virtual void Finalize(int skip_zeros=1)
bool NodeSetX1(Node *node, Node **n)
void RegisterFaces(Element *elem)
void GetEdgeDofs(int i, Array< int > &dofs) const
void DeleteHierarchy(Element *elem)
void UnrefEdge(HashTable< Node > &nodes)
void ForceRefinement(Node *v1, Node *v2, Node *v3, Node *v4)
Abstract finite element space.
int GetDof() const
Returns the degrees of freedom in the FE space.
void swap(Vector *v1, Vector *v2)
void mfem_error(const char *msg)
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Array< Element * > leaf_elements
void CountSplits(Element *elem, int splits[3])
void UpdateLeafElements()
bool NodeSetZ1(Node *node, Node **n)
Node * GetMidEdgeVertexSimple(Node *v1, Node *v2)
void UnrefElementNodes(Element *elem)
void CheckIsoFace(Node *v1, Node *v2, Node *v3, Node *v4, Node *e1, Node *e2, Node *e3, Node *e4, Node *midf)
int FaceSplitType(Node *v1, Node *v2, Node *v3, Node *v4, Node *mid[4]=NULL)
Node * GetMidFaceVertex(Node *e1, Node *e2, Node *e3, Node *e4)
bool NodeSetZ2(Node *node, Node **n)
bool NodeSetX2(Node *node, Node **n)
void SetFaceIndicesFromMesh(Mesh *mesh)
Element * NewTriangle(Node *n0, Node *n1, Node *n2, int attr, int eattr0, int eattr1, int eattr2)
virtual int GetNVertices() const =0
void SetAttribute(const int attr)
Set element's attribute.
Array< Element * > root_elements
int GetNFaces() const
Return the number of faces in a 3D mesh.
const FiniteElementCollection * FEColl() const
Node * GetMidEdgeVertex(Node *v1, Node *v2)
Element * GetSingleElement() const
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void SetSize(int s)
If the matrix is not a square matrix of size s then recreate it.
void ForgetElement(Element *e)
bool NodeSetY2(Node *node, Node **n)
BiLinear2DFiniteElement QuadrilateralFE
int ref_type
refinement XYZ bit mask (7 = full isotropic)
Abstract data type element.
Data type line segment element.
Linear1DFiniteElement SegmentFE
const Element * GetBdrElement(int i) const
virtual int GetType() const =0
Returns element's type.
void FaceSplitLevel(Node *v1, Node *v2, Node *v3, Node *v4, int &h_level, int &v_level)
void Refine(const Array< Refinement > &refinements)
virtual const FiniteElement * FiniteElementForGeometry(int GeomType) const =0
int GetEdgeMaster(int v1, int v2) const
void UnrefVertex(HashTable< Node > &nodes)