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();
7203 #ifdef MFEM_USE_MEMALLOC
7207 elements.Append(tet2);
7226 CreateRefinementFlag(new_redges[1], new_type, flag+1);
7232 mfem_error(
"Bisection for now works only for triangles & tetrahedra.");
7239 int v[2][3], v_new, bisect, t;
7243 if (WantTwoLevelState)
7270 bisect = v_to_v(vert[0], vert[1]);
7274 mfem_error(
"Mesh::Bisection(...) of boundary triangle! #1");
7277 v_new = middle[bisect];
7281 mfem_error(
"Mesh::Bisection(...) of boundary triangle! #2");
7287 v[0][0] = vert[2]; v[0][1] = vert[0]; v[0][2] = v_new;
7288 v[1][0] = vert[1]; v[1][1] = vert[2]; v[1][2] = v_new;
7289 if (WantTwoLevelState)
7291 #ifdef MFEM_USE_MEMALLOC
7312 mfem_error(
"Bisection of boundary elements works only for triangles!");
7317 int *edge1,
int *edge2,
int *middle)
7320 int j, v1[3], v2[3], v3[3], v4[3], v_new[3], bisect[3];
7325 elements[i]->GetVertices(v);
7328 bisect[0] = v_to_v(v[0],v[1]);
7329 bisect[1] = v_to_v(v[1],v[2]);
7330 bisect[2] = v_to_v(v[0],v[2]);
7332 if (bisect[0] < 0 || bisect[1] < 0 || bisect[2] < 0)
7334 mfem_error(
"Mesh::UniformRefinement(...): ERROR");
7338 for (j = 0; j < 3; j++)
7339 if (middle[bisect[j]] == -1)
7341 v_new[j] = NumOfVertices++;
7342 for (
int d = 0; d < spaceDim; d++)
7344 V(d) = (vertices[v[j]](d) + vertices[v[(j+1)%3]](d))/2.;
7350 if (edge1[bisect[j]] == i)
7352 edge1[bisect[j]] = edge2[bisect[j]];
7355 middle[bisect[j]] = v_new[j];
7359 v_new[j] = middle[bisect[j]];
7362 edge1[bisect[j]] = -1;
7367 v1[0] = v[0]; v1[1] = v_new[0]; v1[2] = v_new[2];
7368 v2[0] = v_new[0]; v2[1] = v[1]; v2[2] = v_new[1];
7369 v3[0] = v_new[2]; v3[1] = v_new[1]; v3[2] = v[2];
7370 v4[0] = v_new[1]; v4[1] = v_new[2]; v4[2] = v_new[0];
7373 elements.Append(
new Triangle(v2, elements[i]->GetAttribute()));
7374 elements.Append(
new Triangle(v3, elements[i]->GetAttribute()));
7375 if (WantTwoLevelState)
7379 aux->
Child2 = NumOfElements;
7380 aux->
Child3 = NumOfElements+1;
7381 aux->
Child4 = NumOfElements+2;
7393 mfem_error(
"Uniform refinement for now works only for triangles.");
7403 delete nc_coarse_level;
7404 nc_coarse_level = NULL;
7405 ncmesh->ClearCoarseLevel();
7411 this->
Swap(*nc_coarse_level,
false);
7414 else if (State != s)
7426 for (i = 0; i < f_NumOfElements; )
7428 t = elements[i]->GetType();
7444 for (i = 0; i < f_NumOfBdrElements; )
7446 t = boundary[i]->GetType();
7462 if (el_to_edge != NULL)
7464 delete c_el_to_edge;
7465 el_to_edge = f_el_to_edge;
7472 fc_be_to_edge.DeleteAll();
7476 delete c_bel_to_edge;
7477 bel_to_edge = f_bel_to_edge;
7480 if (el_to_face != NULL)
7482 delete c_el_to_face;
7483 el_to_face = f_el_to_face;
7488 fc_faces_info.DeleteAll();
7491 NumOfVertices = f_NumOfVertices;
7492 NumOfEdges = f_NumOfEdges;
7495 NumOfFaces = f_NumOfFaces;
7497 NumOfElements = f_NumOfElements;
7498 NumOfBdrElements = f_NumOfBdrElements;
7504 if (el_to_edge != NULL)
7506 el_to_edge = f_el_to_edge;
7513 bel_to_edge = f_bel_to_edge;
7516 if (el_to_face != NULL)
7518 el_to_face = f_el_to_face;
7521 NumOfVertices = f_NumOfVertices;
7522 NumOfEdges = f_NumOfEdges;
7525 NumOfFaces = f_NumOfFaces;
7527 NumOfElements = f_NumOfElements;
7528 NumOfBdrElements = f_NumOfBdrElements;
7534 if (el_to_edge != NULL)
7536 el_to_edge = c_el_to_edge;
7543 bel_to_edge = c_bel_to_edge;
7546 if (el_to_face != NULL)
7548 el_to_face = c_el_to_face;
7551 NumOfVertices = c_NumOfVertices;
7552 NumOfEdges = c_NumOfEdges;
7555 NumOfFaces = c_NumOfFaces;
7557 NumOfElements = c_NumOfElements;
7558 NumOfBdrElements = c_NumOfBdrElements;
7562 else if (State != s)
7571 int t = elements[i]->GetType();
7640 int L, R, n, s, lb, rb;
7644 R = GetBisectionHierarchy(elements[n]);
7653 n |= ((L & 1) << s);
7661 n |= ((R & 1) << s);
7667 lb = 2 * nlb; rb = 2 * nrb;
7669 while (lb > 0 || rb > 0);
7688 t = elements[i]->GetType();
7704 type = GetBisectionHierarchy(elements[i]);
7714 int redges[2], type, flag;
7742 type |= ( GetBisectionHierarchy(E) << 3 );
7743 if (type < 8) { type = 0; }
7753 int t = elements[i]->GetType();
7775 case 1:
return aux->
Child2;
7776 case 2:
return aux->
Child3;
7777 case 3:
return aux->
Child4;
7783 case 0:
return aux->
Child2;
7784 case 1:
return aux->
Child3;
7785 case 2:
return aux->
Child4;
7849 if (j == 0) {
return i; }
7869 np[0] = 0.5 * ( pointmat(0,0) + pointmat(0,1) );
7870 np[1] = 0.5 * ( pointmat(1,0) + pointmat(1,1) );
7871 pointmat(0,1) = pointmat(0,0); pointmat(1,1) = pointmat(1,0);
7872 pointmat(0,0) = pointmat(0,2); pointmat(1,0) = pointmat(1,2);
7873 pointmat(0,2) = np[0]; pointmat(1,2) = np[1];
7878 np[0] = 0.5 * ( pointmat(0,0) + pointmat(0,1) );
7879 np[1] = 0.5 * ( pointmat(1,0) + pointmat(1,1) );
7880 pointmat(0,0) = pointmat(0,1); pointmat(1,0) = pointmat(1,1);
7881 pointmat(0,1) = pointmat(0,2); pointmat(1,1) = pointmat(1,2);
7882 pointmat(0,2) = np[0]; pointmat(1,2) = np[1];
7888 int i, j, redges[2], type, flag, ind[4];
7896 pointmat(0,1) = 0.5 * ( pointmat(0,0) + pointmat(0,1) );
7897 pointmat(1,1) = 0.5 * ( pointmat(1,0) + pointmat(1,1) );
7898 pointmat(2,1) = 0.5 * ( pointmat(2,0) + pointmat(2,1) );
7902 case 2: ind[0] = 0; ind[1] = 3; ind[2] = 1; ind[3] = 2;
break;
7903 case 3: ind[0] = 1; ind[1] = 3; ind[2] = 2; ind[3] = 0;
break;
7905 default: ind[0] = 2; ind[1] = 3; ind[2] = 0; ind[3] = 1;
7911 pointmat(0,0) = 0.5 * ( pointmat(0,0) + pointmat(0,1) );
7912 pointmat(1,0) = 0.5 * ( pointmat(1,0) + pointmat(1,1) );
7913 pointmat(2,0) = 0.5 * ( pointmat(2,0) + pointmat(2,1) );
7917 case 1: ind[0] = 3; ind[1] = 1; ind[2] = 0; ind[3] = 2;
break;
7918 case 4: ind[0] = 3; ind[1] = 0; ind[2] = 2; ind[3] = 1;
break;
7920 default: ind[0] = 3; ind[1] = 2; ind[2] = 1; ind[3] = 0;
7924 for (i = 0; i < 3; i++)
7926 for (j = 0; j < 4; j++)
7928 t[j] = pointmat(i,j);
7930 for (j = 0; j < 4; j++)
7932 pointmat(i,ind[j]) = t[j];
7950 return ((k << 1)+1) << l;
7986 Transformation.Attribute = 0;
7987 Transformation.ElementNo = 0;
7993 case 0: pm(0,0) = 0.0; pm(0,1) = 0.5;
break;
7994 default: pm(0,0) = 0.5; pm(0,1) = 1.0;
break;
7999 pm(0,0) = 0.0; pm(0,1) = 1.0;
8005 Transformation.Attribute = 0;
8006 Transformation.ElementNo = 0;
8007 t = elements[i]->GetType();
8019 pm(0,0) = 0.0; pm(1,0) = 0.0;
8020 pm(0,1) = 0.5; pm(1,1) = 0.0;
8021 pm(0,2) = 0.5; pm(1,2) = 0.5;
8022 pm(0,3) = 0.0; pm(1,3) = 0.5;
8025 pm(0,0) = 0.5; pm(1,0) = 0.0;
8026 pm(0,1) = 1.0; pm(1,1) = 0.0;
8027 pm(0,2) = 1.0; pm(1,2) = 0.5;
8028 pm(0,3) = 0.5; pm(1,3) = 0.5;
8031 pm(0,0) = 0.5; pm(1,0) = 0.5;
8032 pm(0,1) = 1.0; pm(1,1) = 0.5;
8033 pm(0,2) = 1.0; pm(1,2) = 1.0;
8034 pm(0,3) = 0.5; pm(1,3) = 1.0;
8037 pm(0,0) = 0.0; pm(1,0) = 0.5;
8038 pm(0,1) = 0.5; pm(1,1) = 0.5;
8039 pm(0,2) = 0.5; pm(1,2) = 1.0;
8040 pm(0,3) = 0.0; pm(1,3) = 1.0;
8054 pm(0,0) = 0.0; pm(0,1) = 0.5; pm(0,2) = 0.0;
8055 pm(1,0) = 0.0; pm(1,1) = 0.0; pm(1,2) = 0.5;
8058 pm(0,0) = 0.5; pm(0,1) = 1.0; pm(0,2) = 0.5;
8059 pm(1,0) = 0.0; pm(1,1) = 0.0; pm(1,2) = 0.5;
8062 pm(0,0) = 0.0; pm(0,1) = 0.5; pm(0,2) = 0.0;
8063 pm(1,0) = 0.5; pm(1,1) = 0.5; pm(1,2) = 1.0;
8066 pm(0,0) = 0.5; pm(0,1) = 0.0; pm(0,2) = 0.5;
8067 pm(1,0) = 0.5; pm(1,1) = 0.5; pm(1,2) = 0.0;
8085 pm(0,0) = 0.0; pm(0,1) = 1.0; pm(0,2) = 0.0;
8086 pm(1,0) = 0.0; pm(1,1) = 0.0; pm(1,2) = 1.0;
8088 path = GetFineElemPath(i, j);
8105 pm(0,0) = 0.0; pm(0,1) = 1.0; pm(0,2) = 0.0;
8106 pm(1,0) = 0.0; pm(1,1) = 0.0; pm(1,2) = 1.0;
8108 return &Transformation;
8118 Transformation.Attribute = 0;
8119 Transformation.ElementNo = 0;
8121 if (j < 4) { dz = 0.0; }
8124 if (jj < 2) { dy = 0.0; }
8126 if (jj == 0 || jj == 3) { dx = 0.0; }
8128 pm(0,0) = dx; pm(1,0) = dy; pm(2,0) = dz;
8129 pm(0,1) = 0.5 + dx; pm(1,1) = dy; pm(2,1) = dz;
8130 pm(0,2) = 0.5 + dx; pm(1,2) = 0.5 + dy; pm(2,2) = dz;
8131 pm(0,3) = dx; pm(1,3) = 0.5 + dy; pm(2,3) = dz;
8132 pm(0,4) = dx; pm(1,4) = dy; pm(2,4) = 0.5 + dz;
8133 pm(0,5) = 0.5 + dx; pm(1,5) = dy; pm(2,5) = 0.5 + dz;
8134 pm(0,6) = 0.5 + dx; pm(1,6) = 0.5 + dy; pm(2,6) = 0.5 + dz;
8135 pm(0,7) = dx; pm(1,7) = 0.5 + dy; pm(2,7) = 0.5 + dz;
8136 return &Transformation;
8142 Transformation.Attribute = 0;
8143 Transformation.ElementNo = 0;
8148 pm(0,0) = 0.0; pm(0,1) = 1.0; pm(0,2) = 0.0; pm(0,3) = 0.0;
8149 pm(1,0) = 0.0; pm(1,1) = 0.0; pm(1,2) = 1.0; pm(1,3) = 0.0;
8150 pm(2,0) = 0.0; pm(2,1) = 0.0; pm(2,2) = 0.0; pm(2,3) = 1.0;
8152 path = GetFineElemPath(i, j);
8165 return &Transformation;
8170 MFEM_ASSERT(Dim==spaceDim,
"2D Manifold meshes not supported");
8179 out <<
"areamesh2\n\n";
8183 out <<
"curved_areamesh2\n\n";
8187 out << NumOfBdrElements <<
'\n';
8188 for (i = 0; i < NumOfBdrElements; i++)
8190 boundary[i]->GetVertices(v);
8192 out << boundary[i]->GetAttribute();
8193 for (j = 0; j < v.
Size(); j++)
8195 out <<
' ' << v[j] + 1;
8201 out << NumOfElements <<
'\n';
8202 for (i = 0; i < NumOfElements; i++)
8204 elements[i]->GetVertices(v);
8206 out << elements[i]->GetAttribute() <<
' ' << v.
Size();
8207 for (j = 0; j < v.
Size(); j++)
8209 out <<
' ' << v[j] + 1;
8217 out << NumOfVertices <<
'\n';
8218 for (i = 0; i < NumOfVertices; i++)
8220 out << vertices[i](0);
8221 for (j = 1; j < Dim; j++)
8223 out <<
' ' << vertices[i](j);
8230 out << NumOfVertices <<
'\n';
8238 mfem_error(
"Mesh::PrintXG(...) : Curved mesh in 3D");
8246 out <<
"NETGEN_Neutral_Format\n";
8248 out << NumOfVertices <<
'\n';
8249 for (i = 0; i < NumOfVertices; i++)
8251 for (j = 0; j < Dim; j++)
8253 out <<
' ' << vertices[i](j);
8259 out << NumOfElements <<
'\n';
8260 for (i = 0; i < NumOfElements; i++)
8262 nv = elements[i]->GetNVertices();
8263 ind = elements[i]->GetVertices();
8264 out << elements[i]->GetAttribute();
8265 for (j = 0; j < nv; j++)
8267 out <<
' ' << ind[j]+1;
8273 out << NumOfBdrElements <<
'\n';
8274 for (i = 0; i < NumOfBdrElements; i++)
8276 nv = boundary[i]->GetNVertices();
8277 ind = boundary[i]->GetVertices();
8278 out << boundary[i]->GetAttribute();
8279 for (j = 0; j < nv; j++)
8281 out <<
' ' << ind[j]+1;
8286 else if (meshgen == 2)
8292 <<
"1 " << NumOfVertices <<
" " << NumOfElements
8293 <<
" 0 0 0 0 0 0 0\n"
8294 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
8295 <<
"0 0 " << NumOfBdrElements <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
8296 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
8297 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
8299 for (i = 0; i < NumOfVertices; i++)
8300 out << i+1 <<
" 0.0 " << vertices[i](0) <<
' ' << vertices[i](1)
8301 <<
' ' << vertices[i](2) <<
" 0.0\n";
8303 for (i = 0; i < NumOfElements; i++)
8305 nv = elements[i]->GetNVertices();
8306 ind = elements[i]->GetVertices();
8307 out << i+1 <<
' ' << elements[i]->GetAttribute();
8308 for (j = 0; j < nv; j++)
8310 out <<
' ' << ind[j]+1;
8315 for (i = 0; i < NumOfBdrElements; i++)
8317 nv = boundary[i]->GetNVertices();
8318 ind = boundary[i]->GetVertices();
8319 out << boundary[i]->GetAttribute();
8320 for (j = 0; j < nv; j++)
8322 out <<
' ' << ind[j]+1;
8324 out <<
" 1.0 1.0 1.0 1.0\n";
8339 NURBSext->Print(out);
8350 out << (ncmesh ?
"MFEM mesh v1.1\n" :
"MFEM mesh v1.0\n");
8354 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
8359 "# TETRAHEDRON = 4\n"
8363 out <<
"\ndimension\n" << Dim
8364 <<
"\n\nelements\n" << NumOfElements <<
'\n';
8365 for (i = 0; i < NumOfElements; i++)
8367 PrintElement(elements[i], out);
8370 out <<
"\nboundary\n" << NumOfBdrElements <<
'\n';
8371 for (i = 0; i < NumOfBdrElements; i++)
8373 PrintElement(boundary[i], out);
8378 out <<
"\nvertex_parents\n";
8379 ncmesh->PrintVertexParents(out);
8381 out <<
"\ncoarse_elements\n";
8382 ncmesh->PrintCoarseElements(out);
8385 out <<
"\nvertices\n" << NumOfVertices <<
'\n';
8388 out << spaceDim <<
'\n';
8389 for (i = 0; i < NumOfVertices; i++)
8391 out << vertices[i](0);
8392 for (j = 1; j < spaceDim; j++)
8394 out <<
' ' << vertices[i](j);
8411 out <<
"MFEM NURBS mesh v1.0\n";
8415 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
8421 out <<
"\ndimension\n" << Dim
8422 <<
"\n\nelements\n" << NumOfElements <<
'\n';
8423 for (i = 0; i < NumOfElements; i++)
8425 PrintElement(elements[i], out);
8428 out <<
"\nboundary\n" << NumOfBdrElements <<
'\n';
8429 for (i = 0; i < NumOfBdrElements; i++)
8431 PrintElement(boundary[i], out);
8434 out <<
"\nedges\n" << NumOfEdges <<
'\n';
8435 for (i = 0; i < NumOfEdges; i++)
8437 edge_vertex->GetRow(i, vert);
8443 out << ki <<
' ' << vert[0] <<
' ' << vert[1] <<
'\n';
8445 out <<
"\nvertices\n" << NumOfVertices <<
'\n';
8451 "# vtk DataFile Version 3.0\n"
8452 "Generated by MFEM\n"
8454 "DATASET UNSTRUCTURED_GRID\n";
8458 out <<
"POINTS " << NumOfVertices <<
" double\n";
8459 for (
int i = 0; i < NumOfVertices; i++)
8461 out << vertices[i](0);
8463 for (j = 1; j < spaceDim; j++)
8465 out <<
' ' << vertices[i](j);
8477 out <<
"POINTS " << Nodes->FESpace()->GetNDofs() <<
" double\n";
8478 for (
int i = 0; i < Nodes->FESpace()->GetNDofs(); i++)
8482 Nodes->FESpace()->DofsToVDofs(vdofs);
8483 out << (*Nodes)(vdofs[0]);
8485 for (j = 1; j < spaceDim; j++)
8487 out <<
' ' << (*Nodes)(vdofs[j]);
8501 for (
int i = 0; i < NumOfElements; i++)
8503 size += elements[i]->GetNVertices() + 1;
8505 out <<
"CELLS " << NumOfElements <<
' ' << size <<
'\n';
8506 for (
int i = 0; i < NumOfElements; i++)
8508 const int *v = elements[i]->GetVertices();
8509 const int nv = elements[i]->GetNVertices();
8511 for (
int j = 0; j < nv; j++)
8523 for (
int i = 0; i < NumOfElements; i++)
8525 Nodes->FESpace()->GetElementDofs(i, dofs);
8526 size += dofs.
Size() + 1;
8528 out <<
"CELLS " << NumOfElements <<
' ' << size <<
'\n';
8529 const char *fec_name = Nodes->FESpace()->FEColl()->Name();
8530 if (!strcmp(fec_name,
"Linear") ||
8531 !strcmp(fec_name,
"H1_2D_P1") ||
8532 !strcmp(fec_name,
"H1_3D_P1"))
8536 else if (!strcmp(fec_name,
"Quadratic") ||
8537 !strcmp(fec_name,
"H1_2D_P2") ||
8538 !strcmp(fec_name,
"H1_3D_P2"))
8544 cerr <<
"Mesh::PrintVTK : can not save '"
8545 << fec_name <<
"' elements!" << endl;
8548 for (
int i = 0; i < NumOfElements; i++)
8550 Nodes->FESpace()->GetElementDofs(i, dofs);
8554 for (
int j = 0; j < dofs.
Size(); j++)
8556 out <<
' ' << dofs[j];
8559 else if (order == 2)
8561 const int *vtk_mfem;
8562 switch (elements[i]->GetGeometryType())
8566 vtk_mfem = vtk_quadratic_hex;
break;
8568 vtk_mfem = vtk_quadratic_tet;
break;
8571 vtk_mfem = vtk_quadratic_hex;
break;
8573 for (
int j = 0; j < dofs.
Size(); j++)
8575 out <<
' ' << dofs[vtk_mfem[j]];
8582 out <<
"CELL_TYPES " << NumOfElements <<
'\n';
8583 for (
int i = 0; i < NumOfElements; i++)
8585 int vtk_cell_type = 5;
8588 switch (elements[i]->GetGeometryType())
8596 else if (order == 2)
8598 switch (elements[i]->GetGeometryType())
8607 out << vtk_cell_type <<
'\n';
8611 out <<
"CELL_DATA " << NumOfElements <<
'\n'
8612 <<
"SCALARS material int\n"
8613 <<
"LOOKUP_TABLE default\n";
8614 for (
int i = 0; i < NumOfElements; i++)
8616 out << elements[i]->GetAttribute() <<
'\n';
8627 "# vtk DataFile Version 3.0\n"
8628 "Generated by MFEM\n"
8630 "DATASET UNSTRUCTURED_GRID\n";
8635 out <<
"FIELD FieldData 1" << endl
8636 <<
"MaterialIds " << 1 <<
" " << attributes.
Size() <<
" int" << endl;
8637 for (
int i = 0; i < attributes.Size(); i++)
8639 out << attributes[i] <<
" ";
8646 for (
int i = 0; i < GetNE(); i++)
8648 int geom = GetElementBaseGeometry(i);
8655 out <<
"POINTS " << np <<
" double\n";
8657 for (
int i = 0; i < GetNE(); i++)
8660 GetElementBaseGeometry(i), ref, 1);
8662 GetElementTransformation(i)->Transform(RefG->
RefPts, pmat);
8664 for (
int j = 0; j < pmat.
Width(); j++)
8666 out << pmat(0, j) <<
' ';
8669 out << pmat(1, j) <<
' ';
8681 out << 0.0 <<
' ' << 0.0;
8688 out <<
"CELLS " << nc <<
' ' << size <<
'\n';
8690 for (
int i = 0; i < GetNE(); i++)
8692 int geom = GetElementBaseGeometry(i);
8697 for (
int j = 0; j < RG.
Size(); )
8700 for (
int k = 0; k < nv; k++, j++)
8702 out <<
' ' << np + RG[j];
8708 out <<
"CELL_TYPES " << nc <<
'\n';
8709 for (
int i = 0; i < GetNE(); i++)
8711 int geom = GetElementBaseGeometry(i);
8715 int vtk_cell_type = 5;
8726 for (
int j = 0; j < RG.
Size(); j += nv)
8728 out << vtk_cell_type <<
'\n';
8732 out <<
"CELL_DATA " << nc <<
'\n'
8733 <<
"SCALARS material int\n"
8734 <<
"LOOKUP_TABLE default\n";
8735 for (
int i = 0; i < GetNE(); i++)
8737 int geom = GetElementBaseGeometry(i);
8740 int attr = GetAttribute(i);
8743 out << attr <<
'\n';
8748 srand((
unsigned)time(0));
8749 double a = double(rand()) / (double(RAND_MAX) + 1.);
8750 int el0 = (int)floor(a * GetNE());
8751 GetElementColoring(coloring, el0);
8752 out <<
"SCALARS element_coloring int\n"
8753 <<
"LOOKUP_TABLE default\n";
8754 for (
int i = 0; i < GetNE(); i++)
8756 int geom = GetElementBaseGeometry(i);
8761 out << coloring[i] + 1 <<
'\n';
8765 out <<
"POINT_DATA " << np <<
'\n';
8770 int delete_el_to_el = (el_to_el) ? (0) : (1);
8771 const Table &el_el = ElementToElementTable();
8772 int num_el = GetNE(), stack_p, stack_top_p, max_num_col;
8775 const int *i_el_el = el_el.
GetI();
8776 const int *j_el_el = el_el.
GetJ();
8781 stack_p = stack_top_p = 0;
8782 for (
int el = el0; stack_top_p < num_el; el=(el+1)%num_el)
8784 if (colors[el] != -2)
8790 el_stack[stack_top_p++] = el;
8792 for ( ; stack_p < stack_top_p; stack_p++)
8794 int i = el_stack[stack_p];
8795 int num_nb = i_el_el[i+1] - i_el_el[i];
8796 if (max_num_col < num_nb + 1)
8798 max_num_col = num_nb + 1;
8800 for (
int j = i_el_el[i]; j < i_el_el[i+1]; j++)
8803 if (colors[k] == -2)
8806 el_stack[stack_top_p++] = k;
8814 for (stack_p = 0; stack_p < stack_top_p; stack_p++)
8816 int i = el_stack[stack_p], col;
8818 for (
int j = i_el_el[i]; j < i_el_el[i+1]; j++)
8820 col = colors[j_el_el[j]];
8823 col_marker[col] = 1;
8827 for (col = 0; col < max_num_col; col++)
8828 if (col_marker[col] == 0)
8836 if (delete_el_to_el)
8844 int elem_attr)
const
8846 if (Dim != 3 && Dim != 2) {
return; }
8848 int i, j, k, l, nv, nbe, *v;
8850 out <<
"MFEM mesh v1.0\n";
8854 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
8859 "# TETRAHEDRON = 4\n"
8863 out <<
"\ndimension\n" << Dim
8864 <<
"\n\nelements\n" << NumOfElements <<
'\n';
8865 for (i = 0; i < NumOfElements; i++)
8867 out << int((elem_attr) ? partitioning[i]+1 : elements[i]->GetAttribute())
8868 <<
' ' << elements[i]->GetGeometryType();
8869 nv = elements[i]->GetNVertices();
8870 v = elements[i]->GetVertices();
8871 for (j = 0; j < nv; j++)
8878 for (i = 0; i < faces_info.Size(); i++)
8880 if ((l = faces_info[i].Elem2No) >= 0)
8882 k = partitioning[faces_info[i].Elem1No];
8883 l = partitioning[l];
8894 out <<
"\nboundary\n" << nbe <<
'\n';
8895 for (i = 0; i < faces_info.Size(); i++)
8897 if ((l = faces_info[i].Elem2No) >= 0)
8899 k = partitioning[faces_info[i].Elem1No];
8900 l = partitioning[l];
8903 nv = faces[i]->GetNVertices();
8904 v = faces[i]->GetVertices();
8905 out << k+1 <<
' ' << faces[i]->GetGeometryType();
8906 for (j = 0; j < nv; j++)
8911 out << l+1 <<
' ' << faces[i]->GetGeometryType();
8912 for (j = nv-1; j >= 0; j--)
8921 k = partitioning[faces_info[i].Elem1No];
8922 nv = faces[i]->GetNVertices();
8923 v = faces[i]->GetVertices();
8924 out << k+1 <<
' ' << faces[i]->GetGeometryType();
8925 for (j = 0; j < nv; j++)
8932 out <<
"\nvertices\n" << NumOfVertices <<
'\n';
8935 out << spaceDim <<
'\n';
8936 for (i = 0; i < NumOfVertices; i++)
8938 out << vertices[i](0);
8939 for (j = 1; j < spaceDim; j++)
8941 out <<
' ' << vertices[i](j);
8957 MFEM_ASSERT(Dim == spaceDim,
"2D Manifolds not supported\n");
8958 if (Dim != 3 && Dim != 2) {
return; }
8965 int *vcount =
new int[NumOfVertices];
8966 for (i = 0; i < NumOfVertices; i++)
8970 for (i = 0; i < NumOfElements; i++)
8972 nv = elements[i]->GetNVertices();
8973 ind = elements[i]->GetVertices();
8974 for (j = 0; j < nv; j++)
8980 int *voff =
new int[NumOfVertices+1];
8982 for (i = 1; i <= NumOfVertices; i++)
8984 voff[i] = vcount[i-1] + voff[i-1];
8987 int **vown =
new int*[NumOfVertices];
8988 for (i = 0; i < NumOfVertices; i++)
8990 vown[i] =
new int[vcount[i]];
9000 Transpose(ElementToEdgeTable(), edge_el);
9003 for (i = 0; i < NumOfElements; i++)
9005 nv = elements[i]->GetNVertices();
9006 ind = elements[i]->GetVertices();
9007 for (j = 0; j < nv; j++)
9010 vown[ind[j]][vcount[ind[j]]] = i;
9014 for (i = 0; i < NumOfVertices; i++)
9016 vcount[i] = voff[i+1] - voff[i];
9020 for (i = 0; i < edge_el.
Size(); i++)
9022 const int *el = edge_el.
GetRow(i);
9025 k = partitioning[el[0]];
9026 l = partitioning[el[1]];
9027 if (interior_faces || k != l)
9039 out <<
"areamesh2\n\n" << nbe <<
'\n';
9041 for (i = 0; i < edge_el.
Size(); i++)
9043 const int *el = edge_el.
GetRow(i);
9046 k = partitioning[el[0]];
9047 l = partitioning[el[1]];
9048 if (interior_faces || k != l)
9051 GetEdgeVertices(i,ev);
9053 for (j = 0; j < 2; j++)
9054 for (s = 0; s < vcount[ev[j]]; s++)
9055 if (vown[ev[j]][s] == el[0])
9057 out <<
' ' << voff[ev[j]]+s+1;
9061 for (j = 1; j >= 0; j--)
9062 for (s = 0; s < vcount[ev[j]]; s++)
9063 if (vown[ev[j]][s] == el[1])
9065 out <<
' ' << voff[ev[j]]+s+1;
9072 k = partitioning[el[0]];
9074 GetEdgeVertices(i,ev);
9076 for (j = 0; j < 2; j++)
9077 for (s = 0; s < vcount[ev[j]]; s++)
9078 if (vown[ev[j]][s] == el[0])
9080 out <<
' ' << voff[ev[j]]+s+1;
9087 out << NumOfElements <<
'\n';
9088 for (i = 0; i < NumOfElements; i++)
9090 nv = elements[i]->GetNVertices();
9091 ind = elements[i]->GetVertices();
9092 out << partitioning[i]+1 <<
' ';
9094 for (j = 0; j < nv; j++)
9096 out <<
' ' << voff[ind[j]]+vcount[ind[j]]--;
9097 vown[ind[j]][vcount[ind[j]]] = i;
9102 for (i = 0; i < NumOfVertices; i++)
9104 vcount[i] = voff[i+1] - voff[i];
9108 out << voff[NumOfVertices] <<
'\n';
9109 for (i = 0; i < NumOfVertices; i++)
9110 for (k = 0; k < vcount[i]; k++)
9112 for (j = 0; j < Dim; j++)
9114 out << vertices[i](j) <<
' ';
9125 out <<
"NETGEN_Neutral_Format\n";
9127 out << voff[NumOfVertices] <<
'\n';
9128 for (i = 0; i < NumOfVertices; i++)
9129 for (k = 0; k < vcount[i]; k++)
9131 for (j = 0; j < Dim; j++)
9133 out <<
' ' << vertices[i](j);
9139 out << NumOfElements <<
'\n';
9140 for (i = 0; i < NumOfElements; i++)
9142 nv = elements[i]->GetNVertices();
9143 ind = elements[i]->GetVertices();
9144 out << partitioning[i]+1;
9145 for (j = 0; j < nv; j++)
9147 out <<
' ' << voff[ind[j]]+vcount[ind[j]]--;
9148 vown[ind[j]][vcount[ind[j]]] = i;
9153 for (i = 0; i < NumOfVertices; i++)
9155 vcount[i] = voff[i+1] - voff[i];
9161 for (i = 0; i < NumOfFaces; i++)
9162 if ((l = faces_info[i].Elem2No) >= 0)
9164 k = partitioning[faces_info[i].Elem1No];
9165 l = partitioning[l];
9166 if (interior_faces || k != l)
9177 for (i = 0; i < NumOfFaces; i++)
9178 if ((l = faces_info[i].Elem2No) >= 0)
9180 k = partitioning[faces_info[i].Elem1No];
9181 l = partitioning[l];
9182 if (interior_faces || k != l)
9184 nv = faces[i]->GetNVertices();
9185 ind = faces[i]->GetVertices();
9187 for (j = 0; j < nv; j++)
9188 for (s = 0; s < vcount[ind[j]]; s++)
9189 if (vown[ind[j]][s] == faces_info[i].Elem1No)
9191 out <<
' ' << voff[ind[j]]+s+1;
9195 for (j = nv-1; j >= 0; j--)
9196 for (s = 0; s < vcount[ind[j]]; s++)
9197 if (vown[ind[j]][s] == faces_info[i].Elem2No)
9199 out <<
' ' << voff[ind[j]]+s+1;
9206 k = partitioning[faces_info[i].Elem1No];
9207 nv = faces[i]->GetNVertices();
9208 ind = faces[i]->GetVertices();
9210 for (j = 0; j < nv; j++)
9211 for (s = 0; s < vcount[ind[j]]; s++)
9212 if (vown[ind[j]][s] == faces_info[i].Elem1No)
9214 out <<
' ' << voff[ind[j]]+s+1;
9219 for (i = 0; i < NumOfVertices; i++)
9224 else if (meshgen == 2)
9229 for (i = 0; i < NumOfFaces; i++)
9230 if ((l = faces_info[i].Elem2No) >= 0)
9232 k = partitioning[faces_info[i].Elem1No];
9233 l = partitioning[l];
9234 if (interior_faces || k != l)
9246 <<
"1 " << voff[NumOfVertices] <<
" " << NumOfElements
9247 <<
" 0 0 0 0 0 0 0\n"
9248 <<
"0 0 0 1 0 0 0 0 0 0 0\n"
9249 <<
"0 0 " << nbe <<
" 0 0 0 0 0 0 0 0 0 0 0 0 0\n"
9250 <<
"0.0 0.0 0.0 0 0 0.0 0.0 0 0.0\n"
9251 <<
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n";
9253 for (i = 0; i < NumOfVertices; i++)
9254 for (k = 0; k < vcount[i]; k++)
9255 out << voff[i]+k <<
" 0.0 " << vertices[i](0) <<
' '
9256 << vertices[i](1) <<
' ' << vertices[i](2) <<
" 0.0\n";
9258 for (i = 0; i < NumOfElements; i++)
9260 nv = elements[i]->GetNVertices();
9261 ind = elements[i]->GetVertices();
9262 out << i+1 <<
' ' << partitioning[i]+1;
9263 for (j = 0; j < nv; j++)
9265 out <<
' ' << voff[ind[j]]+vcount[ind[j]]--;
9266 vown[ind[j]][vcount[ind[j]]] = i;
9271 for (i = 0; i < NumOfVertices; i++)
9273 vcount[i] = voff[i+1] - voff[i];
9277 for (i = 0; i < NumOfFaces; i++)
9278 if ((l = faces_info[i].Elem2No) >= 0)
9280 k = partitioning[faces_info[i].Elem1No];
9281 l = partitioning[l];
9282 if (interior_faces || k != l)
9284 nv = faces[i]->GetNVertices();
9285 ind = faces[i]->GetVertices();
9287 for (j = 0; j < nv; j++)
9288 for (s = 0; s < vcount[ind[j]]; s++)
9289 if (vown[ind[j]][s] == faces_info[i].Elem1No)
9291 out <<
' ' << voff[ind[j]]+s+1;
9293 out <<
" 1.0 1.0 1.0 1.0\n";
9295 for (j = nv-1; j >= 0; j--)
9296 for (s = 0; s < vcount[ind[j]]; s++)
9297 if (vown[ind[j]][s] == faces_info[i].Elem2No)
9299 out <<
' ' << voff[ind[j]]+s+1;
9301 out <<
" 1.0 1.0 1.0 1.0\n";
9306 k = partitioning[faces_info[i].Elem1No];
9307 nv = faces[i]->GetNVertices();
9308 ind = faces[i]->GetVertices();
9310 for (j = 0; j < nv; j++)
9311 for (s = 0; s < vcount[ind[j]]; s++)
9312 if (vown[ind[j]][s] == faces_info[i].Elem1No)
9314 out <<
' ' << voff[ind[j]]+s+1;
9316 out <<
" 1.0 1.0 1.0 1.0\n";
9334 " NURBS mesh is not supported!");
9338 out <<
"MFEM mesh v1.0\n";
9342 "\n#\n# MFEM Geometry Types (see mesh/geom.hpp):\n#\n"
9347 "# TETRAHEDRON = 4\n"
9351 out <<
"\ndimension\n" << Dim
9352 <<
"\n\nelements\n" << NumOfElements <<
'\n';
9353 for (i = 0; i < NumOfElements; i++)
9355 PrintElement(elements[i], out);
9359 const int *
const i_AF_f = Aface_face.
GetI();
9360 const int *
const j_AF_f = Aface_face.
GetJ();
9362 for (
int iAF=0; iAF < Aface_face.
Size(); ++iAF)
9363 for (
const int * iface = j_AF_f + i_AF_f[iAF]; iface < j_AF_f + i_AF_f[iAF+1];
9366 out << iAF+1 <<
' ';
9367 PrintElementWithoutAttr(faces[*iface],out);
9370 out <<
"\nvertices\n" << NumOfVertices <<
'\n';
9373 out << spaceDim <<
'\n';
9374 for (i = 0; i < NumOfVertices; i++)
9376 out << vertices[i](0);
9377 for (j = 1; j < spaceDim; j++)
9379 out <<
' ' << vertices[i](j);
9396 int na = attributes.
Size();
9397 double *cg =
new double[na*spaceDim];
9398 int *nbea =
new int[na];
9400 int *vn =
new int[NumOfVertices];
9401 for (i = 0; i < NumOfVertices; i++)
9405 for (i = 0; i < na; i++)
9407 for (j = 0; j < spaceDim; j++)
9409 cg[i*spaceDim+j] = 0.0;
9414 for (i = 0; i < NumOfElements; i++)
9416 GetElementVertices(i, vert);
9417 for (k = 0; k < vert.
Size(); k++)
9423 for (i = 0; i < NumOfElements; i++)
9425 int bea = GetAttribute(i)-1;
9426 GetPointMatrix(i, pointmat);
9427 GetElementVertices(i, vert);
9429 for (k = 0; k < vert.
Size(); k++)
9430 if (vn[vert[k]] == 1)
9433 for (j = 0; j < spaceDim; j++)
9435 cg[bea*spaceDim+j] += pointmat(j,k);
9441 for (i = 0; i < NumOfElements; i++)
9443 int bea = GetAttribute(i)-1;
9444 GetElementVertices (i, vert);
9446 for (k = 0; k < vert.
Size(); k++)
9449 for (j = 0; j < spaceDim; j++)
9450 vertices[vert[k]](j) = sf*vertices[vert[k]](j) +
9451 (1-sf)*cg[bea*spaceDim+j]/nbea[bea];
9466 int na = NumOfElements;
9467 double *cg =
new double[na*spaceDim];
9468 int *nbea =
new int[na];
9470 int *vn =
new int[NumOfVertices];
9471 for (i = 0; i < NumOfVertices; i++)
9475 for (i = 0; i < na; i++)
9477 for (j = 0; j < spaceDim; j++)
9479 cg[i*spaceDim+j] = 0.0;
9484 for (i = 0; i < NumOfElements; i++)
9486 GetElementVertices(i, vert);
9487 for (k = 0; k < vert.
Size(); k++)
9493 for (i = 0; i < NumOfElements; i++)
9496 GetPointMatrix(i, pointmat);
9497 GetElementVertices(i, vert);
9499 for (k = 0; k < vert.
Size(); k++)
9500 if (vn[vert[k]] == 1)
9503 for (j = 0; j < spaceDim; j++)
9505 cg[bea*spaceDim+j] += pointmat(j,k);
9511 for (i = 0; i < NumOfElements; i++)
9514 GetElementVertices(i, vert);
9516 for (k = 0; k < vert.
Size(); k++)
9519 for (j = 0; j < spaceDim; j++)
9520 vertices[vert[k]](j) = sf*vertices[vert[k]](j) +
9521 (1-sf)*cg[bea*spaceDim+j]/nbea[bea];
9536 Vector vold(spaceDim), vnew(NULL, spaceDim);
9537 for (
int i = 0; i < vertices.Size(); i++)
9539 for (
int j = 0; j < spaceDim; j++)
9541 vold(j) = vertices[i](j);
9551 xnew.ProjectCoefficient(f_pert);
9558 MFEM_VERIFY(spaceDim == deformation.
GetVDim(),
9559 "incompatible vector dimensions");
9566 for (
int i = 0; i < NumOfVertices; i++)
9567 for (
int d = 0; d < spaceDim; d++)
9569 vertices[i](d) = xnew(d + spaceDim*i);
9582 if (NURBSext || ncmesh) {
return; }
9588 for (
int i = 0; i < GetNE(); i++)
9593 for (
int j = 0; j < nv; j++)
9598 for (
int i = 0; i < GetNBE(); i++)
9600 Element *el = GetBdrElement(i);
9603 for (
int j = 0; j < nv; j++)
9609 for (
int i = 0; i < v2v.
Size(); i++)
9613 vertices[num_vert] = vertices[i];
9614 v2v[i] = num_vert++;
9618 if (num_vert == v2v.
Size()) {
return; }
9625 for (
int i = 0; i < GetNE(); i++)
9627 Nodes->FESpace()->GetElementVDofs(i, vdofs);
9632 for (
int i = 0; i < GetNE(); i++)
9634 Nodes->FESpace()->GetElementVDofs(i, vdofs);
9635 Nodes->GetSubVector(vdofs, &nodes_by_element(s));
9639 vertices.SetSize(num_vert);
9640 NumOfVertices = num_vert;
9641 for (
int i = 0; i < GetNE(); i++)
9646 for (
int j = 0; j < nv; j++)
9651 for (
int i = 0; i < GetNBE(); i++)
9653 Element *el = GetBdrElement(i);
9656 for (
int j = 0; j < nv; j++)
9665 el_to_edge =
new Table;
9666 NumOfEdges = GetElementToEdgeTable(*el_to_edge, be_to_edge);
9671 GetElementToFaceTable();
9677 Nodes->FESpace()->Update();
9680 for (
int i = 0; i < GetNE(); i++)
9682 Nodes->FESpace()->GetElementVDofs(i, vdofs);
9683 Nodes->SetSubVector(vdofs, &nodes_by_element(s));
9691 if (NURBSext || ncmesh) {
return; }
9695 int num_bdr_elem = 0;
9696 int new_bel_to_edge_nnz = 0;
9697 for (
int i = 0; i < GetNBE(); i++)
9699 if (FaceIsInterior(GetBdrElementEdgeIndex(i)))
9701 FreeElement(boundary[i]);
9708 new_bel_to_edge_nnz += bel_to_edge->RowSize(i);
9713 if (num_bdr_elem == GetNBE()) {
return; }
9717 Table *new_bel_to_edge = NULL;
9721 new_be_to_edge.
Reserve(num_bdr_elem);
9725 new_be_to_face.
Reserve(num_bdr_elem);
9726 new_bel_to_edge =
new Table;
9727 new_bel_to_edge->
SetDims(num_bdr_elem, new_bel_to_edge_nnz);
9729 for (
int i = 0; i < GetNBE(); i++)
9731 if (!FaceIsInterior(GetBdrElementEdgeIndex(i)))
9733 new_boundary.
Append(boundary[i]);
9736 new_be_to_edge.
Append(be_to_edge[i]);
9740 int row = new_be_to_face.
Size();
9741 new_be_to_face.
Append(be_to_face[i]);
9742 int *e = bel_to_edge->GetRow(i);
9743 int ne = bel_to_edge->RowSize(i);
9744 int *new_e = new_bel_to_edge->
GetRow(row);
9745 for (
int j = 0; j < ne; j++)
9749 new_bel_to_edge->
GetI()[row+1] = new_bel_to_edge->
GetI()[row] + ne;
9754 NumOfBdrElements = new_boundary.
Size();
9765 bel_to_edge = new_bel_to_edge;
9769 for (
int i = 0; i < attribs.
Size(); i++)
9771 attribs[i] = GetBdrAttribute(i);
9775 bdr_attributes.DeleteAll();
9776 attribs.
Copy(bdr_attributes);
9781 #ifdef MFEM_USE_MEMALLOC
9787 default:
delete E;
break;
9800 if (own_nodes) {
delete Nodes; }
9806 for (i = 0; i < NumOfElements; i++)
9808 FreeElement(elements[i]);
9811 for (i = 0; i < NumOfBdrElements; i++)
9813 FreeElement(boundary[i]);
9816 for (i = 0; i < faces.Size(); i++)
9818 FreeElement(faces[i]);
9845 V(1) = s * ((ip.
y + layer) / n);
9850 V(2) = s * ((ip.
z + layer) / n);
9859 cerr <<
"Extrude1D : Not a 1D mesh!" << endl;
9863 int nvy = (closed) ? (ny) : (ny + 1);
9864 int nvt = mesh->
GetNV() * nvy;
9873 mesh2d =
new Mesh(2, nvt, mesh->
GetNE()*ny,
9878 for (
int i = 0; i < mesh->
GetNV(); i++)
9881 for (
int j = 0; j < nvy; j++)
9883 vc[1] = sy * (double(j) / ny);
9889 for (
int i = 0; i < mesh->
GetNE(); i++)
9894 for (
int j = 0; j < ny; j++)
9897 qv[0] = vert[0] * nvy + j;
9898 qv[1] = vert[1] * nvy + j;
9899 qv[2] = vert[1] * nvy + (j + 1) % nvy;
9900 qv[3] = vert[0] * nvy + (j + 1) % nvy;
9906 for (
int i = 0; i < mesh->
GetNBE(); i++)
9911 for (
int j = 0; j < ny; j++)
9914 sv[0] = vert[0] * nvy + j;
9915 sv[1] = vert[0] * nvy + (j + 1) % nvy;
9919 Swap<int>(sv[0], sv[1]);
9931 for (
int i = 0; i < mesh->
GetNE(); i++)
9937 sv[0] = vert[0] * nvy;
9938 sv[1] = vert[1] * nvy;
9942 sv[0] = vert[1] * nvy + ny;
9943 sv[1] = vert[0] * nvy + ny;
9959 string cname = name;
9960 if (cname ==
"Linear")
9964 else if (cname ==
"Quadratic")
9968 else if (cname ==
"Cubic")
9972 else if (!strncmp(name,
"H1_", 3))
9976 else if (!strncmp(name,
"L2_T", 4))
9980 else if (!strncmp(name,
"L2_", 3))
9987 cerr <<
"Extrude1D : The mesh uses unknown FE collection : "
9999 for (
int i = 0; i < mesh->
GetNE(); i++)
10002 for (
int j = ny-1; j >= 0; j--)
int GetNPoints() const
Returns the number of the points in the integration rule.
Abstract class for Finite Elements.
void AddHex(const int *vi, int attr=1)
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
int Size() const
For backward compatibility define Size to be synonym of Width()
void SetState(int s)
Change the mesh state to NORMAL, TWO_LEVEL_COARSE, TWO_LEVEL_FINE.
std::ostream & operator<<(std::ostream &out, const Mesh &mesh)
int Size() const
Logical size of the array.
void GetFaceEdges(int i, Array< int > &, Array< int > &) const
void PrintSurfaces(const Table &Aface_face, std::ostream &out) const
Print set of disjoint surfaces:
void GetPointMatrix(int i, DenseMatrix &pointmat) const
int * CartesianPartitioning(int nxyz[])
Class for integration rule.
void UpdateOrder(int Order)
Change the order of the collection.
const double * GetVertex(int i) const
Return pointer to vertex i's coordinates.
void ScaleElements(double sf)
Class for grid function - Vector with associated FE space.
int DofToVDof(int dof, int vd, int ndofs=-1) const
Table * GetEdgeVertexTable() const
Returns the edge-to-vertex Table (3D)
void GetBdrElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of bdr element i.
void FreeElement(Element *E)
void GetFaceInfos(int Face, int *Inf1, int *Inf2)
void SetVertices(const Vector &vert_coord)
virtual Element * Duplicate(Mesh *m) const =0
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
void GetEdgeVertices(int i, Array< int > &vert) const
Returns the indices of the vertices of edge i.
void METIS_PartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *)
void AddColumnsInRow(int r, int ncol)
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)
void MakeI(int nrows)
Next 7 methods are used together with the default constructor.
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void AddHexAsTets(const int *vi, int attr=1)
void GetFaceElements(int Face, int *Elem1, int *Elem2)
Array< Element * > boundary
void JacToPerfJac(int GeomType, const DenseMatrix &J, DenseMatrix &PJ) const
int * GeneratePartitioning(int nparts, int part_method=1)
void BisectTetTrans(DenseMatrix &pointmat, Tetrahedron *tet, int child)
void MoveVertices(const Vector &displacements)
void SetSize(int s)
Resizes the vector if the new size is different.
int GetNBE() const
Returns number of boundary elements.
void GetLocalPtToSegTransformation(IsoparametricTransformation &, int)
Used in GetFaceElementTransformations (...)
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void PrintWithPartitioning(int *partitioning, std::ostream &out, int elem_attr=0) const
void MakeOwner(FiniteElementCollection *_fec)
Make the GridFunction the owner of 'fec' and 'fes'.
double Det() const
Calculates the determinant of the matrix (for 2x2 or 3x3 matrices)
void NewNodes(GridFunction &nodes, bool make_owner=false)
Replace the internal node GridFunction with the given GridFunction.
Lists all edges/faces in the nonconforming mesh.
void SwapNodes(GridFunction *&nodes, int &own_nodes_)
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
void GetElementFaces(int i, Array< int > &, Array< int > &) const
Return the indices and the orientations of all faces of element i.
void SetDims(int rows, int nnz)
void DegreeElevate(int t)
void Copy(Array ©) const
Create a copy of the current array.
RefinedGeometry * Refine(int Geom, int Times, int ETimes=1)
void AddTri(const int *vi, int attr=1)
int Push(int r, int c, int f)
Piecewise-(bi)linear continuous finite elements.
Data type dense matrix using column-major storage.
int Size() const
Returns the size of the vector.
void GetRow(int i, Array< int > &row) const
Return row i in array row (the Table must be finalized)
Mesh * Extrude1D(Mesh *mesh, const int ny, const double sy, const bool closed)
Extrude a 1D mesh.
void Transform(void(*f)(const Vector &, Vector &))
int GetBdrElementEdgeIndex(int i) const
int GetNE() const
Returns number of elements.
void BisectTriTrans(DenseMatrix &pointmat, Triangle *tri, int child)
void GenerateBoundaryElements()
void DeleteCoarseTables()
void GetElementLocalToGlobal(Array< int > &lelem_elem)
ElementTransformation * GetFineElemTrans(int i, int j)
virtual void SetVertices(const int *ind)
Set the vertices according to the given input.
static int GetQuadOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
Data type quadrilateral element.
void GetVertices(Vector &vert_coord) const
virtual ~Mesh()
Destroys mesh.
void AddBdrSegment(const int *vi, int attr=1)
const IntegrationPoint & GetCenter(int GeomType)
void GetVertexLocalToGlobal(Array< int > &lvert_vert)
void CheckBdrElementOrientation(bool fix_it=true)
Check the orientation of the boundary elements.
void RemoveInternalBoundaries()
NURBSExtension * GetNURBSext()
FaceElementTransformations * GetFaceElementTransformations(int FaceNo, int mask=31)
int Size_of_connections() const
const IntegrationRule * GetVertices(int GeomType)
void FinalizeHexMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
void GetVertexToVertexTable(DSTable &) const
void MarkTriMeshForRefinement()
void skip_comment_lines(std::istream &is, const char comment_char)
int GetGeometryType() const
void DeleteAll()
Delete whole array.
void AddConnections(int r, const int *c, int nc)
int master
master number (in Mesh numbering)
Array< NCFaceInfo > nc_faces_info
Element * ReadElement(std::istream &)
void KnotInsert(Array< KnotVector * > &kv)
int GetFineElemPath(int i, int j)
Element * NewElement(int geom)
void GetEdgeTransformation(int i, IsoparametricTransformation *EdTr)
void RefineAtVertex(const Vertex &vert, int levels, double eps=0.0, int nonconforming=-1)
Refine elements sharing the specified vertex, 'levels' times.
static const int tet_faces[4][3]
ElementTransformation * GetBdrElementTransformation(int i)
Returns the transformation defining the i-th boundary element.
template void SortPairs< int, int >(Pair< int, int > *, int)
void AddVertex(const double *)
void PrintTopo(std::ostream &out, const Array< int > &e_to_k) const
int GetNumFaces() const
Return the number of faces (3D), edges (2D) or vertices (1D).
void Load(std::istream &input, int generate_edges=0, int refine=1, bool fix_orientation=true)
Piecewise-(bi)cubic continuous finite elements.
PointFiniteElement PointFE
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void GetElementJacobian(int i, DenseMatrix &J)
Data type hexahedron element.
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
void MoveNodes(const Vector &displacements)
void GetEdgeOrdering(DSTable &v_to_v, Array< int > &order)
IntegrationRules IntRules(0)
A global object with all integration rules (defined in intrules.cpp)
void FinalizeTriMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
static const int quad_orientations[8][4]
void FinalizeTetMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
void DetOfLinComb(const DenseMatrix &A, const DenseMatrix &B, Vector &c)
void AddBdrQuadAsTriangles(const int *vi, int attr=1)
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
void AddSegmentFaceElement(int lf, int gf, int el, int v0, int v1)
int local
local number within 'element'
int Append(const T &el)
Append element to array, resize if necessary.
void MarkTetMeshForRefinement()
void GetFaceTransformation(int i, IsoparametricTransformation *FTr)
void CreateRefinementFlag(int refinement_edges[2], int type, int flag=0)
void GetLocalSegToTriTransformation(IsoparametricTransformation &loc, int i)
void AddQuadFaceElement(int lf, int gf, int el, int v0, int v1, int v2, int v3)
std::vector< Master > masters
TriLinear3DFiniteElement HexahedronFE
int GetRefinementType(int i)
For a given coarse element i returns its refinement type.
void AddConnection(int r, int c)
static FiniteElement * GetTransformationFEforElementType(int)
void LoadPatchTopo(std::istream &input, Array< int > &edge_to_knot)
Read NURBS patch/macro-element mesh.
STable3D * GetElementToFaceTable(int ret_ftbl=0)
void SetCurvature(int order, bool discont=false, int space_dim=-1, int ordering=1)
void Make2D(int nx, int ny, Element::Type type, int generate_edges, double sx, double sy)
int MeshGenerator()
Truegrid or NetGen?
Type
Constants for the classes derived from Element.
void GetBdrPointMatrix(int i, DenseMatrix &pointmat) const
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
void CheckDisplacements(const Vector &displacements, double &tmax)
void CheckElementOrientation(bool fix_it=true)
Check the orientation of the elements.
NURBSExtension * StealNURBSext()
const IntegrationRule & GetNodes() const
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void Transpose(const Table &A, Table &At, int _ncols_A)
Transpose a Table.
GeometryRefiner GlobGeometryRefiner
void SetLayer(const int l)
int GetAttribute() const
Return element's attribute.
int GetElementToEdgeTable(Table &, Array< int > &)
virtual void SetVertices(const int *ind)
Set the indices the element according to the input.
int GetElementType(int i) const
Returns the type of element i.
Data type triangle element.
const Element * GetElement(int i) const
virtual void SetVertices(const int *ind)
Set the vertices according to the given input.
void GetLocalQuadToHexTransformation(IsoparametricTransformation &loc, int i)
Used in GetFaceElementTransformations (...)
void Sort()
Sorts the array. This requires operator< to be defined for T.
int GetVDim()
Returns dimension of the vector.
void SetNodalFESpace(FiniteElementSpace *nfes)
int Size() const
Returns the number of TYPE I elements.
int GetVDim() const
Returns vector dimension.
A class for non-conforming AMR on higher-order hexahedral, quadrilateral or triangular meshes...
FaceElementTransformations * GetBdrFaceTransformations(int BdrElemNo)
static const char * Name[NumGeom]
FiniteElementSpace * FESpace()
virtual void ReorientTetMesh()
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
virtual void LocalRefinement(const Array< int > &marked_el, int type=3)
This function is not public anymore. Use GeneralRefinement instead.
int METIS_SetDefaultOptions(idx_t *options)
int GetBdrElementType(int i) const
Returns the type of boundary element i.
void FindPartitioningComponents(Table &elem_elem, const Array< int > &partitioning, Array< int > &component, Array< int > &num_comp)
void GetGeckoElementReordering(Array< int > &ordering)
Data type tetrahedron element.
int GetGeomType() const
Returns the geometry type:
int GetOrdering() const
Return the ordering method.
double GetElementSize(int i, int type=0)
int SpaceDimension() const
void GetBdrElementFace(int i, int *, int *) const
Return the index and the orientation of the face of bdr element i. (3D)
void CheckPartitioning(int *partitioning)
virtual void Print(std::ostream &out=std::cout) const
Print the mesh to the given stream using the default MFEM mesh format.
void PrintElementsWithPartitioning(int *partitioning, std::ostream &out, int interior_faces=0)
void AddPointFaceElement(int lf, int gf, int el)
Used in GenerateFaces()
void Make1D(int n, double sx=1.0)
Creates a 1D mesh for the interval [0,sx] divided into n equal intervals.
double * Data() const
Returns vector of the elements.
int GetNumFineElems(int i)
bool IsSlaveFace(const FaceInfo &fi)
void Swap(Array< T > &, Array< T > &)
Array< int > bdr_attributes
virtual void NonconformingRefinement(const Array< Refinement > &refinements, int nc_limit=0)
This function is not public anymore. Use GeneralRefinement instead.
void PrintVTK(std::ostream &out)
Print the mesh in VTK format (linear and quadratic meshes only).
void SetCoarseElem(Element *ce)
MemAlloc< BisectedElement, 1024 > BEMemory
int GetBisectionHierarchy(Element *E)
int SpaceDimension() const
std::vector< Slave > slaves
Abstract finite element space.
int GetDof() const
Returns the degrees of freedom in the FE space.
void RemoveUnusedVertices()
Remove unused vertices and rebuild mesh connectivity.
static void PrintElement(const Element *, std::ostream &)
virtual void NURBSUniformRefinement()
Refine NURBS mesh.
void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *)
static void GetElementArrayEdgeTable(const Array< Element * > &elem_array, const DSTable &v_to_v, Table &el_to_edge)
void PrintCharacteristics(Vector *Vh=NULL, Vector *Vk=NULL, std::ostream &out=std::cout)
void AddAColumnInRow(int r)
void mfem_error(const char *msg)
GridFunction * GetNodes()
Return a pointer to the internal node GridFunction (may be NULL).
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
void PrepareNodeReorder(DSTable **old_v_to_v, Table **old_elem_vert)
static const int edges[12][2]
void SetSubVector(const Array< int > &dofs, const Vector &elemvect)
int FindRoots(const Vector &z, Vector &x)
void AddQuad(const int *vi, int attr=1)
int Push4(int r, int c, int f, int t)
void Save(std::ostream &out)
Prints array to stream out.
Helper struct for defining a connectivity table, see Table::MakeFromList.
virtual void QuadUniformRefinement()
Refine quadrilateral mesh.
virtual void HexUniformRefinement()
Refine hexahedral mesh.
Linear3DFiniteElement TetrahedronFE
void Swap(Mesh &other, bool non_geometry=false)
Array< Element * > elements
const Table & ElementToElementTable()
double GetLength(int i, int j) const
Return the length of the segment from node i to node j.
Linear2DFiniteElement TriangleFE
void METIS_PartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *)
virtual int * DofOrderForOrientation(int GeomType, int Or) const =0
void AddBdrTriangle(const int *vi, int attr=1)
static FiniteElementCollection * New(const char *name)
Table * GetFaceToElementTable() const
virtual void GetVertices(Array< int > &v) const
Returns the indices of the element's vertices.
void GetLocalTriToTetTransformation(IsoparametricTransformation &loc, int i)
Used in GetFaceElementTransformations (...)
NURBSExtension * NURBSext
void AddBdrQuad(const int *vi, int attr=1)
virtual const char * Name() const
const Table & ElementToFaceTable() const
Class for integration point with weight.
void RandomRefinement(int levels, int frac=2, bool aniso=false, int nonconforming=-1, int nc_limit=-1, int seed=0)
Refine each element with 1/frac probability, repeat 'levels' times.
Element * ReadElementWithoutAttr(std::istream &)
void GetElementEdges(int i, Array< int > &edges, Array< int > &cor) const
Return the indices and the orientations of all edges of element i.
void AddTriangle(const int *vi, int attr=1)
static const int hex_faces[6][4]
void GetElementTransformation(int i, IsoparametricTransformation *ElTr)
void GetLocalSegToQuadTransformation(IsoparametricTransformation &loc, int i)
const FiniteElementSpace * GetNodalFESpace()
void FinalizeQuadMesh(int generate_edges=0, int refine=0, bool fix_orientation=true)
NodeExtrudeCoefficient(const int dim, const int _n, const double _s)
void ReorderElements(const Array< int > &ordering, bool reorder_vertices=true)
void ApplySlaveTransformation(IsoparametricTransformation &transf, const FaceInfo &fi)
void Destroy()
Destroy a vector.
void FindTMax(Vector &c, Vector &x, double &tmax, const double factor, const int Dim)
const FiniteElement * GetFE(int i) const
Returns pointer to the FiniteElement associated with i'th element.
void GetMeshComponents(Array< mfem::Vertex > &vertices, Array< mfem::Element * > &elements, Array< mfem::Element * > &boundary) const
Return the basic Mesh arrays for the current finest level.
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
Array< FaceInfo > faces_info
virtual int GetNVertices() const =0
void SetAttribute(const int attr)
Set element's attribute.
void ProjectCoefficient(Coefficient &coeff)
STable3D * GetFacesTable()
Piecewise-(bi)quadratic continuous finite elements.
void Make3D(int nx, int ny, int nz, Element::Type type, int generate_edges, double sx, double sy, double sz)
static void PrintElementWithoutAttr(const Element *, std::ostream &)
int GetFineElem(int i, int j)
void DofsToVDofs(Array< int > &dofs) const
const FiniteElementCollection * FEColl() const
void GetNodes(Vector &node_coord) const
int GetFaceBaseGeometry(int i) const
void AverageVertices(int *indexes, int n, int result)
int NumberOfEntries() const
static int GetTriOrientation(const int *base, const int *test)
Returns the orientation of "test" relative to "base".
void SetNode(int i, const double *coord)
void GetNode(int i, double *coord)
Arbitrary order H1-conforming (continuous) finite elements.
void XYZ_VectorFunction(const Vector &p, Vector &v)
void GetElementColoring(Array< int > &colors, int el0=0)
void AddTet(const int *vi, int attr=1)
Table * GetFaceEdgeTable() const
Returns the face-to-edge Table (3D)
void ParseRefinementFlag(int refinement_edges[2], int &type, int &flag)
void DoNodeReorder(DSTable *old_v_to_v, Table *old_elem_vert)
void SetNodes(const Vector &node_coord)
virtual int GetRefinementFlag()
virtual int DofForGeometry(int GeomType) const =0
void SetNodalGridFunction(GridFunction *nodes, bool make_owner=false)
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void ScaleSubdomains(double sf)
virtual void PrintXG(std::ostream &out=std::cout) const
Print the mesh to the given stream using Netgen/Truegrid format.
void InitFromNCMesh(const NCMesh &ncmesh)
Initialize vertices/elements/boundary/tables from a nonconforming mesh.
void Bisection(int i, const DSTable &, int *, int *, int *)
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
BiLinear2DFiniteElement QuadrilateralFE
void GeneralRefinement(const Array< Refinement > &refinements, int nonconforming=-1, int nc_limit=0)
Abstract data type element.
int GetAttribute(int i) const
Return the attribute of element i.
void AddTriangleFaceElement(int lf, int gf, int el, int v0, int v1, int v2)
const Table & ElementToEdgeTable() const
Data type line segment element.
Linear1DFiniteElement SegmentFE
void GenerateNCFaceInfo()
double GetElementVolume(int i)
void InitMesh(int _Dim, int _spaceDim, int NVert, int NElem, int NBdrElem)
Begin construction of a mesh.
Table * GetVertexToElementTable()
The returned Table must be destroyed by the caller.
const Element * GetBdrElement(int i) const
virtual int GetType() const =0
Returns element's type.
DenseMatrix point_matrix
position within the master
void UpdateNodes()
Update the nodes of a curved mesh after refinement.
Arbitrary order "L2-conforming" discontinuous finite elements.
static const int tri_orientations[6][3]
Class used to extrude the nodes of a mesh.