15 #include "../fem/fem.hpp"
16 #include "../general/sort_pairs.hpp"
37 int geom = GetElementBaseGeometry(i);
46 GetElementJacobian(i, J);
49 return pow(fabs(J.
Det()), 1./Dim);
65 GetElementJacobian(i, J);
67 return sqrt((d_hat * d_hat) / (dir * dir));
90 double h_min, h_max, kappa_min, kappa_max, h,
kappa;
92 out <<
"Mesh Characteristics:";
95 sdim = SpaceDimension();
98 if (Vh) { Vh->
SetSize(NumOfElements); }
99 if (Vk) { Vk->
SetSize(NumOfElements); }
101 h_min = kappa_min = numeric_limits<double>::infinity();
102 h_max = kappa_max = -h_min;
103 for (i = 0; i < NumOfElements; i++)
105 GetElementJacobian(i, J);
106 h = pow(fabs(J.
Weight()), 1.0/
double(dim));
107 kappa = (dim == sdim) ?
109 if (Vh) { (*Vh)(i) = h; }
110 if (Vk) { (*Vk)(i) = kappa; }
112 if (h < h_min) { h_min = h; }
113 if (h > h_max) { h_max = h; }
114 if (kappa < kappa_min) { kappa_min =
kappa; }
115 if (kappa > kappa_max) { kappa_max =
kappa; }
121 <<
"Number of vertices : " << GetNV() <<
'\n'
122 <<
"Number of elements : " << GetNE() <<
'\n'
123 <<
"Number of bdr elem : " << GetNBE() <<
'\n'
124 <<
"h_min : " << h_min <<
'\n'
125 <<
"h_max : " << h_max <<
'\n';
130 <<
"Number of vertices : " << GetNV() <<
'\n'
131 <<
"Number of edges : " << GetNEdges() <<
'\n'
132 <<
"Number of elements : " << GetNE() <<
'\n'
133 <<
"Number of bdr elem : " << GetNBE() <<
'\n'
134 <<
"Euler Number : " << EulerNumber2D() <<
'\n'
135 <<
"h_min : " << h_min <<
'\n'
136 <<
"h_max : " << h_max <<
'\n'
137 <<
"kappa_min : " << kappa_min <<
'\n'
138 <<
"kappa_max : " << kappa_max <<
'\n';
143 <<
"Number of vertices : " << GetNV() <<
'\n'
144 <<
"Number of edges : " << GetNEdges() <<
'\n'
145 <<
"Number of faces : " << GetNFaces() <<
'\n'
146 <<
"Number of elements : " << GetNE() <<
'\n'
147 <<
"Number of bdr elem : " << GetNBE() <<
'\n'
148 <<
"Euler Number : " << EulerNumber() <<
'\n'
149 <<
"h_min : " << h_min <<
'\n'
150 <<
"h_max : " << h_max <<
'\n'
151 <<
"kappa_min : " << kappa_min <<
'\n'
152 <<
"kappa_max : " << kappa_max <<
'\n';
154 out <<
'\n' << std::flush;
168 mfem_error(
"Mesh::GetTransformationFEforElement - unknown ElementType");
180 ElTr->
SetFE(GetTransformationFEforElementType(GetElementType(i)));
186 Nodes->FESpace()->GetElementVDofs(i, vdofs);
188 int n = vdofs.
Size()/spaceDim;
190 for (
int k = 0; k < spaceDim; k++)
192 for (
int j = 0; j < n; j++)
194 pm(k,j) = (*Nodes)(vdofs[n*k+j]);
197 ElTr->
SetFE(Nodes->FESpace()->GetFE(i));
209 int nv = elements[i]->GetNVertices();
210 const int *v = elements[i]->GetVertices();
211 int n = vertices.
Size();
213 for (
int k = 0; k < spaceDim; k++)
215 for (
int j = 0; j < nv; j++)
217 pm(k, j) = nodes(k*n+v[j]);
220 ElTr->
SetFE(GetTransformationFEforElementType(GetElementType(i)));
225 Nodes->FESpace()->GetElementVDofs(i, vdofs);
226 int n = vdofs.
Size()/spaceDim;
228 for (
int k = 0; k < spaceDim; k++)
230 for (
int j = 0; j < n; j++)
232 pm(k,j) = nodes(vdofs[n*k+j]);
235 ElTr->
SetFE(Nodes->FESpace()->GetFE(i));
241 GetElementTransformation(i, &Transformation);
243 return &Transformation;
248 GetBdrElementTransformation(i, &FaceTransformation);
249 return &FaceTransformation;
260 GetTransformationFEforElementType(GetBdrElementType(i)));
266 Nodes->FESpace()->GetBdrElementVDofs(i, vdofs);
267 int n = vdofs.
Size()/spaceDim;
269 for (
int k = 0; k < spaceDim; k++)
271 for (
int j = 0; j < n; j++)
273 pm(k,j) = (*Nodes)(vdofs[n*k+j]);
276 ElTr->
SetFE(Nodes->FESpace()->GetBE(i));
282 FTr->
Attribute = (Dim == 1) ? 1 : faces[FaceNo]->GetAttribute();
287 const int *v = (Dim == 1) ? &FaceNo : faces[FaceNo]->GetVertices();
288 const int nv = (Dim == 1) ? 1 : faces[FaceNo]->GetNVertices();
290 for (
int i = 0; i < spaceDim; i++)
292 for (
int j = 0; j < nv; j++)
294 pm(i, j) = vertices[v[j]](i);
297 FTr->
SetFE(GetTransformationFEforElementType(
302 const FiniteElement *face_el = Nodes->FESpace()->GetFaceElement(FaceNo);
306 Nodes->FESpace()->GetFaceVDofs(FaceNo, vdofs);
307 int n = vdofs.
Size()/spaceDim;
309 for (
int i = 0; i < spaceDim; i++)
311 for (
int j = 0; j < n; j++)
313 pm(i, j) = (*Nodes)(vdofs[n*i+j]);
322 FaceInfo &face_info = faces_info[FaceNo];
324 face_el = Nodes->FESpace()->GetTraceElement(face_info.
Elem1No,
330 GetLocalPtToSegTransformation(FaceElemTr.Loc1.Transf,
335 GetLocalSegToTriTransformation(FaceElemTr.Loc1.Transf,
338 GetLocalSegToQuadTransformation(FaceElemTr.Loc1.Transf,
343 GetLocalTriToTetTransformation(FaceElemTr.Loc1.Transf,
348 GetLocalQuadToHexTransformation(FaceElemTr.Loc1.Transf,
354 FaceElemTr.Loc1.Transform(face_el->
GetNodes(), eir);
356 Nodes->GetVectorValues(Transformation, eir, pm);
365 GetFaceTransformation(FaceNo, &FaceTransformation);
366 return &FaceTransformation;
373 GetFaceTransformation(EdgeNo, EdTr);
378 mfem_error(
"Mesh::GetEdgeTransformation not defined in 1D \n");
387 GetEdgeVertices(EdgeNo, v);
390 for (
int i = 0; i < spaceDim; i++)
392 for (
int j = 0; j < nv; j++)
394 pm(i, j) = vertices[v[j]](i);
403 Nodes->FESpace()->GetEdgeVDofs(EdgeNo, vdofs);
404 int n = vdofs.
Size()/spaceDim;
406 for (
int i = 0; i < spaceDim; i++)
408 for (
int j = 0; j < n; j++)
410 pm(i, j) = (*Nodes)(vdofs[n*i+j]);
419 GetEdgeTransformation(EdgeNo, &EdgeTransformation);
420 return &EdgeTransformation;
442 static const int tri_faces[3][2] = {{0, 1}, {1, 2}, {2, 0}};
443 static const int seg_inv_orient[2][2] = {{0, 1}, {1, 0}};
450 tv = tri_faces[i/64];
451 so = seg_inv_orient[i%64];
454 for (j = 0; j < 2; j++)
456 locpm(0, so[j]) = TriVert->
IntPoint(tv[j]).
x;
457 locpm(1, so[j]) = TriVert->
IntPoint(tv[j]).
y;
465 static const int quad_faces[4][2] = {{0, 1}, {1, 2}, {2, 3}, {3, 0}};
466 static const int seg_inv_orient[2][2] = {{0, 1}, {1, 0}};
473 qv = quad_faces[i/64];
474 so = seg_inv_orient[i%64];
477 for (j = 0; j < 2; j++)
479 locpm(0, so[j]) = QuadVert->
IntPoint(qv[j]).
x;
480 locpm(1, so[j]) = QuadVert->
IntPoint(qv[j]).
y;
486 {1, 2, 3}, {0, 3, 2},
493 {3, 2, 1, 0}, {0, 1, 5, 4},
494 {1, 2, 6, 5}, {2, 3, 7, 6},
495 {3, 0, 4, 7}, {4, 5, 6, 7}
500 {0, 1, 2}, {1, 0, 2},
501 {2, 0, 1}, {2, 1, 0},
507 {0, 1, 2, 3}, {0, 3, 2, 1},
508 {1, 2, 3, 0}, {1, 0, 3, 2},
509 {2, 3, 0, 1}, {2, 1, 0, 3},
510 {3, 0, 1, 2}, {3, 2, 1, 0}
520 const int *tv = tet_faces[i/64];
523 const int *to = tri_orientations[i%64];
527 for (
int j = 0; j < 3; j++)
530 locpm(0, j) = vert.
x;
531 locpm(1, j) = vert.
y;
532 locpm(2, j) = vert.
z;
543 const int *hv = hex_faces[i/64];
545 const int *qo = quad_orientations[i%64];
548 for (
int j = 0; j < 4; j++)
551 locpm(0, j) = vert.
x;
552 locpm(1, j) = vert.
y;
553 locpm(2, j) = vert.
z;
560 FaceInfo &face_info = faces_info[FaceNo];
562 FaceElemTr.Elem1 = NULL;
563 FaceElemTr.Elem2 = NULL;
569 GetElementTransformation(FaceElemTr.Elem1No, &Transformation);
570 FaceElemTr.Elem1 = &Transformation;
576 FaceElemTr.Elem2No = face_info.
Elem2No;
577 if ((mask & 2) && FaceElemTr.Elem2No >= 0)
580 if (NURBSext && (mask & 1)) { MFEM_ABORT(
"NURBS mesh not supported!"); }
582 GetElementTransformation(FaceElemTr.Elem2No, &Transformation2);
583 FaceElemTr.Elem2 = &Transformation2;
587 : faces[FaceNo]->GetGeometryType();
590 FaceElemTr.Face = (mask & 16) ? GetFaceTransformation(FaceNo) : NULL;
593 int face_type = (Dim == 1) ?
Element::POINT : faces[FaceNo]->GetType();
599 GetLocalPtToSegTransformation(FaceElemTr.Loc1.Transf,
602 if (FaceElemTr.Elem2No >= 0 && (mask & 8))
604 GetLocalPtToSegTransformation(FaceElemTr.Loc2.Transf,
614 GetLocalSegToTriTransformation(FaceElemTr.Loc1.Transf,
619 GetLocalSegToQuadTransformation(FaceElemTr.Loc1.Transf,
624 if (FaceElemTr.Elem2No >= 0 && (mask & 8))
628 GetLocalSegToTriTransformation(FaceElemTr.Loc2.Transf,
633 GetLocalSegToQuadTransformation(FaceElemTr.Loc2.Transf,
636 if (IsSlaveFace(face_info))
638 ApplySlaveTransformation(FaceElemTr.Loc2.Transf, face_info);
639 const int *fv = faces[FaceNo]->GetVertices();
642 DenseMatrix &pm = FaceElemTr.Loc2.Transf.GetPointMat();
643 mfem::Swap<double>(pm(0,0), pm(0,1));
644 mfem::Swap<double>(pm(1,0), pm(1,1));
654 GetLocalTriToTetTransformation(FaceElemTr.Loc1.Transf,
657 if (FaceElemTr.Elem2No >= 0 && (mask & 8))
659 GetLocalTriToTetTransformation(FaceElemTr.Loc2.Transf,
661 if (IsSlaveFace(face_info))
663 ApplySlaveTransformation(FaceElemTr.Loc2.Transf, face_info);
672 GetLocalQuadToHexTransformation(FaceElemTr.Loc1.Transf,
675 if (FaceElemTr.Elem2No >= 0 && (mask & 8))
677 GetLocalQuadToHexTransformation(FaceElemTr.Loc2.Transf,
679 if (IsSlaveFace(face_info))
681 ApplySlaveTransformation(FaceElemTr.Loc2.Transf, face_info);
692 return fi.
NCFace >= 0 && nc_faces_info[fi.
NCFace].Slave;
698 #ifdef MFEM_THREAD_SAFE
703 MFEM_ASSERT(fi.
NCFace >= 0,
"");
714 fn = be_to_face[BdrElemNo];
718 fn = be_to_edge[BdrElemNo];
722 fn = boundary[BdrElemNo]->GetVertices()[0];
725 if (FaceIsTrueInterior(fn) || faces_info[fn].NCFace >= 0)
729 tr = GetFaceElementTransformations(fn);
736 *Elem1 = faces_info[Face].Elem1No;
737 *Elem2 = faces_info[Face].Elem2No;
742 *Inf1 = faces_info[Face].Elem1Inf;
743 *Inf2 = faces_info[Face].Elem2Inf;
748 NumOfVertices = NumOfElements = NumOfBdrElements = NumOfEdges = -1;
749 WantTwoLevelState = 0;
755 nc_coarse_level = NULL;
761 el_to_face = el_to_el = bel_to_edge = face_edge = edge_vertex = NULL;
780 delete nc_coarse_level;
781 nc_coarse_level = NULL;
790 el_to_el = face_edge = edge_vertex = NULL;
792 delete nc_coarse_level;
793 nc_coarse_level = NULL;
801 for (
int i = 0; i < attribs.
Size(); i++)
803 attribs[i] = GetBdrAttribute(i);
807 attribs.
Copy(bdr_attributes);
808 if (bdr_attributes.Size() > 0 && bdr_attributes[0] <= 0)
810 MFEM_WARNING(
"Non-positive attributes on the boundary!");
814 for (
int i = 0; i < attribs.
Size(); i++)
816 attribs[i] = GetAttribute(i);
820 attribs.
Copy(attributes);
821 if (attributes.Size() > 0 && attributes[0] <= 0)
823 MFEM_WARNING(
"Non-positive attributes in the domain!");
830 spaceDim = _spaceDim;
836 vertices.SetSize(NVert);
839 elements.SetSize(NElem);
841 NumOfBdrElements = 0;
842 boundary.SetSize(NBdrElem);
847 double *y = vertices[NumOfVertices]();
849 for (
int i = 0; i < spaceDim; i++)
858 elements[NumOfElements++] =
new Triangle(vi, attr);
863 elements[NumOfElements++] =
new Triangle(vi, attr);
873 #ifdef MFEM_USE_MEMALLOC
875 tet = TetMemory.Alloc();
878 elements[NumOfElements++] = tet;
880 elements[NumOfElements++] =
new Tetrahedron(vi, attr);
886 elements[NumOfElements++] =
new Hexahedron(vi, attr);
891 static const int hex_to_tet[6][4] =
893 { 0, 1, 2, 6 }, { 0, 5, 1, 6 }, { 0, 4, 5, 6 },
894 { 0, 2, 3, 6 }, { 0, 3, 7, 6 }, { 0, 7, 4, 6 }
898 for (
int i = 0; i < 6; i++)
900 for (
int j = 0; j < 4; j++)
902 ti[j] = vi[hex_to_tet[i][j]];
910 boundary[NumOfBdrElements++] =
new Segment(vi, attr);
915 boundary[NumOfBdrElements++] =
new Triangle(vi, attr);
925 static const int quad_to_tri[2][3] = { { 0, 1, 2 }, { 0, 2, 3 } };
928 for (
int i = 0; i < 2; i++)
930 for (
int j = 0; j < 3; j++)
932 ti[j] = vi[quad_to_tri[i][j]];
934 AddBdrTriangle(ti, attr);
941 Array<int> &be2face = (Dim == 2) ? be_to_edge : be_to_face;
945 for (i = 0; i < boundary.Size(); i++)
947 FreeElement(boundary[i]);
957 NumOfBdrElements = 0;
958 for (i = 0; i < faces_info.Size(); i++)
960 if (faces_info[i].Elem2No < 0) { NumOfBdrElements++; }
963 boundary.SetSize(NumOfBdrElements);
964 be2face.
SetSize(NumOfBdrElements);
965 for (j = i = 0; i < faces_info.Size(); i++)
967 if (faces_info[i].Elem2No < 0)
969 boundary[j] = faces[i]->Duplicate(
this);
984 static int edge_compare(
const void *ii,
const void *jj)
986 edge_length *i = (edge_length *)ii, *j = (edge_length *)jj;
987 if (i->length > j->length) {
return (1); }
988 if (i->length < j->length) {
return (-1); }
994 CheckElementOrientation(fix_orientation);
998 MarkTriMeshForRefinement();
1003 el_to_edge =
new Table;
1004 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1006 CheckBdrElementOrientation();
1021 bool fix_orientation)
1023 if (fix_orientation)
1025 CheckElementOrientation(fix_orientation);
1030 el_to_edge =
new Table;
1031 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1033 CheckBdrElementOrientation();
1048 #ifdef MFEM_USE_GECKO
1054 Gecko::Functional *functional =
1055 new Gecko::FunctionalGeometric();
1056 unsigned int iterations = 1;
1057 unsigned int window = 2;
1058 unsigned int period = 1;
1059 unsigned int seed = 0;
1062 for (
int elemid = 0; elemid < GetNE(); ++elemid)
1069 const Table &my_el_to_el = ElementToElementTable();
1070 for (
int elemid = 0; elemid < GetNE(); ++elemid)
1072 const int *neighid = my_el_to_el.
GetRow(elemid);
1073 for (
int i = 0; i < my_el_to_el.
RowSize(elemid); ++i)
1075 graph.insert(elemid + 1, neighid[i] + 1);
1080 graph.order(functional, iterations, window, period, seed);
1083 Gecko::Node::Index NE = GetNE();
1084 for (Gecko::Node::Index gnodeid = 1; gnodeid <= NE; ++gnodeid)
1086 ordering[gnodeid - 1] = graph.rank(gnodeid);
1098 MFEM_WARNING(
"element reordering of NURBS meshes is not supported.");
1103 MFEM_WARNING(
"element reordering of non-conforming meshes is not"
1107 MFEM_VERIFY(ordering.
Size() == GetNE(),
"invalid reordering array.")
1137 old_elem_node_vals.
SetSize(GetNE());
1138 nodes_fes = Nodes->FESpace();
1141 for (
int old_elid = 0; old_elid < GetNE(); ++old_elid)
1144 Nodes->GetSubVector(old_dofs, vals);
1145 old_elem_node_vals[old_elid] =
new Vector(vals);
1151 for (
int old_elid = 0; old_elid < ordering.
Size(); ++old_elid)
1153 int new_elid = ordering[old_elid];
1154 new_elements[new_elid] = elements[old_elid];
1159 if (reorder_vertices)
1163 vertex_ordering = -1;
1165 int new_vertex_ind = 0;
1166 for (
int new_elid = 0; new_elid < GetNE(); ++new_elid)
1168 int *elem_vert = elements[new_elid]->GetVertices();
1169 int nv = elements[new_elid]->GetNVertices();
1170 for (
int vi = 0; vi < nv; ++vi)
1172 int old_vertex_ind = elem_vert[vi];
1173 if (vertex_ordering[old_vertex_ind] == -1)
1175 vertex_ordering[old_vertex_ind] = new_vertex_ind;
1176 new_vertices[new_vertex_ind] = vertices[old_vertex_ind];
1185 for (
int new_elid = 0; new_elid < GetNE(); ++new_elid)
1187 int *elem_vert = elements[new_elid]->GetVertices();
1188 int nv = elements[new_elid]->GetNVertices();
1189 for (
int vi = 0; vi < nv; ++vi)
1191 elem_vert[vi] = vertex_ordering[elem_vert[vi]];
1196 for (
int belid = 0; belid < GetNBE(); ++belid)
1198 int *be_vert = boundary[belid]->GetVertices();
1199 int nv = boundary[belid]->GetNVertices();
1200 for (
int vi = 0; vi < nv; ++vi)
1202 be_vert[vi] = vertex_ordering[be_vert[vi]];
1213 el_to_edge =
new Table;
1214 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1219 GetElementToFaceTable();
1229 for (
int old_elid = 0; old_elid < GetNE(); ++old_elid)
1231 int new_elid = ordering[old_elid];
1233 Nodes->SetSubVector(new_dofs, *(old_elem_node_vals[old_elid]));
1234 delete old_elem_node_vals[old_elid];
1246 MarkTriMeshForRefinement();
1250 MarkTetMeshForRefinement();
1260 for (
int i = 0; i < NumOfElements; i++)
1264 GetPointMatrix(i, pmat);
1265 elements[i]->MarkEdge(pmat);
1273 edge_length *length =
new edge_length[NumOfEdges];
1274 for (
int i = 0; i < NumOfVertices; i++)
1279 length[j].length = GetLength(i, it.Column());
1285 qsort(length, NumOfEdges,
sizeof(edge_length), edge_compare);
1288 for (
int i = 0; i < NumOfEdges; i++)
1290 order[length[i].edge] = i;
1300 DSTable v_to_v(NumOfVertices);
1301 GetVertexToVertexTable(v_to_v);
1304 GetEdgeOrdering(v_to_v, order);
1306 for (
int i = 0; i < NumOfElements; i++)
1310 elements[i]->MarkEdge(v_to_v, order);
1313 for (
int i = 0; i < NumOfBdrElements; i++)
1317 boundary[i]->MarkEdge(v_to_v, order);
1324 if (*old_v_to_v && *old_elem_vert)
1332 if (*old_v_to_v == NULL)
1335 if (num_edge_dofs > 0)
1337 *old_v_to_v =
new DSTable(NumOfVertices);
1338 GetVertexToVertexTable(*(*old_v_to_v));
1341 if (*old_elem_vert == NULL)
1344 int num_elem_dofs = fec->
DofForGeometry(GetElementBaseGeometry(0));
1345 if (num_elem_dofs > 1)
1347 *old_elem_vert =
new Table;
1348 (*old_elem_vert)->
MakeI(GetNE());
1349 for (
int i = 0; i < GetNE(); i++)
1351 (*old_elem_vert)->AddColumnsInRow(i, elements[i]->GetNVertices());
1353 (*old_elem_vert)->MakeJ();
1354 for (
int i = 0; i < GetNE(); i++)
1356 (*old_elem_vert)->AddConnections(i, elements[i]->GetVertices(),
1357 elements[i]->GetNVertices());
1359 (*old_elem_vert)->ShiftUpI();
1373 int num_elem_dofs = fec->
DofForGeometry(GetElementBaseGeometry(0));
1389 if (num_edge_dofs > 0)
1391 DSTable new_v_to_v(NumOfVertices);
1392 GetVertexToVertexTable(new_v_to_v);
1394 for (
int i = 0; i < NumOfVertices; i++)
1398 int old_i = (*old_v_to_v)(i, it.Column());
1399 int new_i = it.Index();
1406 old_dofs.
SetSize(num_edge_dofs);
1407 new_dofs.
SetSize(num_edge_dofs);
1408 for (
int j = 0; j < num_edge_dofs; j++)
1410 old_dofs[j] = offset + old_i * num_edge_dofs + j;
1411 new_dofs[j] = offset + new_i * num_edge_dofs + j;
1415 for (
int j = 0; j < old_dofs.
Size(); j++)
1417 (*Nodes)(new_dofs[j]) = onodes(old_dofs[j]);
1421 offset += NumOfEdges * num_edge_dofs;
1424 cout <<
"Mesh::DoNodeReorder : redges = " << redges << endl;
1429 if (num_face_dofs > 0)
1432 Table old_face_vertex;
1433 old_face_vertex.
MakeI(NumOfFaces);
1434 for (
int i = 0; i < NumOfFaces; i++)
1438 old_face_vertex.
MakeJ();
1439 for (
int i = 0; i < NumOfFaces; i++)
1441 faces[i]->GetNVertices());
1445 STable3D *faces_tbl = GetElementToFaceTable(1);
1449 for (
int i = 0; i < NumOfFaces; i++)
1451 int *old_v = old_face_vertex.
GetRow(i), *new_v;
1452 int new_i, new_or, *dof_ord;
1453 switch (old_face_vertex.
RowSize(i))
1456 new_i = (*faces_tbl)(old_v[0], old_v[1], old_v[2]);
1457 new_v = faces[new_i]->GetVertices();
1458 new_or = GetTriOrientation(old_v, new_v);
1463 new_i = (*faces_tbl)(old_v[0], old_v[1], old_v[2], old_v[3]);
1464 new_v = faces[new_i]->GetVertices();
1465 new_or = GetQuadOrientation(old_v, new_v);
1470 old_dofs.
SetSize(num_face_dofs);
1471 new_dofs.
SetSize(num_face_dofs);
1472 for (
int j = 0; j < num_face_dofs; j++)
1474 old_dofs[j] = offset + i * num_face_dofs + j;
1475 new_dofs[j] = offset + new_i * num_face_dofs + dof_ord[j];
1481 for (
int j = 0; j < old_dofs.
Size(); j++)
1483 (*Nodes)(new_dofs[j]) = onodes(old_dofs[j]);
1487 offset += NumOfFaces * num_face_dofs;
1493 if (num_elem_dofs > 1)
1505 for (
int i = 0; i < GetNE(); i++)
1507 int *old_v = old_elem_vert->
GetRow(i);
1508 int *new_v = elements[i]->GetVertices();
1509 int new_or, *dof_ord;
1510 int geom = elements[i]->GetGeometryType();
1514 new_or = (old_v[0] == new_v[0]) ? +1 : -1;
1517 new_or = GetTriOrientation(old_v, new_v);
1520 new_or = GetQuadOrientation(old_v, new_v);
1525 <<
" elements (" << fec->
Name()
1526 <<
" FE collection) are not supported yet!" << endl;
1531 if (dof_ord == NULL)
1533 cerr <<
"Mesh::DoNodeReorder : FE collection '" << fec->
Name()
1535 <<
" elements!" << endl;
1538 old_dofs.
SetSize(num_elem_dofs);
1539 new_dofs.
SetSize(num_elem_dofs);
1540 for (
int j = 0; j < num_elem_dofs; j++)
1543 old_dofs[j] = offset + dof_ord[j];
1544 new_dofs[j] = offset + j;
1548 for (
int j = 0; j < old_dofs.
Size(); j++)
1550 (*Nodes)(new_dofs[j]) = onodes(old_dofs[j]);
1553 offset += num_elem_dofs;
1560 if (num_face_dofs == 0)
1564 GetElementToFaceTable();
1567 CheckBdrElementOrientation();
1572 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1577 CheckBdrElementOrientation();
1584 CheckElementOrientation(fix_orientation);
1586 if (NumOfBdrElements == 0)
1588 GetElementToFaceTable();
1590 GenerateBoundaryElements();
1595 MarkTetMeshForRefinement();
1598 GetElementToFaceTable();
1601 CheckBdrElementOrientation();
1603 if (generate_edges == 1)
1605 el_to_edge =
new Table;
1606 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1622 CheckElementOrientation(fix_orientation);
1624 GetElementToFaceTable();
1627 if (NumOfBdrElements == 0)
1629 GenerateBoundaryElements();
1632 CheckBdrElementOrientation();
1636 el_to_edge =
new Table;
1637 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1650 int generate_edges,
double sx,
double sy,
double sz)
1654 int NVert, NElem, NBdrElem;
1656 NVert = (nx+1) * (ny+1) * (nz+1);
1657 NElem = nx * ny * nz;
1658 NBdrElem = 2*(nx*ny+nx*nz+ny*nz);
1665 InitMesh(3, 3, NVert, NElem, NBdrElem);
1671 for (z = 0; z <= nz; z++)
1673 coord[2] = ((double) z / nz) * sz;
1674 for (y = 0; y <= ny; y++)
1676 coord[1] = ((double) y / ny) * sy;
1677 for (x = 0; x <= nx; x++)
1679 coord[0] = ((double) x / nx) * sx;
1685 #define VTX(XC, YC, ZC) ((XC)+((YC)+(ZC)*(ny+1))*(nx+1))
1688 for (z = 0; z < nz; z++)
1690 for (y = 0; y < ny; y++)
1692 for (x = 0; x < nx; x++)
1694 ind[0] = VTX(x , y , z );
1695 ind[1] = VTX(x+1, y , z );
1696 ind[2] = VTX(x+1, y+1, z );
1697 ind[3] = VTX(x , y+1, z );
1698 ind[4] = VTX(x , y , z+1);
1699 ind[5] = VTX(x+1, y , z+1);
1700 ind[6] = VTX(x+1, y+1, z+1);
1701 ind[7] = VTX(x , y+1, z+1);
1704 AddHexAsTets(ind, 1);
1716 for (y = 0; y < ny; y++)
1717 for (x = 0; x < nx; x++)
1719 ind[0] = VTX(x , y , 0);
1720 ind[1] = VTX(x , y+1, 0);
1721 ind[2] = VTX(x+1, y+1, 0);
1722 ind[3] = VTX(x+1, y , 0);
1725 AddBdrQuadAsTriangles(ind, 1);
1733 for (y = 0; y < ny; y++)
1734 for (x = 0; x < nx; x++)
1736 ind[0] = VTX(x , y , nz);
1737 ind[1] = VTX(x+1, y , nz);
1738 ind[2] = VTX(x+1, y+1, nz);
1739 ind[3] = VTX(x , y+1, nz);
1742 AddBdrQuadAsTriangles(ind, 6);
1750 for (z = 0; z < nz; z++)
1751 for (y = 0; y < ny; y++)
1753 ind[0] = VTX(0 , y , z );
1754 ind[1] = VTX(0 , y , z+1);
1755 ind[2] = VTX(0 , y+1, z+1);
1756 ind[3] = VTX(0 , y+1, z );
1759 AddBdrQuadAsTriangles(ind, 5);
1767 for (z = 0; z < nz; z++)
1768 for (y = 0; y < ny; y++)
1770 ind[0] = VTX(nx, y , z );
1771 ind[1] = VTX(nx, y+1, z );
1772 ind[2] = VTX(nx, y+1, z+1);
1773 ind[3] = VTX(nx, y , z+1);
1776 AddBdrQuadAsTriangles(ind, 3);
1784 for (x = 0; x < nx; x++)
1785 for (z = 0; z < nz; z++)
1787 ind[0] = VTX(x , 0, z );
1788 ind[1] = VTX(x+1, 0, z );
1789 ind[2] = VTX(x+1, 0, z+1);
1790 ind[3] = VTX(x , 0, z+1);
1793 AddBdrQuadAsTriangles(ind, 2);
1801 for (x = 0; x < nx; x++)
1802 for (z = 0; z < nz; z++)
1804 ind[0] = VTX(x , ny, z );
1805 ind[1] = VTX(x , ny, z+1);
1806 ind[2] = VTX(x+1, ny, z+1);
1807 ind[3] = VTX(x+1, ny, z );
1810 AddBdrQuadAsTriangles(ind, 4);
1819 ofstream test_stream(
"debug.mesh");
1821 test_stream.close();
1825 bool fix_orientation =
true;
1829 FinalizeTetMesh(generate_edges, refine, fix_orientation);
1833 FinalizeHexMesh(generate_edges, refine, fix_orientation);
1838 double sx,
double sy)
1851 NumOfVertices = (nx+1) * (ny+1);
1852 NumOfElements = nx * ny;
1853 NumOfBdrElements = 2 * nx + 2 * ny;
1854 vertices.SetSize(NumOfVertices);
1855 elements.SetSize(NumOfElements);
1856 boundary.SetSize(NumOfBdrElements);
1862 for (j = 0; j < ny+1; j++)
1864 cy = ((double) j / ny) * sy;
1865 for (i = 0; i < nx+1; i++)
1867 cx = ((double) i / nx) * sx;
1868 vertices[k](0) = cx;
1869 vertices[k](1) = cy;
1876 for (j = 0; j < ny; j++)
1878 for (i = 0; i < nx; i++)
1880 ind[0] = i + j*(nx+1);
1881 ind[1] = i + 1 +j*(nx+1);
1882 ind[2] = i + 1 + (j+1)*(nx+1);
1883 ind[3] = i + (j+1)*(nx+1);
1891 for (i = 0; i < nx; i++)
1893 boundary[i] =
new Segment(i, i+1, 1);
1894 boundary[nx+i] =
new Segment(m+i+1, m+i, 3);
1897 for (j = 0; j < ny; j++)
1899 boundary[2*nx+j] =
new Segment((j+1)*m, j*m, 4);
1900 boundary[2*nx+ny+j] =
new Segment(j*m+nx, (j+1)*m+nx, 2);
1908 NumOfVertices = (nx+1) * (ny+1);
1909 NumOfElements = 2 * nx * ny;
1910 NumOfBdrElements = 2 * nx + 2 * ny;
1911 vertices.SetSize(NumOfVertices);
1912 elements.SetSize(NumOfElements);
1913 boundary.SetSize(NumOfBdrElements);
1919 for (j = 0; j < ny+1; j++)
1921 cy = ((double) j / ny) * sy;
1922 for (i = 0; i < nx+1; i++)
1924 cx = ((double) i / nx) * sx;
1925 vertices[k](0) = cx;
1926 vertices[k](1) = cy;
1933 for (j = 0; j < ny; j++)
1935 for (i = 0; i < nx; i++)
1937 ind[0] = i + j*(nx+1);
1938 ind[1] = i + 1 + (j+1)*(nx+1);
1939 ind[2] = i + (j+1)*(nx+1);
1942 ind[1] = i + 1 + j*(nx+1);
1943 ind[2] = i + 1 + (j+1)*(nx+1);
1951 for (i = 0; i < nx; i++)
1953 boundary[i] =
new Segment(i, i+1, 1);
1954 boundary[nx+i] =
new Segment(m+i+1, m+i, 3);
1957 for (j = 0; j < ny; j++)
1959 boundary[2*nx+j] =
new Segment((j+1)*m, j*m, 4);
1960 boundary[2*nx+ny+j] =
new Segment(j*m+nx, (j+1)*m+nx, 2);
1963 MarkTriMeshForRefinement();
1966 CheckElementOrientation();
1968 if (generate_edges == 1)
1970 el_to_edge =
new Table;
1971 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
1973 CheckBdrElementOrientation();
1982 attributes.Append(1);
1983 bdr_attributes.Append(1); bdr_attributes.Append(2);
1984 bdr_attributes.Append(3); bdr_attributes.Append(4);
1999 NumOfVertices = n + 1;
2001 NumOfBdrElements = 2;
2002 vertices.SetSize(NumOfVertices);
2003 elements.SetSize(NumOfElements);
2004 boundary.SetSize(NumOfBdrElements);
2007 for (j = 0; j < n+1; j++)
2009 vertices[j](0) = ((
double) j / n) * sx;
2013 for (j = 0; j < n; j++)
2015 elements[j] =
new Segment(j, j+1, 1);
2020 boundary[0] =
new Point(ind, 1);
2022 boundary[1] =
new Point(ind, 2);
2029 attributes.Append(1);
2030 bdr_attributes.Append(1); bdr_attributes.Append(2);
2046 MFEM_VERIFY(mesh.
State == NORMAL,
"source mesh is not in a NORMAL state");
2051 elements.SetSize(NumOfElements);
2052 for (
int i = 0; i < NumOfElements; i++)
2054 elements[i] = mesh.
elements[i]->Duplicate(
this);
2058 MFEM_ASSERT(mesh.
vertices.Size() == NumOfVertices,
"internal MFEM error!");
2062 boundary.SetSize(NumOfBdrElements);
2063 for (
int i = 0; i < NumOfBdrElements; i++)
2065 boundary[i] = mesh.
boundary[i]->Duplicate(
this);
2084 faces.SetSize(mesh.
faces.Size());
2085 for (
int i = 0; i < faces.Size(); i++)
2088 faces[i] = (face) ? face->
Duplicate(
this) : NULL;
2105 nc_coarse_level = NULL;
2113 "copying NURBS meshes is not implemented");
2117 MFEM_VERIFY(mesh.
ncmesh == NULL,
2118 "copying non-conforming meshes is not implemented");
2123 if (mesh.
Nodes && copy_nodes)
2133 Nodes->MakeOwner(fec_copy);
2134 *Nodes = *mesh.
Nodes;
2145 bool fix_orientation)
2149 Load(input, generate_edges, refine, fix_orientation);
2162 #ifdef MFEM_USE_MEMALLOC
2163 return TetMemory.Alloc();
2178 el = NewElement(geom);
2181 for (
int i = 0; i < nv; i++)
2194 for (
int j = 0; j < nv; j++)
2207 el = ReadElementWithoutAttr(input);
2216 PrintElementWithoutAttr(el, out);
2222 for (
int i = 0; i < NumOfElements; i++)
2224 switch (elements[i]->GetType())
2229 meshgen |= 1;
break;
2239 static const int vtk_quadratic_tet[10] =
2240 { 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 };
2243 static const int vtk_quadratic_hex[27] =
2245 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
2246 24, 22, 21, 23, 20, 25, 26
2254 if (is.peek() != comment_char)
2258 is.ignore(numeric_limits<streamsize>::max(),
'\n');
2262 void Mesh::Load(std::istream &input,
int generate_edges,
int refine,
2263 bool fix_orientation)
2265 int i, j, ints[32], n, attr, curved = 0, read_gf = 1;
2266 const int buflen = 1024;
2271 MFEM_ABORT(
"Input stream is not open");
2274 if (NumOfVertices != -1)
2277 for (i = 0; i < NumOfElements; i++)
2279 FreeElement(elements[i]);
2281 elements.DeleteAll();
2285 vertices.DeleteAll();
2289 for (i = 0; i < NumOfBdrElements; i++)
2291 FreeElement(boundary[i]);
2293 boundary.DeleteAll();
2294 NumOfBdrElements = 0;
2297 for (i = 0; i < faces.Size(); i++)
2299 FreeElement(faces[i]);
2304 faces_info.DeleteAll();
2308 be_to_edge.DeleteAll();
2309 be_to_face.DeleteAll();
2318 if (own_nodes) {
delete Nodes; }
2326 getline(input, mesh_type);
2328 bool mfem_v10 = (mesh_type ==
"MFEM mesh v1.0");
2329 bool mfem_v11 = (mesh_type ==
"MFEM mesh v1.1");
2331 if (mfem_v10 || mfem_v11)
2340 MFEM_VERIFY(ident ==
"dimension",
"invalid mesh file");
2346 MFEM_VERIFY(ident ==
"elements",
"invalid mesh file");
2347 input >> NumOfElements;
2348 elements.SetSize(NumOfElements);
2349 for (j = 0; j < NumOfElements; j++)
2351 elements[j] = ReadElement(input);
2357 MFEM_VERIFY(ident ==
"boundary",
"invalid mesh file");
2358 input >> NumOfBdrElements;
2359 boundary.SetSize(NumOfBdrElements);
2360 for (j = 0; j < NumOfBdrElements; j++)
2362 boundary[j] = ReadElement(input);
2368 if (ident ==
"vertex_parents" && mfem_v11)
2370 ncmesh =
new NCMesh(
this, &input);
2376 if (ident ==
"coarse_elements")
2378 ncmesh->LoadCoarseElements(input);
2385 MFEM_VERIFY(ident ==
"vertices",
"invalid mesh file");
2386 input >> NumOfVertices;
2387 vertices.SetSize(NumOfVertices);
2389 input >> ws >> ident;
2390 if (ident !=
"nodes")
2393 spaceDim = atoi(ident.c_str());
2394 for (j = 0; j < NumOfVertices; j++)
2396 for (i = 0; i < spaceDim; i++)
2398 input >> vertices[j](i);
2403 if (ncmesh) { ncmesh->SetVertexPositions(vertices); }
2412 else if (mesh_type ==
"linemesh")
2418 input >> NumOfVertices;
2419 vertices.SetSize(NumOfVertices);
2421 for (j = 0; j < NumOfVertices; j++)
2423 input >> vertices[j](0);
2426 input >> NumOfElements;
2427 elements.SetSize(NumOfElements);
2429 for (j = 0; j < NumOfElements; j++)
2431 input >> a >> p1 >> p2;
2432 elements[j] =
new Segment(p1-1, p2-1, a);
2436 input >> NumOfBdrElements;
2437 boundary.SetSize(NumOfBdrElements);
2438 for (j = 0; j < NumOfBdrElements; j++)
2440 input >> a >> ind[0];
2442 boundary[j] =
new Point(ind,a);
2445 else if (mesh_type ==
"areamesh2" || mesh_type ==
"curved_areamesh2")
2450 if (mesh_type ==
"curved_areamesh2")
2456 input >> NumOfBdrElements;
2457 boundary.SetSize(NumOfBdrElements);
2458 for (i = 0; i < NumOfBdrElements; i++)
2461 >> ints[0] >> ints[1];
2462 ints[0]--; ints[1]--;
2463 boundary[i] =
new Segment(ints, attr);
2467 input >> NumOfElements;
2468 elements.SetSize(NumOfElements);
2469 for (i = 0; i < NumOfElements; i++)
2472 for (j = 0; j < n; j++)
2480 elements[i] =
new Segment(ints, attr);
2483 elements[i] =
new Triangle(ints, attr);
2494 input >> NumOfVertices;
2495 vertices.SetSize(NumOfVertices);
2496 for (i = 0; i < NumOfVertices; i++)
2497 for (j = 0; j < Dim; j++)
2499 input >> vertices[i](j);
2504 input >> NumOfVertices;
2505 vertices.SetSize(NumOfVertices);
2509 else if (mesh_type ==
"NETGEN" || mesh_type ==
"NETGEN_Neutral_Format")
2515 input >> NumOfVertices;
2517 vertices.SetSize(NumOfVertices);
2518 for (i = 0; i < NumOfVertices; i++)
2519 for (j = 0; j < Dim; j++)
2521 input >> vertices[i](j);
2525 input >> NumOfElements;
2526 elements.SetSize(NumOfElements);
2527 for (i = 0; i < NumOfElements; i++)
2530 for (j = 0; j < 4; j++)
2535 #ifdef MFEM_USE_MEMALLOC
2537 tet = TetMemory.Alloc();
2547 input >> NumOfBdrElements;
2548 boundary.SetSize(NumOfBdrElements);
2549 for (i = 0; i < NumOfBdrElements; i++)
2552 for (j = 0; j < 3; j++)
2557 boundary[i] =
new Triangle(ints, attr);
2560 else if (mesh_type ==
"TrueGrid")
2572 input >> vari >> NumOfVertices >> vari >> vari >> NumOfElements;
2573 input.getline(buf, buflen);
2574 input.getline(buf, buflen);
2576 input.getline(buf, buflen);
2577 input.getline(buf, buflen);
2578 input.getline(buf, buflen);
2581 vertices.SetSize(NumOfVertices);
2582 for (i = 0; i < NumOfVertices; i++)
2584 input >> vari >> varf >> vertices[i](0) >> vertices[i](1);
2585 input.getline(buf, buflen);
2589 elements.SetSize(NumOfElements);
2590 for (i = 0; i < NumOfElements; i++)
2592 input >> vari >> attr;
2593 for (j = 0; j < 4; j++)
2598 input.getline(buf, buflen);
2599 input.getline(buf, buflen);
2607 input >> vari >> NumOfVertices >> NumOfElements;
2608 input.getline(buf, buflen);
2609 input.getline(buf, buflen);
2610 input >> vari >> vari >> NumOfBdrElements;
2611 input.getline(buf, buflen);
2612 input.getline(buf, buflen);
2613 input.getline(buf, buflen);
2615 vertices.SetSize(NumOfVertices);
2616 for (i = 0; i < NumOfVertices; i++)
2618 input >> vari >> varf >> vertices[i](0) >> vertices[i](1)
2620 input.getline(buf, buflen);
2623 elements.SetSize(NumOfElements);
2624 for (i = 0; i < NumOfElements; i++)
2626 input >> vari >> attr;
2627 for (j = 0; j < 8; j++)
2632 input.getline(buf, buflen);
2636 boundary.SetSize(NumOfBdrElements);
2637 for (i = 0; i < NumOfBdrElements; i++)
2640 for (j = 0; j < 4; j++)
2645 input.getline(buf, buflen);
2650 else if (mesh_type ==
"# vtk DataFile Version 3.0" ||
2651 mesh_type ==
"# vtk DataFile Version 2.0")
2656 getline(input, buff);
2657 getline(input, buff);
2658 if (buff !=
"ASCII")
2660 mfem_error(
"Mesh::Load : VTK mesh is not in ASCII format!");
2663 getline(input, buff);
2664 if (buff !=
"DATASET UNSTRUCTURED_GRID")
2666 mfem_error(
"Mesh::Load : VTK mesh is not UNSTRUCTURED_GRID!");
2677 mfem_error(
"Mesh::Load : VTK mesh does not have POINTS data!");
2680 while (buff !=
"POINTS");
2686 getline(input, buff);
2687 for (i = 0; i < points.
Size(); i++)
2694 NumOfElements = n = 0;
2696 input >> ws >> buff;
2697 if (buff ==
"CELLS")
2699 input >> NumOfElements >> n >> ws;
2701 for (i = 0; i < n; i++)
2703 input >> cells_data[i];
2710 input >> ws >> buff;
2711 if (buff ==
"CELL_TYPES")
2713 input >> NumOfElements;
2714 elements.
SetSize(NumOfElements);
2715 for (j = i = 0; i < NumOfElements; i++)
2723 elements[i] =
new Triangle(&cells_data[j+1]);
2731 #ifdef MFEM_USE_MEMALLOC
2732 elements[i] = TetMemory.Alloc();
2733 elements[i]->SetVertices(&cells_data[j+1]);
2740 elements[i] =
new Hexahedron(&cells_data[j+1]);
2746 elements[i] =
new Triangle(&cells_data[j+1]);
2756 #ifdef MFEM_USE_MEMALLOC
2757 elements[i] = TetMemory.Alloc();
2758 elements[i]->SetVertices(&cells_data[j+1]);
2766 elements[i] =
new Hexahedron(&cells_data[j+1]);
2769 cerr <<
"Mesh::Load : VTK mesh : cell type " << ct
2770 <<
" is not supported!" << endl;
2774 j += cells_data[j] + 1;
2779 streampos sp = input.tellg();
2780 input >> ws >> buff;
2781 if (buff ==
"CELL_DATA")
2784 getline(input, buff);
2786 if (!strncmp(buff.c_str(),
"SCALARS material", 16))
2788 getline(input, buff);
2789 for (i = 0; i < NumOfElements; i++)
2792 elements[i]->SetAttribute(attr);
2809 vertices.SetSize(np);
2810 for (i = 0; i < np; i++)
2812 vertices[i](0) = points(3*i+0);
2813 vertices[i](1) = points(3*i+1);
2814 vertices[i](2) = points(3*i+2);
2819 NumOfBdrElements = 0;
2821 else if (order == 2)
2828 for (n = i = 0; i < NumOfElements; i++)
2830 int *v = elements[i]->GetVertices();
2831 int nv = elements[i]->GetNVertices();
2832 for (j = 0; j < nv; j++)
2833 if (pts_dof[v[j]] == -1)
2835 pts_dof[v[j]] = n++;
2839 for (n = i = 0; i < np; i++)
2840 if (pts_dof[i] != -1)
2845 for (i = 0; i < NumOfElements; i++)
2847 int *v = elements[i]->GetVertices();
2848 int nv = elements[i]->GetNVertices();
2849 for (j = 0; j < nv; j++)
2851 v[j] = pts_dof[v[j]];
2857 for (i = 0; i < np; i++)
2859 if ((j = pts_dof[i]) != -1)
2861 vertices[j](0) = points(3*i+0);
2862 vertices[j](1) = points(3*i+1);
2863 vertices[j](2) = points(3*i+2);
2868 NumOfBdrElements = 0;
2876 GetElementToFaceTable();
2885 el_to_edge =
new Table;
2886 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
2896 Nodes->MakeOwner(fec);
2901 for (n = i = 0; i < NumOfElements; i++)
2904 const int *vtk_mfem;
2905 switch (elements[i]->GetGeometryType())
2909 vtk_mfem = vtk_quadratic_hex;
break;
2911 vtk_mfem = vtk_quadratic_tet;
break;
2914 vtk_mfem = vtk_quadratic_hex;
break;
2917 for (n++, j = 0; j < dofs.
Size(); j++, n++)
2919 if (pts_dof[cells_data[n]] == -1)
2921 pts_dof[cells_data[n]] = dofs[vtk_mfem[j]];
2925 if (pts_dof[cells_data[n]] != dofs[vtk_mfem[j]])
2927 "inconsistent quadratic mesh!");
2933 for (i = 0; i < np; i++)
2936 if ((dofs[0] = pts_dof[i]) != -1)
2939 for (j = 0; j < dofs.
Size(); j++)
2941 (*Nodes)(dofs[j]) = points(3*i+j);
2949 else if (mesh_type ==
"MFEM NURBS mesh v1.0")
2953 Dim = NURBSext->Dimension();
2954 NumOfVertices = NURBSext->GetNV();
2955 NumOfElements = NURBSext->GetNE();
2956 NumOfBdrElements = NURBSext->GetNBE();
2958 NURBSext->GetElementTopo(elements);
2959 NURBSext->GetBdrElementTopo(boundary);
2961 vertices.SetSize(NumOfVertices);
2963 if (NURBSext->HavePatches())
2969 Nodes->MakeOwner(fec);
2970 NURBSext->SetCoordsFromPatches(*Nodes);
2973 int vd = Nodes->VectorDim();
2974 for (i = 0; i < vd; i++)
2977 Nodes->GetNodalValues(vert_val, i+1);
2978 for (j = 0; j < NumOfVertices; j++)
2980 vertices[j](i) = vert_val(j);
2989 else if (mesh_type ==
"MFEM INLINE mesh v1.0")
3017 MFEM_VERIFY(input.get() ==
'=',
3018 "Inline mesh expected '=' after keyword " << name);
3025 else if (name ==
"ny")
3029 else if (name ==
"nz")
3033 else if (name ==
"sx")
3037 else if (name ==
"sy")
3041 else if (name ==
"sz")
3045 else if (name ==
"type")
3049 if (eltype ==
"segment")
3053 else if (eltype ==
"quad")
3057 else if (eltype ==
"tri")
3061 else if (eltype ==
"hex")
3065 else if (eltype ==
"tet")
3071 MFEM_ABORT(
"unrecognized element type (read '" << eltype
3072 <<
"') in inline mesh format. "
3073 "Allowed: segment, tri, tet, quad, hex");
3078 MFEM_ABORT(
"unrecognized keyword (" << name
3079 <<
") in inline mesh format. "
3080 "Allowed: nx, ny, nz, type, sx, sy, sz");
3085 if (input.peek() ==
';')
3100 MFEM_VERIFY(nx > 0 && sx > 0.0,
3101 "invalid 1D inline mesh format, all values must be "
3103 <<
" nx = " << nx <<
"\n"
3104 <<
" sx = " << sx <<
"\n");
3109 MFEM_VERIFY(nx > 0 && ny > 0 && sx > 0.0 && sy > 0.0,
3110 "invalid 2D inline mesh format, all values must be "
3112 <<
" nx = " << nx <<
"\n"
3113 <<
" ny = " << ny <<
"\n"
3114 <<
" sx = " << sx <<
"\n"
3115 <<
" sy = " << sy <<
"\n");
3116 Make2D(nx, ny, type, generate_edges, sx, sy);
3120 MFEM_VERIFY(nx > 0 && ny > 0 && nz > 0 &&
3121 sx > 0.0 && sy > 0.0 && sz > 0.0,
3122 "invalid 3D inline mesh format, all values must be "
3124 <<
" nx = " << nx <<
"\n"
3125 <<
" ny = " << ny <<
"\n"
3126 <<
" nz = " << nz <<
"\n"
3127 <<
" sx = " << sx <<
"\n"
3128 <<
" sy = " << sy <<
"\n"
3129 <<
" sz = " << sz <<
"\n");
3130 Make3D(nx, ny, nz, type, generate_edges, sx, sy, sz);
3134 mfem_error(
"Mesh::Load : For inline mesh, must specify an "
3135 "element type = [segment, tri, quad, tet, hex]");
3141 MFEM_ABORT(
"Unknown input mesh format");
3165 if (NumOfBdrElements == 0 && Dim > 2)
3168 GetElementToFaceTable();
3170 GenerateBoundaryElements();
3176 CheckElementOrientation(fix_orientation);
3180 MarkForRefinement();
3192 GetElementToFaceTable();
3195 if ( !(curved && (meshgen & 1)) )
3197 CheckBdrElementOrientation();
3206 if (Dim > 1 && generate_edges == 1)
3209 if (!el_to_edge) { el_to_edge =
new Table; }
3210 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
3214 if (NumOfBdrElements == 0)
3216 GenerateBoundaryElements();
3219 if ( !(curved && (meshgen & 1)) )
3221 CheckBdrElementOrientation();
3224 c_el_to_edge = NULL;
3234 ncmesh->OnMeshUpdated(
this);
3237 GenerateNCFaceInfo();
3249 spaceDim = Nodes->VectorDim();
3251 for (i = 0; i < spaceDim; i++)
3254 Nodes->GetNodalValues(vert_val, i+1);
3255 for (j = 0; j < NumOfVertices; j++)
3257 vertices[j](i) = vert_val(j);
3266 Table *old_elem_vert = NULL;
3267 if (fix_orientation || refine)
3269 PrepareNodeReorder(&old_v_to_v, &old_elem_vert);
3274 CheckElementOrientation(fix_orientation);
3277 MarkForRefinement();
3280 if (fix_orientation || refine)
3282 DoNodeReorder(old_v_to_v, old_elem_vert);
3283 delete old_elem_vert;
3289 if (ncmesh) { ncmesh->spaceDim = spaceDim; }
3294 int i, j, ie, ib, iv, *v, nv;
3304 if (mesh_array[0]->NURBSext)
3309 NumOfVertices = NURBSext->GetNV();
3310 NumOfElements = NURBSext->GetNE();
3312 NURBSext->GetElementTopo(elements);
3325 NumOfBdrElements = 0;
3326 for (i = 0; i < num_pieces; i++)
3328 NumOfBdrElements += mesh_array[i]->
GetNBE();
3330 boundary.SetSize(NumOfBdrElements);
3331 vertices.SetSize(NumOfVertices);
3333 for (i = 0; i < num_pieces; i++)
3339 for (j = 0; j < m->
GetNE(); j++)
3341 elements[lelem_elem[j]]->SetAttribute(m->
GetAttribute(j));
3344 for (j = 0; j < m->
GetNBE(); j++)
3349 for (
int k = 0; k < nv; k++)
3351 v[k] = lvert_vert[v[k]];
3353 boundary[ib++] = el;
3356 for (j = 0; j < m->
GetNV(); j++)
3358 vertices[lvert_vert[j]].SetCoords(m->
GetVertex(j));
3365 NumOfBdrElements = 0;
3367 for (i = 0; i < num_pieces; i++)
3370 NumOfElements += m->
GetNE();
3371 NumOfBdrElements += m->
GetNBE();
3372 NumOfVertices += m->
GetNV();
3374 elements.SetSize(NumOfElements);
3375 boundary.SetSize(NumOfBdrElements);
3376 vertices.SetSize(NumOfVertices);
3378 for (i = 0; i < num_pieces; i++)
3382 for (j = 0; j < m->
GetNE(); j++)
3387 for (
int k = 0; k < nv; k++)
3391 elements[ie++] = el;
3394 for (j = 0; j < m->
GetNBE(); j++)
3399 for (
int k = 0; k < nv; k++)
3403 boundary[ib++] = el;
3406 for (j = 0; j < m->
GetNV(); j++)
3408 vertices[iv++].SetCoords(m->
GetVertex(j));
3415 for (i = 0; i < num_pieces; i++)
3423 GetElementToFaceTable();
3434 el_to_edge =
new Table;
3435 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
3454 for (i = 0; i < num_pieces; i++)
3456 gf_array[i] = mesh_array[i]->
GetNodes();
3463 CheckElementOrientation(
false);
3464 CheckBdrElementOrientation(
false);
3470 if (NURBSext == NULL)
3472 mfem_error(
"Mesh::KnotInsert : Not a NURBS mesh!");
3475 if (kv.
Size() != NURBSext->GetNKV())
3477 mfem_error(
"Mesh::KnotInsert : KnotVector array size mismatch!");
3480 NURBSext->ConvertToPatches(*Nodes);
3482 NURBSext->KnotInsert(kv);
3490 NURBSext->ConvertToPatches(*Nodes);
3492 NURBSext->UniformRefinement();
3499 if (NURBSext == NULL)
3501 mfem_error(
"Mesh::DegreeElevate : Not a NURBS mesh!");
3504 NURBSext->ConvertToPatches(*Nodes);
3506 NURBSext->DegreeElevate(t);
3521 NURBSext->SetKnotsFromPatches();
3523 Dim = NURBSext->Dimension();
3526 if (NumOfElements != NURBSext->GetNE())
3528 for (
int i = 0; i < elements.Size(); i++)
3530 FreeElement(elements[i]);
3532 NumOfElements = NURBSext->GetNE();
3533 NURBSext->GetElementTopo(elements);
3536 if (NumOfBdrElements != NURBSext->GetNBE())
3538 for (
int i = 0; i < boundary.Size(); i++)
3540 FreeElement(boundary[i]);
3542 NumOfBdrElements = NURBSext->GetNBE();
3543 NURBSext->GetBdrElementTopo(boundary);
3546 Nodes->FESpace()->Update();
3548 NURBSext->SetCoordsFromPatches(*Nodes);
3550 if (NumOfVertices != NURBSext->GetNV())
3552 NumOfVertices = NURBSext->GetNV();
3553 vertices.SetSize(NumOfVertices);
3554 int vd = Nodes->VectorDim();
3555 for (
int i = 0; i < vd; i++)
3558 Nodes->GetNodalValues(vert_val, i+1);
3559 for (
int j = 0; j < NumOfVertices; j++)
3561 vertices[j](i) = vert_val(j);
3568 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
3577 GetElementToFaceTable();
3601 input >> NumOfElements;
3602 elements.SetSize(NumOfElements);
3603 for (j = 0; j < NumOfElements; j++)
3605 elements[j] = ReadElement(input);
3611 input >> NumOfBdrElements;
3612 boundary.SetSize(NumOfBdrElements);
3613 for (j = 0; j < NumOfBdrElements; j++)
3615 boundary[j] = ReadElement(input);
3621 input >> NumOfEdges;
3622 edge_vertex =
new Table(NumOfEdges, 2);
3623 edge_to_knot.
SetSize(NumOfEdges);
3624 for (j = 0; j < NumOfEdges; j++)
3626 int *v = edge_vertex->GetRow(j);
3627 input >> edge_to_knot[j] >> v[0] >> v[1];
3630 edge_to_knot[j] = -1 - edge_to_knot[j];
3637 input >> NumOfVertices;
3638 vertices.SetSize(0);
3645 GetElementToFaceTable();
3647 if (NumOfBdrElements == 0)
3649 GenerateBoundaryElements();
3651 CheckBdrElementOrientation();
3661 el_to_edge =
new Table;
3662 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
3666 if (NumOfBdrElements == 0)
3668 GenerateBoundaryElements();
3670 CheckBdrElementOrientation();
3686 for (
int d = 0; d < v.
Size(); d++)
3694 for (d = 0; d < p.
Size(); d++)
3698 for ( ; d < v.
Size(); d++)
3707 if (Nodes == NULL || Nodes->FESpace() != nodes.
FESpace())
3722 SetNodalGridFunction(nodes,
true);
3728 NewNodes(*nodes, make_owner);
3733 return ((Nodes) ? Nodes->FESpace() : NULL);
3738 space_dim = (space_dim == -1) ? spaceDim : space_dim;
3751 SetNodalFESpace(nfes);
3752 Nodes->MakeOwner(nfec);
3759 case 1:
return GetNV();
3760 case 2:
return GetNEdges();
3761 case 3:
return GetNFaces();
3766 #if (!defined(MFEM_USE_MPI) || defined(MFEM_DEBUG))
3767 static const char *fixed_or_not[] = {
"fixed",
"NOT FIXED" };
3772 int i, j, k, wo = 0, fo = 0, *vi = 0;
3775 if (Dim == 2 && spaceDim == 2)
3779 for (i = 0; i < NumOfElements; i++)
3783 vi = elements[i]->GetVertices();
3784 for (j = 0; j < 3; j++)
3786 v[j] = vertices[vi[j]]();
3788 for (j = 0; j < 2; j++)
3789 for (k = 0; k < 2; k++)
3791 J(j, k) = v[j+1][k] - v[0][k];
3797 GetElementJacobian(i, J);
3803 switch (GetElementType(i))
3823 for (i = 0; i < NumOfElements; i++)
3825 vi = elements[i]->GetVertices();
3826 switch (GetElementType(i))
3831 for (j = 0; j < 4; j++)
3833 v[j] = vertices[vi[j]]();
3835 for (j = 0; j < 3; j++)
3836 for (k = 0; k < 3; k++)
3838 J(j, k) = v[j+1][k] - v[0][k];
3844 GetElementJacobian(i, J);
3859 GetElementJacobian(i, J);
3872 #if (!defined(MFEM_USE_MPI) || defined(MFEM_DEBUG))
3874 cout <<
"Elements with wrong orientation: " << wo <<
" / "
3875 << NumOfElements <<
" (" << fixed_or_not[(wo == fo) ? 0 : 1]
3884 if (test[0] == base[0])
3885 if (test[1] == base[1])
3893 else if (test[0] == base[1])
3894 if (test[1] == base[0])
3903 if (test[1] == base[0])
3913 const int *aor = tri_orientations[orient];
3914 for (
int j = 0; j < 3; j++)
3915 if (test[aor[j]] != base[j])
3928 for (i = 0; i < 4; i++)
3929 if (test[i] == base[0])
3936 if (test[(i+1)%4] == base[1])
3944 const int *aor = quad_orientations[orient];
3945 for (
int j = 0; j < 4; j++)
3946 if (test[aor[j]] != base[j])
3948 cerr <<
"Mesh::GetQuadOrientation(...)" << endl;
3949 cerr <<
" base = [";
3950 for (
int k = 0; k < 4; k++)
3952 cerr <<
" " << base[k];
3954 cerr <<
" ]\n test = [";
3955 for (
int k = 0; k < 4; k++)
3957 cerr <<
" " << test[k];
3959 cerr <<
" ]" << endl;
3964 if (test[(i+1)%4] == base[1])
3978 for (i = 0; i < NumOfBdrElements; i++)
3980 if (faces_info[be_to_edge[i]].Elem2No < 0)
3982 int *bv = boundary[i]->GetVertices();
3983 int *fv = faces[be_to_edge[i]]->GetVertices();
3988 mfem::Swap<int>(bv[0], bv[1]);
4001 for (i = 0; i < NumOfBdrElements; i++)
4003 if (faces_info[be_to_face[i]].Elem2No < 0)
4006 bv = boundary[i]->GetVertices();
4007 el = faces_info[be_to_face[i]].Elem1No;
4008 ev = elements[el]->GetVertices();
4009 switch (GetElementType(el))
4013 int *fv = faces[be_to_face[i]]->GetVertices();
4016 orientation = GetTriOrientation(fv, bv);
4017 if (orientation % 2)
4023 mfem::Swap<int>(bv[0], bv[1]);
4032 int lf = faces_info[be_to_face[i]].Elem1Inf/64;
4033 for (
int j = 0; j < 4; j++)
4035 v[j] = ev[hex_faces[lf][j]];
4037 if (GetQuadOrientation(v, bv) % 2)
4041 mfem::Swap<int>(bv[0], bv[2]);
4055 cout <<
"Boundary elements with wrong orientation: " << wo <<
" / "
4056 << NumOfBdrElements <<
" (" << fixed_or_not[fix_it ? 0 : 1]
4066 el_to_edge->GetRow(i, edges);
4070 mfem_error(
"Mesh::GetElementEdges(...) element to edge table "
4071 "is not generated.");
4074 const int *v = elements[i]->GetVertices();
4075 const int ne = elements[i]->GetNEdges();
4077 for (
int j = 0; j < ne; j++)
4079 const int *e = elements[i]->GetEdgeVertices(j);
4080 cor[j] = (v[e[0]] < v[e[1]]) ? (1) : (-1);
4090 edges[0] = be_to_edge[i];
4091 const int *v = boundary[i]->GetVertices();
4092 cor[0] = (v[0] < v[1]) ? (1) : (-1);
4098 bel_to_edge->GetRow(i, edges);
4105 const int *v = boundary[i]->GetVertices();
4106 const int ne = boundary[i]->GetNEdges();
4108 for (
int j = 0; j < ne; j++)
4110 const int *e = boundary[i]->GetEdgeVertices(j);
4111 cor[j] = (v[e[0]] < v[e[1]]) ? (1) : (-1);
4123 const int *v = faces[i]->GetVertices();
4124 o[0] = (v[0] < v[1]) ? (1) : (-1);
4132 MFEM_ASSERT(State != TWO_LEVEL_COARSE,
"internal MFEM error!");
4136 face_edge->GetRow(i, edges);
4138 const int *v = faces[i]->GetVertices();
4139 const int ne = faces[i]->GetNEdges();
4141 for (
int j = 0; j < ne; j++)
4143 const int *e = faces[i]->GetEdgeVertices(j);
4144 o[j] = (v[e[0]] < v[e[1]]) ? (1) : (-1);
4150 MFEM_ASSERT(State != TWO_LEVEL_COARSE,
"internal MFEM error!");
4154 GetEdgeVertexTable();
4155 edge_vertex->GetRow(i, vert);
4171 if (faces.Size() != NumOfFaces)
4173 mfem_error(
"Mesh::GetFaceEdgeTable : faces were not generated!");
4177 DSTable v_to_v(NumOfVertices);
4178 GetVertexToVertexTable(v_to_v);
4180 face_edge =
new Table;
4181 GetElementArrayEdgeTable(faces, v_to_v, *face_edge);
4193 DSTable v_to_v(NumOfVertices);
4194 GetVertexToVertexTable(v_to_v);
4197 edge_vertex =
new Table(nedges, 2);
4198 for (
int i = 0; i < NumOfVertices; i++)
4203 edge_vertex->Push(j, i);
4204 edge_vertex->Push(j, it.Column());
4207 edge_vertex->Finalize();
4218 vert_elem->
MakeI(NumOfVertices);
4220 for (i = 0; i < NumOfElements; i++)
4222 nv = elements[i]->GetNVertices();
4223 v = elements[i]->GetVertices();
4224 for (j = 0; j < nv; j++)
4232 for (i = 0; i < NumOfElements; i++)
4234 nv = elements[i]->GetNVertices();
4235 v = elements[i]->GetVertices();
4236 for (j = 0; j < nv; j++)
4251 face_elem->
MakeI(faces_info.Size());
4253 for (
int i = 0; i < faces_info.Size(); i++)
4255 if (faces_info[i].Elem2No >= 0)
4267 for (
int i = 0; i < faces_info.Size(); i++)
4270 if (faces_info[i].Elem2No >= 0)
4288 el_to_face->GetRow(i, fcs);
4292 mfem_error(
"Mesh::GetElementFaces(...) : el_to_face not generated.");
4297 for (j = 0; j < n; j++)
4298 if (faces_info[fcs[j]].Elem1No == i)
4300 cor[j] = faces_info[fcs[j]].Elem1Inf % 64;
4303 else if (faces_info[fcs[j]].Elem2No == i)
4305 cor[j] = faces_info[fcs[j]].Elem2Inf % 64;
4309 mfem_error(
"Mesh::GetElementFaces(...) : 2");
4314 cor[j] = faces_info[fcs[j]].Elem2Inf % 64;
4330 bv = boundary[i]->GetVertices();
4331 fv = faces[be_to_face[i]]->GetVertices();
4335 switch (GetBdrElementType(i))
4338 *o = GetTriOrientation(fv, bv);
4341 *o = GetQuadOrientation(fv, bv);
4344 mfem_error(
"Mesh::GetBdrElementFace(...) 2");
4351 switch (GetElementType(0))
4365 mfem_error(
"Mesh::GetFaceBaseGeometry(...) #1");
4374 case 1:
return boundary[i]->GetVertices()[0];
4375 case 2:
return be_to_edge[i];
4376 case 3:
return be_to_face[i];
4377 default:
mfem_error(
"Mesh::GetBdrElementEdgeIndex: invalid dimension!");
4423 v = elements[i]->GetVertices();
4424 nv = elements[i]->GetNVertices();
4426 pointmat.
SetSize(spaceDim, nv);
4427 for (k = 0; k < spaceDim; k++)
4428 for (j = 0; j < nv; j++)
4430 pointmat(k, j) = vertices[v[j]](k);
4439 v = boundary[i]->GetVertices();
4440 nv = boundary[i]->GetNVertices();
4442 pointmat.
SetSize(spaceDim, nv);
4443 for (k = 0; k < spaceDim; k++)
4444 for (j = 0; j < nv; j++)
4446 pointmat(k, j) = vertices[v[j]](k);
4452 const double *vi = vertices[i]();
4453 const double *vj = vertices[j]();
4456 for (
int k = 0; k < spaceDim; k++)
4458 length += (vi[k]-vj[k])*(vi[k]-vj[k]);
4461 return sqrt(length);
4469 for (
int i = 0; i < elem_array.
Size(); i++)
4474 for (
int i = 0; i < elem_array.
Size(); i++)
4476 const int *v = elem_array[i]->GetVertices();
4477 const int ne = elem_array[i]->GetNEdges();
4478 for (
int j = 0; j < ne; j++)
4480 const int *e = elem_array[i]->GetEdgeVertices(j);
4491 for (
int i = 0; i < edge_vertex->Size(); i++)
4493 const int *v = edge_vertex->GetRow(i);
4494 v_to_v.
Push(v[0], v[1]);
4499 for (
int i = 0; i < NumOfElements; i++)
4501 const int *v = elements[i]->GetVertices();
4502 const int ne = elements[i]->GetNEdges();
4503 for (
int j = 0; j < ne; j++)
4505 const int *e = elements[i]->GetEdgeVertices(j);
4506 v_to_v.
Push(v[e[0]], v[e[1]]);
4514 int i, NumberOfEdges;
4516 DSTable v_to_v(NumOfVertices);
4517 GetVertexToVertexTable(v_to_v);
4522 GetElementArrayEdgeTable(elements, v_to_v, e_to_f);
4527 be_to_f.
SetSize(NumOfBdrElements);
4528 for (i = 0; i < NumOfBdrElements; i++)
4530 const int *v = boundary[i]->GetVertices();
4531 be_to_f[i] = v_to_v(v[0], v[1]);
4536 if (bel_to_edge == NULL)
4538 bel_to_edge =
new Table;
4540 GetElementArrayEdgeTable(boundary, v_to_v, *bel_to_edge);
4544 mfem_error(
"1D GetElementToEdgeTable is not yet implemented.");
4548 return NumberOfEdges;
4558 int num_faces = GetNumFaces();
4559 MFEM_ASSERT(faces_info.Size() == num_faces,
"faces were not generated!");
4564 for (
int i = 0; i < faces_info.Size(); i++)
4566 const FaceInfo &fi = faces_info[i];
4576 el_to_el =
new Table(NumOfElements, conn);
4583 if (el_to_face == NULL)
4592 if (el_to_edge == NULL)
4601 if (faces_info[gf].Elem1No == -1)
4604 faces_info[gf].Elem1No = el;
4605 faces_info[gf].Elem1Inf = 64 * lf;
4606 faces_info[gf].Elem2No = -1;
4607 faces_info[gf].Elem2Inf = -1;
4611 faces_info[gf].Elem2No = el;
4612 faces_info[gf].Elem2Inf = 64 * lf + 1;
4618 if (faces[gf] == NULL)
4620 faces[gf] =
new Segment(v0, v1);
4621 faces_info[gf].Elem1No = el;
4622 faces_info[gf].Elem1Inf = 64 * lf;
4623 faces_info[gf].Elem2No = -1;
4624 faces_info[gf].Elem2Inf = -1;
4628 int *v = faces[gf]->GetVertices();
4629 faces_info[gf].Elem2No = el;
4630 if ( v[1] == v0 && v[0] == v1 )
4632 faces_info[gf].Elem2Inf = 64 * lf + 1;
4634 else if ( v[0] == v0 && v[1] == v1 )
4636 faces_info[gf].Elem2Inf = 64 * lf;
4640 MFEM_ASSERT((v[1] == v0 && v[0] == v1)||
4641 (v[0] == v0 && v[1] == v1),
"");
4647 int v0,
int v1,
int v2)
4649 if (faces[gf] == NULL)
4651 faces[gf] =
new Triangle(v0, v1, v2);
4652 faces_info[gf].Elem1No = el;
4653 faces_info[gf].Elem1Inf = 64 * lf;
4654 faces_info[gf].Elem2No = -1;
4655 faces_info[gf].Elem2Inf = -1;
4659 int orientation, vv[3] = { v0, v1, v2 };
4660 orientation = GetTriOrientation(faces[gf]->GetVertices(), vv);
4661 MFEM_ASSERT(orientation % 2 != 0,
"");
4662 faces_info[gf].Elem2No = el;
4663 faces_info[gf].Elem2Inf = 64 * lf + orientation;
4668 int v0,
int v1,
int v2,
int v3)
4670 if (faces_info[gf].Elem1No < 0)
4673 faces_info[gf].Elem1No = el;
4674 faces_info[gf].Elem1Inf = 64 * lf;
4675 faces_info[gf].Elem2No = -1;
4676 faces_info[gf].Elem2Inf = -1;
4680 int vv[4] = { v0, v1, v2, v3 };
4681 int oo = GetQuadOrientation(faces[gf]->GetVertices(), vv);
4682 MFEM_ASSERT(oo % 2 != 0,
"");
4683 faces_info[gf].Elem2No = el;
4684 faces_info[gf].Elem2Inf = 64 * lf + oo;
4690 int i, nfaces = GetNumFaces();
4692 for (i = 0; i < faces.Size(); i++)
4694 FreeElement(faces[i]);
4698 faces.SetSize(nfaces);
4699 faces_info.SetSize(nfaces);
4700 for (i = 0; i < nfaces; i++)
4703 faces_info[i].Elem1No = -1;
4704 faces_info[i].NCFace = -1;
4706 for (i = 0; i < NumOfElements; i++)
4708 const int *v = elements[i]->GetVertices();
4712 AddPointFaceElement(0, v[0], i);
4713 AddPointFaceElement(1, v[1], i);
4717 ef = el_to_edge->GetRow(i);
4718 const int ne = elements[i]->GetNEdges();
4719 for (
int j = 0; j < ne; j++)
4721 const int *e = elements[i]->GetEdgeVertices(j);
4722 AddSegmentFaceElement(j, ef[j], i, v[e[0]], v[e[1]]);
4727 ef = el_to_face->GetRow(i);
4728 switch (GetElementType(i))
4732 for (
int j = 0; j < 4; j++)
4734 const int *fv = tet_faces[j];
4735 AddTriangleFaceElement(j, ef[j], i,
4736 v[fv[0]], v[fv[1]], v[fv[2]]);
4742 for (
int j = 0; j < 6; j++)
4744 const int *fv = hex_faces[j];
4745 AddQuadFaceElement(j, ef[j], i,
4746 v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
4751 MFEM_ABORT(
"Unexpected type of Element.");
4759 MFEM_VERIFY(ncmesh,
"missing NCMesh.");
4761 for (
int i = 0; i < faces_info.Size(); i++)
4763 faces_info[i].NCFace = -1;
4767 (Dim == 2) ? ncmesh->GetEdgeList() : ncmesh->GetFaceList();
4769 nc_faces_info.SetSize(0);
4770 nc_faces_info.Reserve(list.
masters.size() + list.
slaves.size());
4773 for (
unsigned i = 0; i < list.
masters.size(); i++)
4776 faces_info[master.
index].NCFace = nc_faces_info.Size();
4782 for (
unsigned i = 0; i < list.
slaves.size(); i++)
4789 slave_fi.
NCFace = nc_faces_info.Size();
4797 const int *fv = faces[slave.
master]->GetVertices();
4809 for (
int i = 0; i < NumOfElements; i++)
4811 const int *v = elements[i]->GetVertices();
4812 switch (GetElementType(i))
4816 for (
int j = 0; j < 4; j++)
4818 const int *fv = tet_faces[j];
4819 faces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]);
4827 for (
int j = 0; j < 6; j++)
4829 const int *fv = hex_faces[j];
4830 faces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]);
4835 MFEM_ABORT(
"Unexpected type of Element.");
4846 if (el_to_face != NULL)
4850 el_to_face =
new Table(NumOfElements, 6);
4851 faces_tbl =
new STable3D(NumOfVertices);
4852 for (i = 0; i < NumOfElements; i++)
4854 v = elements[i]->GetVertices();
4855 switch (GetElementType(i))
4859 for (
int j = 0; j < 4; j++)
4861 const int *fv = tet_faces[j];
4863 i, faces_tbl->
Push(v[fv[0]], v[fv[1]], v[fv[2]]));
4871 for (
int j = 0; j < 6; j++)
4873 const int *fv = hex_faces[j];
4875 i, faces_tbl->
Push4(v[fv[0]], v[fv[1]], v[fv[2]], v[fv[3]]));
4880 MFEM_ABORT(
"Unexpected type of Element.");
4883 el_to_face->Finalize();
4885 be_to_face.SetSize(NumOfBdrElements);
4886 for (i = 0; i < NumOfBdrElements; i++)
4888 v = boundary[i]->GetVertices();
4889 switch (GetBdrElementType(i))
4893 be_to_face[i] = (*faces_tbl)(v[0], v[1], v[2]);
4898 be_to_face[i] = (*faces_tbl)(v[0], v[1], v[2], v[3]);
4902 MFEM_ABORT(
"Unexpected type of boundary Element.");
4918 if (Dim != 3 || !(meshgen & 1))
4924 Table *old_elem_vert = NULL;
4928 PrepareNodeReorder(&old_v_to_v, &old_elem_vert);
4931 DeleteCoarseTables();
4933 for (
int i = 0; i < NumOfElements; i++)
4937 v = elements[i]->GetVertices();
4939 Rotate3(v[0], v[1], v[2]);
4942 Rotate3(v[1], v[2], v[3]);
4946 ShiftL2R(v[0], v[1], v[3]);
4951 for (
int i = 0; i < NumOfBdrElements; i++)
4955 v = boundary[i]->GetVertices();
4957 Rotate3(v[0], v[1], v[2]);
4963 GetElementToFaceTable();
4967 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
4972 DoNodeReorder(old_v_to_v, old_elem_vert);
4973 delete old_elem_vert;
4980 static int mfem_less(
const void *x,
const void *y)
4982 if (*(
int*)x < *(
int*)y)
4986 if (*(
int*)x > *(
int*)y)
4992 #ifndef MFEM_USE_METIS_5
4997 int*,
int*,
int*,
int*,
int*,
idxtype*);
4999 int*,
int*,
int*,
int*,
int*,
idxtype*);
5001 int*,
int*,
int*,
int*,
int*,
idxtype*);
5026 double pmin[3] = { numeric_limits<double>::infinity(),
5027 numeric_limits<double>::infinity(),
5028 numeric_limits<double>::infinity()
5030 double pmax[3] = { -numeric_limits<double>::infinity(),
5031 -numeric_limits<double>::infinity(),
5032 -numeric_limits<double>::infinity()
5035 for (
int vi = 0; vi < NumOfVertices; vi++)
5037 const double *p = vertices[vi]();
5038 for (
int i = 0; i < spaceDim; i++)
5040 if (p[i] < pmin[i]) { pmin[i] = p[i]; }
5041 if (p[i] > pmax[i]) { pmax[i] = p[i]; }
5045 partitioning =
new int[NumOfElements];
5049 Vector pt(ppt, spaceDim);
5050 for (
int el = 0; el < NumOfElements; el++)
5052 GetElementTransformation(el)->Transform(
5055 for (
int i = spaceDim-1; i >= 0; i--)
5057 int idx = (int)floor(nxyz[i]*((pt(i) - pmin[i])/(pmax[i] - pmin[i])));
5058 if (idx < 0) { idx = 0; }
5059 if (idx >= nxyz[i]) { idx = nxyz[i]-1; }
5060 part = part * nxyz[i] + idx;
5062 partitioning[el] = part;
5065 return partitioning;
5071 int i, *partitioning;
5073 ElementToElementTable();
5075 partitioning =
new int[NumOfElements];
5079 for (i = 0; i < NumOfElements; i++)
5081 partitioning[i] = 0;
5087 #ifndef MFEM_USE_METIS_5
5099 I = el_to_el->GetI();
5100 J = el_to_el->GetJ();
5101 #ifndef MFEM_USE_METIS_5
5109 if (part_method >= 0 && part_method <= 2)
5110 for (i = 0; i < n; i++)
5112 qsort(&J[I[i]], I[i+1]-I[i],
sizeof(
int), &mfem_less);
5117 if (part_method == 0 || part_method == 3)
5119 #ifndef MFEM_USE_METIS_5
5147 " error in METIS_PartGraphRecursive!");
5153 if (part_method == 1 || part_method == 4)
5155 #ifndef MFEM_USE_METIS_5
5183 " error in METIS_PartGraphKway!");
5189 if (part_method == 2 || part_method == 5)
5191 #ifndef MFEM_USE_METIS_5
5220 " error in METIS_PartGraphKway!");
5225 cout <<
"Mesh::GeneratePartitioning(...): edgecut = "
5239 for (i = 0; i < nparts; i++)
5245 for (i = 0; i < NumOfElements; i++)
5247 psize[partitioning[i]].one++;
5250 int empty_parts = 0;
5251 for (i = 0; i < nparts; i++)
5252 if (psize[i].one == 0)
5261 cerr <<
"Mesh::GeneratePartitioning returned " << empty_parts
5262 <<
" empty parts!" << endl;
5266 for (i = nparts-1; i > nparts-1-empty_parts; i--)
5271 for (
int j = 0; j < NumOfElements; j++)
5272 for (i = nparts-1; i > nparts-1-empty_parts; i--)
5273 if (psize[i].one == 0 || partitioning[j] != psize[i].two)
5279 partitioning[j] = psize[nparts-1-i].two;
5285 return partitioning;
5289 mfem_error(
"Mesh::GeneratePartitioning(...): "
5290 "MFEM was compiled without Metis.");
5304 int num_elem, *i_elem_elem, *j_elem_elem;
5306 num_elem = elem_elem.
Size();
5307 i_elem_elem = elem_elem.
GetI();
5308 j_elem_elem = elem_elem.
GetJ();
5313 int stack_p, stack_top_p, elem;
5317 for (i = 0; i < num_elem; i++)
5319 if (partitioning[i] > num_part)
5321 num_part = partitioning[i];
5328 for (i = 0; i < num_part; i++)
5335 for (elem = 0; elem < num_elem; elem++)
5337 if (component[elem] >= 0)
5342 component[elem] = num_comp[partitioning[elem]]++;
5344 elem_stack[stack_top_p++] = elem;
5346 for ( ; stack_p < stack_top_p; stack_p++)
5348 i = elem_stack[stack_p];
5349 for (j = i_elem_elem[i]; j < i_elem_elem[i+1]; j++)
5352 if (partitioning[k] == partitioning[i])
5354 if (component[k] < 0)
5356 component[k] = component[i];
5357 elem_stack[stack_top_p++] = k;
5359 else if (component[k] != component[i])
5371 int i, n_empty, n_mcomp;
5373 const Array<int> _partitioning(partitioning, GetNE());
5375 ElementToElementTable();
5379 n_empty = n_mcomp = 0;
5380 for (i = 0; i < num_comp.
Size(); i++)
5381 if (num_comp[i] == 0)
5385 else if (num_comp[i] > 1)
5392 cout <<
"Mesh::CheckPartitioning(...) :\n"
5393 <<
"The following subdomains are empty :\n";
5394 for (i = 0; i < num_comp.
Size(); i++)
5395 if (num_comp[i] == 0)
5403 cout <<
"Mesh::CheckPartitioning(...) :\n"
5404 <<
"The following subdomains are NOT connected :\n";
5405 for (i = 0; i < num_comp.
Size(); i++)
5406 if (num_comp[i] > 1)
5412 if (n_empty == 0 && n_mcomp == 0)
5413 cout <<
"Mesh::CheckPartitioning(...) : "
5414 "All subdomains are connected." << endl;
5428 const double *a = A.
Data();
5429 const double *b = B.
Data();
5438 c(0) = a[0]*a[3]-a[1]*a[2];
5439 c(1) = a[0]*b[3]-a[1]*b[2]+b[0]*a[3]-b[1]*a[2];
5440 c(2) = b[0]*b[3]-b[1]*b[2];
5461 c(0) = (a[0] * (a[4] * a[8] - a[5] * a[7]) +
5462 a[1] * (a[5] * a[6] - a[3] * a[8]) +
5463 a[2] * (a[3] * a[7] - a[4] * a[6]));
5465 c(1) = (b[0] * (a[4] * a[8] - a[5] * a[7]) +
5466 b[1] * (a[5] * a[6] - a[3] * a[8]) +
5467 b[2] * (a[3] * a[7] - a[4] * a[6]) +
5469 a[0] * (b[4] * a[8] - b[5] * a[7]) +
5470 a[1] * (b[5] * a[6] - b[3] * a[8]) +
5471 a[2] * (b[3] * a[7] - b[4] * a[6]) +
5473 a[0] * (a[4] * b[8] - a[5] * b[7]) +
5474 a[1] * (a[5] * b[6] - a[3] * b[8]) +
5475 a[2] * (a[3] * b[7] - a[4] * b[6]));
5477 c(2) = (a[0] * (b[4] * b[8] - b[5] * b[7]) +
5478 a[1] * (b[5] * b[6] - b[3] * b[8]) +
5479 a[2] * (b[3] * b[7] - b[4] * b[6]) +
5481 b[0] * (a[4] * b[8] - a[5] * b[7]) +
5482 b[1] * (a[5] * b[6] - a[3] * b[8]) +
5483 b[2] * (a[3] * b[7] - a[4] * b[6]) +
5485 b[0] * (b[4] * a[8] - b[5] * a[7]) +
5486 b[1] * (b[5] * a[6] - b[3] * a[8]) +
5487 b[2] * (b[3] * a[7] - b[4] * a[6]));
5489 c(3) = (b[0] * (b[4] * b[8] - b[5] * b[7]) +
5490 b[1] * (b[5] * b[6] - b[3] * b[8]) +
5491 b[2] * (b[3] * b[7] - b[4] * b[6]));
5537 double a = z(2), b = z(1), c = z(0);
5538 double D = b*b-4*a*c;
5545 x(0) = x(1) = -0.5 * b / a;
5550 x(0) = -(x(1) = fabs(0.5 * sqrt(D) / a));
5558 t = -0.5 * (b + sqrt(D));
5562 t = -0.5 * (b - sqrt(D));
5568 Swap<double>(x(0), x(1));
5576 double a = z(2)/z(3), b = z(1)/z(3), c = z(0)/z(3);
5579 double Q = (a * a - 3 * b) / 9;
5580 double R = (2 * a * a * a - 9 * a * b + 27 * c) / 54;
5581 double Q3 = Q * Q * Q;
5588 x(0) = x(1) = x(2) = - a / 3;
5592 double sqrtQ = sqrt(Q);
5596 x(0) = -2 * sqrtQ - a / 3;
5597 x(1) = x(2) = sqrtQ - a / 3;
5601 x(0) = x(1) = - sqrtQ - a / 3;
5602 x(2) = 2 * sqrtQ - a / 3;
5609 double theta = acos(R / sqrt(Q3));
5610 double A = -2 * sqrt(Q);
5612 x0 = A * cos(theta / 3) - a / 3;
5613 x1 = A * cos((theta + 2.0 * M_PI) / 3) - a / 3;
5614 x2 = A * cos((theta - 2.0 * M_PI) / 3) - a / 3;
5619 Swap<double>(x0, x1);
5623 Swap<double>(x1, x2);
5626 Swap<double>(x0, x1);
5639 A = -pow(sqrt(R2 - Q3) + R, 1.0/3.0);
5643 A = pow(sqrt(R2 - Q3) - R, 1.0/3.0);
5645 x(0) = A + Q / A - a / 3;
5654 const double factor,
const int Dim)
5656 const double c0 = c(0);
5657 c(0) = c0 * (1.0 - pow(factor, -Dim));
5659 for (
int j = 0; j < nr; j++)
5671 c(0) = c0 * (1.0 - pow(factor, Dim));
5673 for (
int j = 0; j < nr; j++)
5689 int nvs = vertices.Size();
5690 DenseMatrix P, V, DS, PDS(spaceDim), VDS(spaceDim);
5691 Vector c(spaceDim+1), x(spaceDim);
5692 const double factor = 2.0;
5699 for (
int i = 0; i < NumOfElements; i++)
5706 for (
int j = 0; j < spaceDim; j++)
5707 for (
int k = 0; k < nv; k++)
5709 P(j, k) = vertices[v[k]](j);
5710 V(j, k) = displacements(v[k]+j*nvs);
5714 GetTransformationFEforElementType(el->
GetType());
5740 for (
int j = 0; j < nv; j++)
5766 for (
int i = 0, nv = vertices.Size(); i < nv; i++)
5767 for (
int j = 0; j < spaceDim; j++)
5769 vertices[i](j) += displacements(j*nv+i);
5775 int nv = vertices.Size();
5776 vert_coord.
SetSize(nv*spaceDim);
5777 for (
int i = 0; i < nv; i++)
5778 for (
int j = 0; j < spaceDim; j++)
5780 vert_coord(j*nv+i) = vertices[i](j);
5786 for (
int i = 0, nv = vertices.Size(); i < nv; i++)
5787 for (
int j = 0; j < spaceDim; j++)
5789 vertices[i](j) = vert_coord(j*nv+i);
5798 for (
int j = 0; j < spaceDim; j++)
5800 coord[j] = (*Nodes)(fes->
DofToVDof(i, j));
5805 for (
int j = 0; j < spaceDim; j++)
5807 coord[j] = vertices[i](j);
5817 for (
int j = 0; j < spaceDim; j++)
5819 (*Nodes)(fes->
DofToVDof(i, j)) = coord[j];
5824 for (
int j = 0; j < spaceDim; j++)
5826 vertices[i](j) = coord[j];
5836 (*Nodes) += displacements;
5840 MoveVertices(displacements);
5848 node_coord = (*Nodes);
5852 GetVertices(node_coord);
5860 (*Nodes) = node_coord;
5864 SetVertices(node_coord);
5870 if (own_nodes) {
delete Nodes; }
5873 own_nodes = (int)make_owner;
5884 mfem::Swap<GridFunction*>(Nodes, nodes);
5885 mfem::Swap<int>(own_nodes, own_nodes_);
5896 for (k = 0; k < spaceDim; k++)
5898 vertices[result](k) = vertices[indexes[0]](k);
5901 for (j = 1; j < n; j++)
5902 for (k = 0; k < spaceDim; k++)
5904 vertices[result](k) += vertices[indexes[j]](k);
5907 for (k = 0; k < spaceDim; k++)
5909 vertices[result](k) *= (1.0 / n);
5915 Nodes->FESpace()->UpdateAndInterpolate(Nodes);
5921 int i, j, *v, vv[2], attr, wtls = WantTwoLevelState;
5926 UseTwoLevelState(1);
5931 if (el_to_edge == NULL)
5933 el_to_edge =
new Table;
5934 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
5937 int oedge = NumOfVertices;
5938 int oelem = oedge + NumOfEdges;
5940 DeleteCoarseTables();
5942 vertices.SetSize(oelem + NumOfElements);
5944 for (i = 0; i < NumOfElements; i++)
5946 v = elements[i]->GetVertices();
5948 AverageVertices(v, 4, oelem+i);
5950 e = el_to_edge->GetRow(i);
5952 vv[0] = v[0], vv[1] = v[1]; AverageVertices(vv, 2, oedge+e[0]);
5953 vv[0] = v[1], vv[1] = v[2]; AverageVertices(vv, 2, oedge+e[1]);
5954 vv[0] = v[2], vv[1] = v[3]; AverageVertices(vv, 2, oedge+e[2]);
5955 vv[0] = v[3], vv[1] = v[0]; AverageVertices(vv, 2, oedge+e[3]);
5958 elements.SetSize(4 * NumOfElements);
5959 for (i = 0; i < NumOfElements; i++)
5961 attr = elements[i]->GetAttribute();
5962 v = elements[i]->GetVertices();
5963 e = el_to_edge->GetRow(i);
5964 j = NumOfElements + 3 * i;
5966 elements[j+0] =
new Quadrilateral(oedge+e[0], v[1], oedge+e[1],
5968 elements[j+1] =
new Quadrilateral(oelem+i, oedge+e[1], v[2],
5970 elements[j+2] =
new Quadrilateral(oedge+e[3], oelem+i, oedge+e[2],
5973 if (WantTwoLevelState)
5990 boundary.SetSize(2 * NumOfBdrElements);
5991 for (i = 0; i < NumOfBdrElements; i++)
5994 v = boundary[i]->GetVertices();
5995 j = NumOfBdrElements + i;
5997 boundary[j] =
new Segment(oedge+be_to_edge[i], v[1], attr);
5999 if (WantTwoLevelState)
6001 #ifdef MFEM_USE_MEMALLOC
6012 v[1] = oedge+be_to_edge[i];
6015 if (WantTwoLevelState)
6017 c_NumOfVertices = NumOfVertices;
6018 c_NumOfEdges = NumOfEdges;
6019 c_NumOfElements = NumOfElements;
6020 c_NumOfBdrElements = NumOfBdrElements;
6026 NumOfVertices = oelem + NumOfElements;
6027 NumOfElements = 4 * NumOfElements;
6028 NumOfBdrElements = 2 * NumOfBdrElements;
6031 if (WantTwoLevelState)
6033 f_NumOfVertices = NumOfVertices;
6034 f_NumOfElements = NumOfElements;
6035 f_NumOfBdrElements = NumOfBdrElements;
6038 if (el_to_edge != NULL)
6040 if (WantTwoLevelState)
6042 c_el_to_edge = el_to_edge;
6044 f_el_to_edge =
new Table;
6045 NumOfEdges = GetElementToEdgeTable(*f_el_to_edge, be_to_edge);
6046 el_to_edge = f_el_to_edge;
6047 f_NumOfEdges = NumOfEdges;
6051 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6059 UseTwoLevelState(wtls);
6063 CheckElementOrientation(
false);
6064 CheckBdrElementOrientation(
false);
6070 int i, wtls = WantTwoLevelState;
6077 UseTwoLevelState(1);
6082 if (el_to_edge == NULL)
6084 el_to_edge =
new Table;
6085 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6087 if (el_to_face == NULL)
6089 GetElementToFaceTable();
6092 int oedge = NumOfVertices;
6093 int oface = oedge + NumOfEdges;
6094 int oelem = oface + NumOfFaces;
6096 DeleteCoarseTables();
6098 vertices.SetSize(oelem + NumOfElements);
6099 for (i = 0; i < NumOfElements; i++)
6102 "Element is not a hex!");
6103 v = elements[i]->GetVertices();
6105 AverageVertices(v, 8, oelem+i);
6107 f = el_to_face->GetRow(i);
6109 for (
int j = 0; j < 6; j++)
6111 for (
int k = 0; k < 4; k++)
6113 vv[k] = v[hex_faces[j][k]];
6115 AverageVertices(vv, 4, oface+f[j]);
6118 e = el_to_edge->GetRow(i);
6120 for (
int j = 0; j < 12; j++)
6122 for (
int k = 0; k < 2; k++)
6126 AverageVertices(vv, 2, oedge+e[j]);
6131 elements.SetSize(8 * NumOfElements);
6132 for (i = 0; i < NumOfElements; i++)
6134 attr = elements[i]->GetAttribute();
6135 v = elements[i]->GetVertices();
6136 e = el_to_edge->GetRow(i);
6137 f = el_to_face->GetRow(i);
6138 j = NumOfElements + 7 * i;
6140 elements[j+0] =
new Hexahedron(oedge+e[0], v[1], oedge+e[1], oface+f[0],
6141 oface+f[1], oedge+e[9], oface+f[2],
6143 elements[j+1] =
new Hexahedron(oface+f[0], oedge+e[1], v[2], oedge+e[2],
6144 oelem+i, oface+f[2], oedge+e[10],
6146 elements[j+2] =
new Hexahedron(oedge+e[3], oface+f[0], oedge+e[2], v[3],
6147 oface+f[4], oelem+i, oface+f[3],
6149 elements[j+3] =
new Hexahedron(oedge+e[8], oface+f[1], oelem+i,
6150 oface+f[4], v[4], oedge+e[4], oface+f[5],
6152 elements[j+4] =
new Hexahedron(oface+f[1], oedge+e[9], oface+f[2],
6153 oelem+i, oedge+e[4], v[5], oedge+e[5],
6155 elements[j+5] =
new Hexahedron(oelem+i, oface+f[2], oedge+e[10],
6156 oface+f[3], oface+f[5], oedge+e[5], v[6],
6158 elements[j+6] =
new Hexahedron(oface+f[4], oelem+i, oface+f[3],
6159 oedge+e[11], oedge+e[7], oface+f[5],
6160 oedge+e[6], v[7], attr);
6162 if (WantTwoLevelState)
6168 for (k = 0; k < 7; k++)
6170 oe->
Child[k] = j + k;
6184 boundary.SetSize(4 * NumOfBdrElements);
6185 for (i = 0; i < NumOfBdrElements; i++)
6188 "boundary Element is not a quad!");
6189 attr = boundary[i]->GetAttribute();
6190 v = boundary[i]->GetVertices();
6191 e = bel_to_edge->GetRow(i);
6192 f = & be_to_face[i];
6193 j = NumOfBdrElements + 3 * i;
6195 boundary[j+0] =
new Quadrilateral(oedge+e[0], v[1], oedge+e[1],
6197 boundary[j+1] =
new Quadrilateral(oface+f[0], oedge+e[1], v[2],
6199 boundary[j+2] =
new Quadrilateral(oedge+e[3], oface+f[0], oedge+e[2],
6202 if (WantTwoLevelState)
6219 if (WantTwoLevelState)
6221 c_NumOfVertices = NumOfVertices;
6222 c_NumOfEdges = NumOfEdges;
6223 c_NumOfFaces = NumOfFaces;
6224 c_NumOfElements = NumOfElements;
6225 c_NumOfBdrElements = NumOfBdrElements;
6231 NumOfVertices = oelem + NumOfElements;
6232 NumOfElements = 8 * NumOfElements;
6233 NumOfBdrElements = 4 * NumOfBdrElements;
6235 if (WantTwoLevelState)
6237 f_NumOfVertices = NumOfVertices;
6238 f_NumOfElements = NumOfElements;
6239 f_NumOfBdrElements = NumOfBdrElements;
6242 if (el_to_face != NULL)
6244 if (WantTwoLevelState)
6246 c_el_to_face = el_to_face;
6250 GetElementToFaceTable();
6252 if (WantTwoLevelState)
6254 f_el_to_face = el_to_face;
6255 f_NumOfFaces = NumOfFaces;
6260 CheckBdrElementOrientation(
false);
6263 if (el_to_edge != NULL)
6265 if (WantTwoLevelState)
6267 c_el_to_edge = el_to_edge;
6268 f_el_to_edge =
new Table;
6269 c_bel_to_edge = bel_to_edge;
6271 NumOfEdges = GetElementToEdgeTable(*f_el_to_edge, be_to_edge);
6272 el_to_edge = f_el_to_edge;
6273 f_bel_to_edge = bel_to_edge;
6274 f_NumOfEdges = NumOfEdges;
6278 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6285 UseTwoLevelState(wtls);
6295 int i, j, ind, nedges, wtls = WantTwoLevelState;
6300 mfem_error(
"Local and nonconforming refinements cannot be mixed.");
6305 UseTwoLevelState(1);
6309 DeleteCoarseTables();
6313 if (WantTwoLevelState)
6315 c_NumOfVertices = NumOfVertices;
6316 c_NumOfElements = NumOfElements;
6317 c_NumOfBdrElements = NumOfBdrElements;
6320 int cne = NumOfElements, cnv = NumOfVertices;
6321 NumOfVertices += marked_el.
Size();
6322 NumOfElements += marked_el.
Size();
6323 vertices.SetSize(NumOfVertices);
6324 elements.SetSize(NumOfElements);
6325 for (j = 0; j < marked_el.
Size(); j++)
6330 int new_v = cnv + j, new_e = cne + j;
6331 AverageVertices(vert, 2, new_v);
6332 elements[new_e] =
new Segment(new_v, vert[1], attr);
6333 if (WantTwoLevelState)
6335 #ifdef MFEM_USE_MEMALLOC
6350 if (WantTwoLevelState)
6352 f_NumOfVertices = NumOfVertices;
6353 f_NumOfElements = NumOfElements;
6354 f_NumOfBdrElements = NumOfBdrElements;
6364 if (WantTwoLevelState)
6366 c_NumOfVertices = NumOfVertices;
6367 c_NumOfEdges = NumOfEdges;
6368 c_NumOfElements = NumOfElements;
6369 c_NumOfBdrElements = NumOfBdrElements;
6373 DSTable v_to_v(NumOfVertices);
6374 GetVertexToVertexTable(v_to_v);
6378 int *edge1 =
new int[nedges];
6379 int *edge2 =
new int[nedges];
6380 int *middle =
new int[nedges];
6382 for (i = 0; i < nedges; i++)
6384 edge1[i] = edge2[i] = middle[i] = -1;
6387 for (i = 0; i < NumOfElements; i++)
6389 elements[i]->GetVertices(v);
6390 for (j = 1; j < v.
Size(); j++)
6392 ind = v_to_v(v[j-1], v[j]);
6393 (edge1[ind] == -1) ? (edge1[ind] = i) : (edge2[ind] = i);
6395 ind = v_to_v(v[0], v[v.
Size()-1]);
6396 (edge1[ind] == -1) ? (edge1[ind] = i) : (edge2[ind] = i);
6400 for (i = 0; i < marked_el.
Size(); i++)
6402 RedRefinement(marked_el[i], v_to_v, edge1, edge2, middle);
6406 int need_refinement;
6409 need_refinement = 0;
6410 for (i = 0; i < nedges; i++)
6411 if (middle[i] != -1 && edge1[i] != -1)
6413 need_refinement = 1;
6414 GreenRefinement(edge1[i], v_to_v, edge1, edge2, middle);
6417 while (need_refinement == 1);
6420 int v1[2], v2[2], bisect, temp;
6421 temp = NumOfBdrElements;
6422 for (i = 0; i < temp; i++)
6424 boundary[i]->GetVertices(v);
6425 bisect = v_to_v(v[0], v[1]);
6426 if (middle[bisect] != -1)
6430 v1[0] = v[0]; v1[1] = middle[bisect];
6431 v2[0] = middle[bisect]; v2[1] = v[1];
6433 if (WantTwoLevelState)
6435 boundary.
Append(
new Segment(v2, boundary[i]->GetAttribute()));
6436 #ifdef MFEM_USE_MEMALLOC
6443 new Segment(v1, boundary[i]->GetAttribute());
6451 boundary.Append(
new Segment(v2, boundary[i]->GetAttribute()));
6455 mfem_error(
"Only bisection of segment is implemented"
6459 NumOfBdrElements = boundary.Size();
6466 if (WantTwoLevelState)
6468 f_NumOfVertices = NumOfVertices;
6469 f_NumOfElements = NumOfElements;
6470 f_NumOfBdrElements = NumOfBdrElements;
6475 if (el_to_edge != NULL)
6477 if (WantTwoLevelState)
6479 c_el_to_edge = el_to_edge;
6481 f_el_to_edge =
new Table;
6482 NumOfEdges = GetElementToEdgeTable(*f_el_to_edge, be_to_edge);
6483 el_to_edge = f_el_to_edge;
6484 f_NumOfEdges = NumOfEdges;
6488 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6496 if (WantTwoLevelState)
6498 c_NumOfVertices = NumOfVertices;
6499 c_NumOfEdges = NumOfEdges;
6500 c_NumOfFaces = NumOfFaces;
6501 c_NumOfElements = NumOfElements;
6502 c_NumOfBdrElements = NumOfBdrElements;
6506 DSTable v_to_v(NumOfVertices);
6507 GetVertexToVertexTable(v_to_v);
6511 int *middle =
new int[nedges];
6513 for (i = 0; i < nedges; i++)
6523 for (i = 0; i < marked_el.
Size(); i++)
6525 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6529 for (i = 0; i < marked_el.
Size(); i++)
6531 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6533 Bisection(NumOfElements - 1, v_to_v, NULL, NULL, middle);
6534 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6538 for (i = 0; i < marked_el.
Size(); i++)
6540 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6542 ii = NumOfElements - 1;
6543 Bisection(ii, v_to_v, NULL, NULL, middle);
6544 Bisection(NumOfElements - 1, v_to_v, NULL, NULL, middle);
6545 Bisection(ii, v_to_v, NULL, NULL, middle);
6547 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6548 Bisection(NumOfElements-1, v_to_v, NULL, NULL, middle);
6549 Bisection(marked_el[i], v_to_v, NULL, NULL, middle);
6554 if (WantTwoLevelState)
6561 int need_refinement;
6566 need_refinement = 0;
6569 for (i = 0; i < NumOfElements; i++)
6573 if (elements[i]->NeedRefinement(v_to_v, middle))
6575 need_refinement = 1;
6576 Bisection(i, v_to_v, NULL, NULL, middle);
6580 while (need_refinement == 1);
6587 need_refinement = 0;
6588 for (i = 0; i < NumOfBdrElements; i++)
6589 if (boundary[i]->NeedRefinement(v_to_v, middle))
6591 need_refinement = 1;
6592 Bisection(i, v_to_v, middle);
6595 while (need_refinement == 1);
6598 int refinement_edges[2], type, flag;
6599 for (i = 0; i < NumOfElements; i++)
6606 ((
Tetrahedron *)El)->ParseRefinementFlag(refinement_edges, type,
6609 ((
Tetrahedron *)El)->CreateRefinementFlag(refinement_edges,
6614 NumOfBdrElements = boundary.Size();
6619 if (el_to_edge != NULL)
6621 if (WantTwoLevelState)
6623 c_el_to_edge = el_to_edge;
6624 f_el_to_edge =
new Table;
6625 c_bel_to_edge = bel_to_edge;
6627 NumOfEdges = GetElementToEdgeTable(*f_el_to_edge, be_to_edge);
6628 el_to_edge = f_el_to_edge;
6629 f_bel_to_edge = bel_to_edge;
6633 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6636 if (el_to_face != NULL)
6638 if (WantTwoLevelState)
6640 c_el_to_face = el_to_face;
6644 GetElementToFaceTable();
6646 if (WantTwoLevelState)
6648 f_el_to_face = el_to_face;
6652 if (WantTwoLevelState)
6654 f_NumOfVertices = NumOfVertices;
6655 f_NumOfEdges = NumOfEdges;
6656 f_NumOfFaces = NumOfFaces;
6657 f_NumOfElements = NumOfElements;
6658 f_NumOfBdrElements = NumOfBdrElements;
6666 UseTwoLevelState(wtls);
6670 CheckElementOrientation(
false);
6679 MFEM_ABORT(
"Mesh::NonconformingRefinement: NURBS meshes are not supported."
6680 " Project the NURBS to Nodes first.");
6683 int wtls = WantTwoLevelState;
6687 UseTwoLevelState(1);
6691 DeleteCoarseTables();
6696 ncmesh =
new NCMesh(
this);
6699 if (WantTwoLevelState)
6701 ncmesh->MarkCoarseLevel();
6705 ncmesh->Refine(refinements);
6709 ncmesh->LimitNCLevel(nc_limit);
6715 ncmesh->OnMeshUpdated(mesh2);
6719 Swap(*mesh2,
false);
6722 if (WantTwoLevelState)
6724 nc_coarse_level = mesh2;
6725 State = TWO_LEVEL_FINE;
6732 GenerateNCFaceInfo();
6737 UseTwoLevelState(wtls);
6750 NumOfVertices = vertices.Size();
6751 NumOfElements = elements.Size();
6752 NumOfBdrElements = boundary.Size();
6756 NumOfEdges = NumOfFaces = 0;
6759 el_to_edge =
new Table;
6760 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
6761 c_el_to_edge = NULL;
6765 GetElementToFaceTable();
6769 CheckBdrElementOrientation(
false);
6779 InitFromNCMesh(ncmesh);
6831 NURBSUniformRefinement();
6833 else if (meshgen == 1 || ncmesh)
6836 for (
int i = 0; i < elem_to_refine.
Size(); i++)
6838 elem_to_refine[i] = i;
6843 LocalRefinement(elem_to_refine);
6847 GeneralRefinement(elem_to_refine, 1);
6852 QuadUniformRefinement();
6856 HexUniformRefinement();
6865 int nonconforming,
int nc_limit)
6871 else if (nonconforming < 0)
6874 int type = elements[0]->GetType();
6885 if (nonconforming || ncmesh != NULL)
6888 NonconformingRefinement(refinements, nc_limit);
6893 for (
int i = 0; i < refinements.
Size(); i++)
6895 el_to_refine.
Append(refinements[i].index);
6899 int type, rt = (refinements.
Size() ? refinements[0].ref_type : 7);
6900 if (rt == 1 || rt == 2 || rt == 4)
6904 else if (rt == 3 || rt == 5 || rt == 6)
6914 LocalRefinement(el_to_refine, type);
6922 for (
int i = 0; i < el_to_refine.
Size(); i++)
6926 GeneralRefinement(refinements, nonconforming, nc_limit);
6934 GeneralRefinement(empty, 1);
6939 int nonconforming,
int nc_limit,
int seed)
6942 for (
int i = 0; i < levels; i++)
6945 for (
int j = 0; j < GetNE(); j++)
6947 if (!(rand() % frac))
6952 type = (Dim == 3) ? (rand() % 7 + 1) : (rand() % 3 + 1);
6957 GeneralRefinement(refs, nonconforming, nc_limit);
6965 for (
int k = 0; k < levels; k++)
6968 for (
int i = 0; i < GetNE(); i++)
6970 GetElementVertices(i, v);
6971 bool refine =
false;
6972 for (
int j = 0; j < v.
Size(); j++)
6975 for (
int l = 0; l < spaceDim; l++)
6977 double d = vert(l) - vertices[v[j]](l);
6980 if (dist <= eps*eps) { refine =
true;
break; }
6987 GeneralRefinement(refs, nonconforming);
6992 int *edge1,
int *edge2,
int *middle)
6995 int v[2][4], v_new, bisect, t;
7000 if (WantTwoLevelState)
7027 bisect = v_to_v(vert[0], vert[1]);
7031 mfem_error(
"Mesh::Bisection(...) of triangle! #1");
7034 if (middle[bisect] == -1)
7036 v_new = NumOfVertices++;
7037 for (
int d = 0; d < spaceDim; d++)
7039 V(d) = 0.5 * (vertices[vert[0]](d) + vertices[vert[1]](d));
7045 if (edge1[bisect] == i)
7047 edge1[bisect] = edge2[bisect];
7050 middle[bisect] = v_new;
7054 v_new = middle[bisect];
7062 v[0][0] = vert[2]; v[0][1] = vert[0]; v[0][2] = v_new;
7063 v[1][0] = vert[1]; v[1][1] = vert[2]; v[1][2] = v_new;
7065 if (WantTwoLevelState)
7067 #ifdef MFEM_USE_MEMALLOC
7086 bisect = v_to_v(v[1][0], v[1][1]);
7090 mfem_error(
"Mesh::Bisection(...) of triangle! #2");
7093 if (edge1[bisect] == i)
7095 edge1[bisect] = NumOfElements;
7097 else if (edge2[bisect] == i)
7099 edge2[bisect] = NumOfElements;
7106 int j, type, new_type, old_redges[2], new_redges[2][2], flag;
7110 mfem_error(
"Mesh::Bisection : TETRAHEDRON element is not marked for "
7116 bisect = v_to_v(vert[0], vert[1]);
7120 cerr <<
"Error in Bisection(...) of tetrahedron!" << endl
7121 <<
" redge[0] = " << old_redges[0]
7122 <<
" redge[1] = " << old_redges[1]
7123 <<
" type = " << type
7124 <<
" flag = " << flag << endl;
7128 if (middle[bisect] == -1)
7130 v_new = NumOfVertices++;
7131 for (j = 0; j < 3; j++)
7133 V(j) = 0.5 * (vertices[vert[0]](j) + vertices[vert[1]](j));
7137 middle[bisect] = v_new;
7141 v_new = middle[bisect];
7150 new_redges[0][0] = 2;
7151 new_redges[0][1] = 1;
7152 new_redges[1][0] = 2;
7153 new_redges[1][1] = 1;
7154 switch (old_redges[0])
7157 v[0][0] = vert[0]; v[0][1] = vert[2]; v[0][2] = vert[3];
7161 v[0][0] = vert[3]; v[0][1] = vert[0]; v[0][2] = vert[2];
7164 v[0][0] = vert[2]; v[0][1] = vert[3]; v[0][2] = vert[0];
7166 switch (old_redges[1])
7169 v[1][0] = vert[2]; v[1][1] = vert[1]; v[1][2] = vert[3];
7173 v[1][0] = vert[1]; v[1][1] = vert[3]; v[1][2] = vert[2];
7176 v[1][0] = vert[3]; v[1][1] = vert[2]; v[1][2] = vert[1];
7180 if (WantTwoLevelState)
7182 #ifdef MFEM_USE_MEMALLOC
7185 tet = TetMemory.Alloc();