13 #include "../fem/fem.hpp"
14 #include "../general/text.hpp"
20 #ifdef MFEM_USE_NETCDF
29 bool Mesh::remove_unused_vertices =
true;
31 void Mesh::ReadMFEMMesh(std::istream &input,
bool mfem_v11,
int &curved)
40 MFEM_VERIFY(ident ==
"dimension",
"invalid mesh file");
46 MFEM_VERIFY(ident ==
"elements",
"invalid mesh file");
47 input >> NumOfElements;
48 elements.SetSize(NumOfElements);
49 for (
int j = 0; j < NumOfElements; j++)
51 elements[j] = ReadElement(input);
57 MFEM_VERIFY(ident ==
"boundary",
"invalid mesh file");
58 input >> NumOfBdrElements;
59 boundary.SetSize(NumOfBdrElements);
60 for (
int j = 0; j < NumOfBdrElements; j++)
62 boundary[j] = ReadElement(input);
68 if (mfem_v11 && ident ==
"vertex_parents")
70 ncmesh =
new NCMesh(
this, &input);
76 if (ident ==
"coarse_elements")
78 ncmesh->LoadCoarseElements(input);
85 MFEM_VERIFY(ident ==
"vertices",
"invalid mesh file");
86 input >> NumOfVertices;
87 vertices.SetSize(NumOfVertices);
93 spaceDim = atoi(ident.c_str());
94 for (
int j = 0; j < NumOfVertices; j++)
96 for (
int i = 0; i < spaceDim; i++)
98 input >> vertices[j](i);
103 if (ncmesh) { ncmesh->SetVertexPositions(vertices); }
114 if (remove_unused_vertices) { RemoveUnusedVertices(); }
117 void Mesh::ReadLineMesh(std::istream &input)
123 input >> NumOfVertices;
124 vertices.SetSize(NumOfVertices);
126 for (j = 0; j < NumOfVertices; j++)
128 input >> vertices[j](0);
131 input >> NumOfElements;
132 elements.SetSize(NumOfElements);
134 for (j = 0; j < NumOfElements; j++)
136 input >> a >> p1 >> p2;
137 elements[j] =
new Segment(p1-1, p2-1, a);
141 input >> NumOfBdrElements;
142 boundary.SetSize(NumOfBdrElements);
143 for (j = 0; j < NumOfBdrElements; j++)
145 input >> a >> ind[0];
147 boundary[j] =
new Point(ind,a);
151 void Mesh::ReadNetgen2DMesh(std::istream &input,
int &curved)
153 int ints[32], attr, n;
159 input >> NumOfBdrElements;
160 boundary.SetSize(NumOfBdrElements);
161 for (
int i = 0; i < NumOfBdrElements; i++)
164 >> ints[0] >> ints[1];
165 ints[0]--; ints[1]--;
166 boundary[i] =
new Segment(ints, attr);
170 input >> NumOfElements;
171 elements.SetSize(NumOfElements);
172 for (
int i = 0; i < NumOfElements; i++)
175 for (
int j = 0; j < n; j++)
183 elements[i] =
new Segment(ints, attr);
186 elements[i] =
new Triangle(ints, attr);
197 input >> NumOfVertices;
198 vertices.SetSize(NumOfVertices);
199 for (
int i = 0; i < NumOfVertices; i++)
200 for (
int j = 0; j < Dim; j++)
202 input >> vertices[i](j);
207 input >> NumOfVertices;
208 vertices.SetSize(NumOfVertices);
213 void Mesh::ReadNetgen3DMesh(std::istream &input)
221 input >> NumOfVertices;
223 vertices.SetSize(NumOfVertices);
224 for (
int i = 0; i < NumOfVertices; i++)
225 for (
int j = 0; j < Dim; j++)
227 input >> vertices[i](j);
231 input >> NumOfElements;
232 elements.SetSize(NumOfElements);
233 for (
int i = 0; i < NumOfElements; i++)
236 for (
int j = 0; j < 4; j++)
241 #ifdef MFEM_USE_MEMALLOC
243 tet = TetMemory.Alloc();
253 input >> NumOfBdrElements;
254 boundary.SetSize(NumOfBdrElements);
255 for (
int i = 0; i < NumOfBdrElements; i++)
258 for (
int j = 0; j < 3; j++)
263 boundary[i] =
new Triangle(ints, attr);
267 void Mesh::ReadTrueGridMesh(std::istream &input)
269 int i, j, ints[32], attr;
270 const int buflen = 1024;
281 input >> vari >> NumOfVertices >> vari >> vari >> NumOfElements;
282 input.getline(buf, buflen);
283 input.getline(buf, buflen);
285 input.getline(buf, buflen);
286 input.getline(buf, buflen);
287 input.getline(buf, buflen);
290 vertices.SetSize(NumOfVertices);
291 for (i = 0; i < NumOfVertices; i++)
293 input >> vari >> varf >> vertices[i](0) >> vertices[i](1);
294 input.getline(buf, buflen);
298 elements.SetSize(NumOfElements);
299 for (i = 0; i < NumOfElements; i++)
301 input >> vari >> attr;
302 for (j = 0; j < 4; j++)
307 input.getline(buf, buflen);
308 input.getline(buf, buflen);
316 input >> vari >> NumOfVertices >> NumOfElements;
317 input.getline(buf, buflen);
318 input.getline(buf, buflen);
319 input >> vari >> vari >> NumOfBdrElements;
320 input.getline(buf, buflen);
321 input.getline(buf, buflen);
322 input.getline(buf, buflen);
324 vertices.SetSize(NumOfVertices);
325 for (i = 0; i < NumOfVertices; i++)
327 input >> vari >> varf >> vertices[i](0) >> vertices[i](1)
329 input.getline(buf, buflen);
332 elements.SetSize(NumOfElements);
333 for (i = 0; i < NumOfElements; i++)
335 input >> vari >> attr;
336 for (j = 0; j < 8; j++)
341 input.getline(buf, buflen);
345 boundary.SetSize(NumOfBdrElements);
346 for (i = 0; i < NumOfBdrElements; i++)
349 for (j = 0; j < 4; j++)
354 input.getline(buf, buflen);
361 const int Mesh::vtk_quadratic_tet[10] =
362 { 0, 1, 2, 3, 4, 7, 5, 6, 8, 9 };
366 const int Mesh::vtk_quadratic_wedge[18] =
367 { 0, 2, 1, 3, 5, 4, 8, 7, 6, 11, 10, 9, 12, 14, 13, 17, 16, 15};
370 const int Mesh::vtk_quadratic_hex[27] =
372 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
373 24, 22, 21, 23, 20, 25, 26
376 void Mesh::ReadVTKMesh(std::istream &input,
int &curved,
int &read_gf,
388 getline(input, buff);
389 getline(input, buff);
393 MFEM_ABORT(
"VTK mesh is not in ASCII format!");
396 getline(input, buff);
398 if (buff !=
"DATASET UNSTRUCTURED_GRID")
400 MFEM_ABORT(
"VTK mesh is not UNSTRUCTURED_GRID!");
411 MFEM_ABORT(
"VTK mesh does not have POINTS data!");
414 while (buff !=
"POINTS");
420 getline(input, buff);
421 for (i = 0; i < points.
Size(); i++)
428 NumOfElements = n = 0;
433 input >> NumOfElements >> n >> ws;
435 for (i = 0; i < n; i++)
437 input >> cells_data[i];
445 if (buff ==
"CELL_TYPES")
447 input >> NumOfElements;
448 elements.
SetSize(NumOfElements);
449 for (j = i = 0; i < NumOfElements; i++)
451 int ct, elem_dim, elem_order = 1;
457 elements[i] =
new Triangle(&cells_data[j+1]);
465 #ifdef MFEM_USE_MEMALLOC
466 elements[i] = TetMemory.Alloc();
467 elements[i]->SetVertices(&cells_data[j+1]);
474 elements[i] =
new Hexahedron(&cells_data[j+1]);
481 new Wedge(cells_data[j+1], cells_data[j+3], cells_data[j+2],
482 cells_data[j+4], cells_data[j+6], cells_data[j+5]);
488 elements[i] =
new Triangle(&cells_data[j+1]);
498 #ifdef MFEM_USE_MEMALLOC
499 elements[i] = TetMemory.Alloc();
500 elements[i]->SetVertices(&cells_data[j+1]);
511 new Wedge(cells_data[j+1], cells_data[j+3], cells_data[j+2],
512 cells_data[j+4], cells_data[j+6], cells_data[j+5]);
517 elements[i] =
new Hexahedron(&cells_data[j+1]);
520 MFEM_ABORT(
"VTK mesh : cell type " << ct <<
" is not supported!");
523 MFEM_VERIFY(Dim == -1 || Dim == elem_dim,
524 "elements with different dimensions are not supported");
525 MFEM_VERIFY(order == -1 || order == elem_order,
526 "elements with different orders are not supported");
529 j += cells_data[j] + 1;
534 streampos sp = input.tellg();
536 if (buff ==
"CELL_DATA")
539 getline(input, buff);
542 if (!strncmp(buff.c_str(),
"SCALARS material", 16))
544 getline(input, buff);
545 for (i = 0; i < NumOfElements; i++)
548 elements[i]->SetAttribute(attr);
565 vertices.SetSize(np);
566 for (i = 0; i < np; i++)
568 vertices[i](0) = points(3*i+0);
569 vertices[i](1) = points(3*i+1);
570 vertices[i](2) = points(3*i+2);
575 NumOfBdrElements = 0;
584 for (n = i = 0; i < NumOfElements; i++)
586 int *v = elements[i]->GetVertices();
587 int nv = elements[i]->GetNVertices();
588 for (j = 0; j < nv; j++)
589 if (pts_dof[v[j]] == -1)
595 for (n = i = 0; i < np; i++)
596 if (pts_dof[i] != -1)
601 for (i = 0; i < NumOfElements; i++)
603 int *v = elements[i]->GetVertices();
604 int nv = elements[i]->GetNVertices();
605 for (j = 0; j < nv; j++)
607 v[j] = pts_dof[v[j]];
613 for (i = 0; i < np; i++)
615 if ((j = pts_dof[i]) != -1)
617 vertices[j](0) = points(3*i+0);
618 vertices[j](1) = points(3*i+1);
619 vertices[j](2) = points(3*i+2);
624 NumOfBdrElements = 0;
629 finalize_topo =
false;
635 Nodes->MakeOwner(fec);
640 for (n = i = 0; i < NumOfElements; i++)
644 switch (elements[i]->GetGeometryType())
646 case Geometry::TRIANGLE:
647 case Geometry::SQUARE:
648 vtk_mfem = vtk_quadratic_hex;
break;
649 case Geometry::TETRAHEDRON:
650 vtk_mfem = vtk_quadratic_tet;
break;
652 vtk_mfem = vtk_quadratic_hex;
break;
653 case Geometry::PRISM:
654 vtk_mfem = vtk_quadratic_wedge;
break;
660 for (n++, j = 0; j < dofs.
Size(); j++, n++)
662 if (pts_dof[cells_data[n]] == -1)
664 pts_dof[cells_data[n]] = dofs[vtk_mfem[j]];
668 if (pts_dof[cells_data[n]] != dofs[vtk_mfem[j]])
670 MFEM_ABORT(
"VTK mesh : inconsistent quadratic mesh!");
677 for (i = 0; i < np; i++)
680 if ((dofs[0] = pts_dof[i]) != -1)
683 for (j = 0; j < dofs.
Size(); j++)
685 (*Nodes)(dofs[j]) = points(3*i+j);
694 void Mesh::ReadNURBSMesh(std::istream &input,
int &curved,
int &read_gf)
698 Dim = NURBSext->Dimension();
699 NumOfVertices = NURBSext->GetNV();
700 NumOfElements = NURBSext->GetNE();
701 NumOfBdrElements = NURBSext->GetNBE();
703 NURBSext->GetElementTopo(elements);
704 NURBSext->GetBdrElementTopo(boundary);
706 vertices.SetSize(NumOfVertices);
708 if (NURBSext->HavePatches())
714 Nodes->MakeOwner(fec);
715 NURBSext->SetCoordsFromPatches(*Nodes);
718 int vd = Nodes->VectorDim();
719 for (
int i = 0; i < vd; i++)
722 Nodes->GetNodalValues(vert_val, i+1);
723 for (
int j = 0; j < NumOfVertices; j++)
725 vertices[j](i) = vert_val(j);
735 void Mesh::ReadInlineMesh(std::istream &input,
bool generate_edges)
763 MFEM_VERIFY(input.get() ==
'=',
764 "Inline mesh expected '=' after keyword " << name);
771 else if (name ==
"ny")
775 else if (name ==
"nz")
779 else if (name ==
"sx")
783 else if (name ==
"sy")
787 else if (name ==
"sz")
791 else if (name ==
"type")
795 if (eltype ==
"segment")
797 type = Element::SEGMENT;
799 else if (eltype ==
"quad")
801 type = Element::QUADRILATERAL;
803 else if (eltype ==
"tri")
805 type = Element::TRIANGLE;
807 else if (eltype ==
"hex")
809 type = Element::HEXAHEDRON;
811 else if (eltype ==
"wedge")
813 type = Element::WEDGE;
815 else if (eltype ==
"tet")
817 type = Element::TETRAHEDRON;
821 MFEM_ABORT(
"unrecognized element type (read '" << eltype
822 <<
"') in inline mesh format. "
823 "Allowed: segment, tri, quad, tet, hex, wedge");
828 MFEM_ABORT(
"unrecognized keyword (" << name
829 <<
") in inline mesh format. "
830 "Allowed: nx, ny, nz, type, sx, sy, sz");
835 if (input.peek() ==
';')
848 if (type == Element::SEGMENT)
850 MFEM_VERIFY(nx > 0 && sx > 0.0,
851 "invalid 1D inline mesh format, all values must be "
853 <<
" nx = " << nx <<
"\n"
854 <<
" sx = " << sx <<
"\n");
857 else if (type == Element::TRIANGLE || type == Element::QUADRILATERAL)
859 MFEM_VERIFY(nx > 0 && ny > 0 && sx > 0.0 && sy > 0.0,
860 "invalid 2D inline mesh format, all values must be "
862 <<
" nx = " << nx <<
"\n"
863 <<
" ny = " << ny <<
"\n"
864 <<
" sx = " << sx <<
"\n"
865 <<
" sy = " << sy <<
"\n");
866 Make2D(nx, ny, type, sx, sy, generate_edges,
true);
868 else if (type == Element::TETRAHEDRON || type == Element::WEDGE ||
869 type == Element::HEXAHEDRON)
871 MFEM_VERIFY(nx > 0 && ny > 0 && nz > 0 &&
872 sx > 0.0 && sy > 0.0 && sz > 0.0,
873 "invalid 3D inline mesh format, all values must be "
875 <<
" nx = " << nx <<
"\n"
876 <<
" ny = " << ny <<
"\n"
877 <<
" nz = " << nz <<
"\n"
878 <<
" sx = " << sx <<
"\n"
879 <<
" sy = " << sy <<
"\n"
880 <<
" sz = " << sz <<
"\n");
881 Make3D(nx, ny, nz, type, sx, sy, sz,
true);
886 MFEM_ABORT(
"For inline mesh, must specify an element type ="
887 " [segment, tri, quad, tet, hex, wedge]");
891 void Mesh::ReadGmshMesh(std::istream &input,
int &curved,
int &read_gf)
896 input >> version >> binary >> dsize;
899 MFEM_ABORT(
"Gmsh file version < 2.2");
901 if (dsize !=
sizeof(
double))
903 MFEM_ABORT(
"Gmsh file : dsize != sizeof(double)");
905 getline(input, buff);
910 input.read(reinterpret_cast<char*>(&one),
sizeof(one));
913 MFEM_ABORT(
"Gmsh file : wrong binary format");
920 map<int, int> vertices_map;
932 double bb_tol = 1e-14;
940 bool periodic =
false;
947 while (input >> buff)
949 if (buff ==
"$Nodes")
951 input >> NumOfVertices;
952 getline(input, buff);
953 vertices.SetSize(NumOfVertices);
955 const int gmsh_dim = 3;
956 double coord[gmsh_dim];
957 for (
int ver = 0; ver < NumOfVertices; ++ver)
961 input.read(reinterpret_cast<char*>(&serial_number),
sizeof(
int));
962 input.read(reinterpret_cast<char*>(coord), gmsh_dim*
sizeof(
double));
966 input >> serial_number;
967 for (
int ci = 0; ci < gmsh_dim; ++ci)
972 vertices[ver] =
Vertex(coord, gmsh_dim);
973 vertices_map[serial_number] = ver;
975 for (
int ci = 0; ci < gmsh_dim; ++ci)
977 bb_min[ci] = (ver == 0) ? coord[ci] :
978 std::min(bb_min[ci], coord[ci]);
979 bb_max[ci] = (ver == 0) ? coord[ci] :
980 std::max(bb_max[ci], coord[ci]);
983 double bb_size = std::max(bb_max[0] - bb_min[0],
984 std::max(bb_max[1] - bb_min[1],
985 bb_max[2] - bb_min[2]));
987 if (bb_max[1] - bb_min[1] > bb_size * bb_tol)
991 if (bb_max[2] - bb_min[2] > bb_size * bb_tol)
996 if (static_cast<int>(vertices_map.size()) != NumOfVertices)
998 MFEM_ABORT(
"Gmsh file : vertices indices are not unique");
1001 else if (buff ==
"$Elements")
1003 int num_of_all_elements;
1004 input >> num_of_all_elements;
1006 getline(input, buff);
1009 int type_of_element;
1017 int nodes_of_gmsh_element[] =
1166 -1,-1,-1,-1,-1,-1,-1,
1182 -1,-1,-1,-1,-1,-1,-1,
1227 int lin3[] = {0,2,1};
1228 int lin4[] = {0,2,3,1};
1229 int tri6[] = {0,3,1,5,4,2};
1230 int tri10[] = {0,3,4,1,8,9,5,7,6,2};
1231 int quad9[] = {0,4,1,7,8,5,3,6,2};
1232 int quad16[] = {0,4,5,1,11,12,13,6,
1235 int tet10[] {0,4,1,6,5,2,7,9,8,3};
1236 int tet20[] = {0,4,5,1,9,16,6,8,7,2,
1237 11,17,15,18,19,13,10,14,12,3
1239 int hex27[] {0,8,1,9,20,11,3,13,2,
1240 10,21,12,22,26,23,15,24,14,
1241 4,16,5,17,25,18,7,19,6
1243 int hex64[] {0,8,9,1,10,32,35,14,
1244 11,33,34,15,3,19,18,2,
1245 12,36,37,16,40,56,57,44,
1246 43,59,58,45,22,49,48,20,
1247 13,39,38,17,41,60,61,47,
1248 42,63,62,46,23,50,51,21,
1249 4,24,25,5,26,52,53,28,
1250 27,55,54,29,7,31,30,6
1253 int wdg18[] = {0,6,1,7,9,2,8,15,10,
1254 16,17,11,3,12,4,13,14,5
1256 int wdg40[] = {0,6,7,1,8,24,12,9,13,2,
1257 10,26,27,14,30,38,34,33,35,16,
1258 11,29,28,15,31,39,37,32,36,17,
1259 3,18,19,4,20,25,22,21,23,5
1262 int pyr14[] = {0,5,1,6,13,8,3,
1265 int pyr30[] = {0,5,6,1,7,25,28,11,8,26,
1266 27,12,3,16,15,2,9,21,13,22,
1267 29,23,19,24,17,10,14,20,18,4
1270 vector<Element*> elements_0D, elements_1D, elements_2D, elements_3D;
1271 elements_0D.reserve(num_of_all_elements);
1272 elements_1D.reserve(num_of_all_elements);
1273 elements_2D.reserve(num_of_all_elements);
1274 elements_3D.reserve(num_of_all_elements);
1277 vector<Array<int>*> ho_verts_1D, ho_verts_2D, ho_verts_3D;
1278 ho_verts_1D.reserve(num_of_all_elements);
1279 ho_verts_2D.reserve(num_of_all_elements);
1280 ho_verts_3D.reserve(num_of_all_elements);
1283 vector<int> ho_el_order_1D, ho_el_order_2D, ho_el_order_3D;
1284 ho_el_order_1D.reserve(num_of_all_elements);
1285 ho_el_order_2D.reserve(num_of_all_elements);
1286 ho_el_order_3D.reserve(num_of_all_elements);
1298 ho_lin[2] = lin3; ho_lin[3] = lin4;
1299 ho_tri[2] = tri6; ho_tri[3] = tri10;
1300 ho_sqr[2] = quad9; ho_sqr[3] = quad16;
1301 ho_tet[2] = tet10; ho_tet[3] = tet20;
1302 ho_hex[2] = hex27; ho_hex[3] = hex64;
1303 ho_wdg[2] = wdg18; ho_wdg[3] = wdg40;
1304 ho_pyr[2] = pyr14; ho_pyr[3] = pyr30;
1308 int n_elem_part = 0;
1309 const int header_size = 3;
1312 int header[header_size];
1313 int n_elem_one_type;
1315 while (n_elem_part < num_of_all_elements)
1317 input.read(reinterpret_cast<char*>(header),
1318 header_size*
sizeof(
int));
1319 type_of_element = header[0];
1320 n_elem_one_type = header[1];
1323 n_elem_part += n_elem_one_type;
1325 const int n_elem_nodes = nodes_of_gmsh_element[type_of_element-1];
1326 vector<int> data(1+n_tags+n_elem_nodes);
1327 for (
int el = 0; el < n_elem_one_type; ++el)
1329 input.read(reinterpret_cast<char*>(&data[0]),
1330 data.size()*
sizeof(int));
1332 serial_number = data[dd++];
1335 phys_domain = (n_tags > 0) ? data[dd++] : 1;
1338 elem_domain = (n_tags > 1) ? data[dd++] : 0;
1341 n_partitions = (n_tags > 2) ? data[dd++] : 0;
1344 vector<int> vert_indices(n_elem_nodes);
1345 for (
int vi = 0; vi < n_elem_nodes; ++vi)
1347 map<int, int>::const_iterator it =
1348 vertices_map.find(data[1+n_tags+vi]);
1349 if (it == vertices_map.end())
1351 MFEM_ABORT(
"Gmsh file : vertex index doesn't exist");
1353 vert_indices[vi] = it->second;
1357 if (phys_domain <= 0)
1359 MFEM_ABORT(
"Non-positive element attribute in Gmsh mesh!");
1364 switch (type_of_element)
1377 elements_1D.push_back(
1378 new Segment(&vert_indices[0], phys_domain));
1379 if (type_of_element != 1)
1381 el_order = n_elem_nodes - 1;
1383 hov->
Append(&vert_indices[0], n_elem_nodes);
1384 ho_verts_1D.push_back(hov);
1385 ho_el_order_1D.push_back(el_order);
1391 case 21: el_order--;
1392 case 23: el_order--;
1393 case 25: el_order--;
1394 case 42: el_order--;
1395 case 43: el_order--;
1396 case 44: el_order--;
1397 case 45: el_order--;
1398 case 46: el_order--;
1400 elements_2D.push_back(
1401 new Triangle(&vert_indices[0], phys_domain));
1405 hov->
Append(&vert_indices[0], n_elem_nodes);
1406 ho_verts_2D.push_back(hov);
1407 ho_el_order_2D.push_back(el_order);
1412 case 10: el_order--;
1413 case 36: el_order--;
1414 case 37: el_order--;
1415 case 38: el_order--;
1416 case 47: el_order--;
1417 case 48: el_order--;
1418 case 49: el_order--;
1419 case 50: el_order--;
1420 case 51: el_order--;
1422 elements_2D.push_back(
1427 hov->
Append(&vert_indices[0], n_elem_nodes);
1428 ho_verts_2D.push_back(hov);
1429 ho_el_order_2D.push_back(el_order);
1434 case 11: el_order--;
1435 case 29: el_order--;
1436 case 30: el_order--;
1437 case 31: el_order--;
1438 case 71: el_order--;
1439 case 72: el_order--;
1440 case 73: el_order--;
1441 case 74: el_order--;
1442 case 75: el_order--;
1444 #ifdef MFEM_USE_MEMALLOC
1445 elements_3D.push_back(TetMemory.Alloc());
1446 elements_3D.back()->SetVertices(&vert_indices[0]);
1447 elements_3D.back()->SetAttribute(phys_domain);
1449 elements_3D.push_back(
1455 hov->
Append(&vert_indices[0], n_elem_nodes);
1456 ho_verts_3D.push_back(hov);
1457 ho_el_order_3D.push_back(el_order);
1462 case 12: el_order--;
1463 case 92: el_order--;
1464 case 93: el_order--;
1465 case 94: el_order--;
1466 case 95: el_order--;
1467 case 96: el_order--;
1468 case 97: el_order--;
1469 case 98: el_order--;
1472 elements_3D.push_back(
1473 new Hexahedron(&vert_indices[0], phys_domain));
1477 hov->
Append(&vert_indices[0], n_elem_nodes);
1478 ho_verts_3D.push_back(hov);
1479 ho_el_order_3D.push_back(el_order);
1484 case 13: el_order--;
1485 case 90: el_order--;
1486 case 91: el_order--;
1487 case 106: el_order--;
1488 case 107: el_order--;
1489 case 108: el_order--;
1490 case 109: el_order--;
1491 case 110: el_order--;
1494 elements_3D.push_back(
1495 new Wedge(&vert_indices[0], phys_domain));
1499 hov->
Append(&vert_indices[0], n_elem_nodes);
1500 ho_verts_3D.push_back(hov);
1501 ho_el_order_3D.push_back(el_order);
1532 elements_0D.push_back(
1533 new Point(&vert_indices[0], phys_domain));
1537 MFEM_WARNING(
"Unsupported Gmsh element type.");
1546 for (
int el = 0; el < num_of_all_elements; ++el)
1548 input >> serial_number >> type_of_element >> n_tags;
1549 vector<int> data(n_tags);
1550 for (
int i = 0; i < n_tags; ++i) { input >> data[i]; }
1553 phys_domain = (n_tags > 0) ? data[0] : 1;
1556 elem_domain = (n_tags > 1) ? data[1] : 0;
1559 n_partitions = (n_tags > 2) ? data[2] : 0;
1562 const int n_elem_nodes = nodes_of_gmsh_element[type_of_element-1];
1563 vector<int> vert_indices(n_elem_nodes);
1565 for (
int vi = 0; vi < n_elem_nodes; ++vi)
1568 map<int, int>::const_iterator it = vertices_map.find(index);
1569 if (it == vertices_map.end())
1571 MFEM_ABORT(
"Gmsh file : vertex index doesn't exist");
1573 vert_indices[vi] = it->second;
1577 if (phys_domain <= 0)
1579 MFEM_ABORT(
"Non-positive element attribute in Gmsh mesh!");
1584 switch (type_of_element)
1597 elements_1D.push_back(
1598 new Segment(&vert_indices[0], phys_domain));
1599 if (type_of_element != 1)
1602 hov->
Append(&vert_indices[0], n_elem_nodes);
1603 ho_verts_1D.push_back(hov);
1604 el_order = n_elem_nodes - 1;
1605 ho_el_order_1D.push_back(el_order);
1611 case 21: el_order--;
1612 case 23: el_order--;
1613 case 25: el_order--;
1614 case 42: el_order--;
1615 case 43: el_order--;
1616 case 44: el_order--;
1617 case 45: el_order--;
1618 case 46: el_order--;
1620 elements_2D.push_back(
1621 new Triangle(&vert_indices[0], phys_domain));
1625 hov->
Append(&vert_indices[0], n_elem_nodes);
1626 ho_verts_2D.push_back(hov);
1627 ho_el_order_2D.push_back(el_order);
1632 case 10: el_order--;
1633 case 36: el_order--;
1634 case 37: el_order--;
1635 case 38: el_order--;
1636 case 47: el_order--;
1637 case 48: el_order--;
1638 case 49: el_order--;
1639 case 50: el_order--;
1640 case 51: el_order--;
1642 elements_2D.push_back(
1647 hov->
Append(&vert_indices[0], n_elem_nodes);
1648 ho_verts_2D.push_back(hov);
1649 ho_el_order_2D.push_back(el_order);
1654 case 11: el_order--;
1655 case 29: el_order--;
1656 case 30: el_order--;
1657 case 31: el_order--;
1658 case 71: el_order--;
1659 case 72: el_order--;
1660 case 73: el_order--;
1661 case 74: el_order--;
1662 case 75: el_order--;
1664 #ifdef MFEM_USE_MEMALLOC
1665 elements_3D.push_back(TetMemory.Alloc());
1666 elements_3D.back()->SetVertices(&vert_indices[0]);
1667 elements_3D.back()->SetAttribute(phys_domain);
1669 elements_3D.push_back(
1675 hov->
Append(&vert_indices[0], n_elem_nodes);
1676 ho_verts_3D.push_back(hov);
1677 ho_el_order_3D.push_back(el_order);
1682 case 12: el_order--;
1683 case 92: el_order--;
1684 case 93: el_order--;
1685 case 94: el_order--;
1686 case 95: el_order--;
1687 case 96: el_order--;
1688 case 97: el_order--;
1689 case 98: el_order--;
1692 elements_3D.push_back(
1693 new Hexahedron(&vert_indices[0], phys_domain));
1697 hov->
Append(&vert_indices[0], n_elem_nodes);
1698 ho_verts_3D.push_back(hov);
1699 ho_el_order_3D.push_back(el_order);
1704 case 13: el_order--;
1705 case 90: el_order--;
1706 case 91: el_order--;
1707 case 106: el_order--;
1708 case 107: el_order--;
1709 case 108: el_order--;
1710 case 109: el_order--;
1711 case 110: el_order--;
1714 elements_3D.push_back(
1715 new Wedge(&vert_indices[0], phys_domain));
1719 hov->
Append(&vert_indices[0], n_elem_nodes);
1720 ho_verts_3D.push_back(hov);
1721 ho_el_order_3D.push_back(el_order);
1752 elements_0D.push_back(
1753 new Point(&vert_indices[0], phys_domain));
1757 MFEM_WARNING(
"Unsupported Gmsh element type.");
1764 if (!elements_3D.empty())
1767 NumOfElements = elements_3D.size();
1768 elements.SetSize(NumOfElements);
1769 for (
int el = 0; el < NumOfElements; ++el)
1771 elements[el] = elements_3D[el];
1773 NumOfBdrElements = elements_2D.size();
1774 boundary.SetSize(NumOfBdrElements);
1775 for (
int el = 0; el < NumOfBdrElements; ++el)
1777 boundary[el] = elements_2D[el];
1779 for (
size_t el = 0; el < ho_el_order_3D.size(); el++)
1781 mesh_order = max(mesh_order, ho_el_order_3D[el]);
1784 for (
size_t el = 0; el < elements_1D.size(); ++el)
1786 delete elements_1D[el];
1788 for (
size_t el = 0; el < elements_0D.size(); ++el)
1790 delete elements_0D[el];
1793 else if (!elements_2D.empty())
1796 NumOfElements = elements_2D.size();
1797 elements.SetSize(NumOfElements);
1798 for (
int el = 0; el < NumOfElements; ++el)
1800 elements[el] = elements_2D[el];
1802 NumOfBdrElements = elements_1D.size();
1803 boundary.SetSize(NumOfBdrElements);
1804 for (
int el = 0; el < NumOfBdrElements; ++el)
1806 boundary[el] = elements_1D[el];
1808 for (
size_t el = 0; el < ho_el_order_2D.size(); el++)
1810 mesh_order = max(mesh_order, ho_el_order_2D[el]);
1813 for (
size_t el = 0; el < elements_0D.size(); ++el)
1815 delete elements_0D[el];
1818 else if (!elements_1D.empty())
1821 NumOfElements = elements_1D.size();
1822 elements.SetSize(NumOfElements);
1823 for (
int el = 0; el < NumOfElements; ++el)
1825 elements[el] = elements_1D[el];
1827 NumOfBdrElements = elements_0D.size();
1828 boundary.SetSize(NumOfBdrElements);
1829 for (
int el = 0; el < NumOfBdrElements; ++el)
1831 boundary[el] = elements_0D[el];
1833 for (
size_t el = 0; el < ho_el_order_1D.size(); el++)
1835 mesh_order = max(mesh_order, ho_el_order_1D[el]);
1840 MFEM_ABORT(
"Gmsh file : no elements found");
1853 BasisType::ClosedUniform);
1861 for (
int el = 0; el < NumOfElements; el++)
1863 const int * vm = NULL;
1865 switch (GetElementType(el))
1867 case Element::SEGMENT:
1868 ho_verts = ho_verts_1D[el];
1869 el_order = ho_el_order_1D[el];
1870 if (!ho_lin[el_order])
1872 ho_lin[el_order] =
new int[ho_verts->
Size()];
1875 vm = ho_lin[el_order];
1877 case Element::TRIANGLE:
1878 ho_verts = ho_verts_2D[el];
1879 el_order = ho_el_order_2D[el];
1880 if (!ho_tri[el_order])
1882 ho_tri[el_order] =
new int[ho_verts->
Size()];
1885 vm = ho_tri[el_order];
1887 case Element::QUADRILATERAL:
1888 ho_verts = ho_verts_2D[el];
1889 el_order = ho_el_order_2D[el];
1890 if (!ho_sqr[el_order])
1892 ho_sqr[el_order] =
new int[ho_verts->
Size()];
1895 vm = ho_sqr[el_order];
1897 case Element::TETRAHEDRON:
1898 ho_verts = ho_verts_3D[el];
1899 el_order = ho_el_order_3D[el];
1900 if (!ho_tet[el_order])
1902 ho_tet[el_order] =
new int[ho_verts->
Size()];
1905 vm = ho_tet[el_order];
1907 case Element::HEXAHEDRON:
1908 ho_verts = ho_verts_3D[el];
1909 el_order = ho_el_order_3D[el];
1910 if (!ho_hex[el_order])
1912 ho_hex[el_order] =
new int[ho_verts->
Size()];
1915 vm = ho_hex[el_order];
1917 case Element::WEDGE:
1918 ho_verts = ho_verts_3D[el];
1919 el_order = ho_el_order_3D[el];
1920 if (!ho_wdg[el_order])
1922 ho_wdg[el_order] =
new int[ho_verts->
Size()];
1925 vm = ho_wdg[el_order];
1938 MFEM_WARNING(
"Unsupported Gmsh element type.");
1941 int nv = (ho_verts) ? ho_verts->
Size() : 0;
1943 for (
int v = 0; v<nv; v++)
1945 double * c = GetVertex((*ho_verts)[vm[v]]);
1946 for (
int d=0; d<spaceDim; d++)
1948 Nodes_gf(spaceDim * (o + v) + d) = c[d];
1956 for (
size_t el=0; el<ho_verts_1D.size(); el++)
1958 delete ho_verts_1D[el];
1960 for (
size_t el=0; el<ho_verts_2D.size(); el++)
1962 delete ho_verts_2D[el];
1964 for (
size_t el=0; el<ho_verts_3D.size(); el++)
1966 delete ho_verts_3D[el];
1970 for (
int ord=4; ord<ho_lin.
Size(); ord++)
1972 if (ho_lin[ord] != NULL) {
delete [] ho_lin[ord]; }
1974 for (
int ord=4; ord<ho_tri.
Size(); ord++)
1976 if (ho_tri[ord] != NULL) {
delete [] ho_tri[ord]; }
1978 for (
int ord=4; ord<ho_sqr.
Size(); ord++)
1980 if (ho_sqr[ord] != NULL) {
delete [] ho_sqr[ord]; }
1982 for (
int ord=4; ord<ho_tet.
Size(); ord++)
1984 if (ho_tet[ord] != NULL) {
delete [] ho_tet[ord]; }
1986 for (
int ord=4; ord<ho_hex.
Size(); ord++)
1988 if (ho_hex[ord] != NULL) {
delete [] ho_hex[ord]; }
1990 for (
int ord=4; ord<ho_wdg.
Size(); ord++)
1992 if (ho_wdg[ord] != NULL) {
delete [] ho_wdg[ord]; }
1994 for (
int ord=4; ord<ho_pyr.
Size(); ord++)
1996 if (ho_pyr[ord] != NULL) {
delete [] ho_pyr[ord]; }
1999 MFEM_CONTRACT_VAR(n_partitions);
2000 MFEM_CONTRACT_VAR(elem_domain);
2003 else if (buff ==
"$Periodic")
2010 for (
int i = 0; i < v2v.
Size(); i++)
2017 input >> num_per_ent;
2018 getline(input, buff);
2019 for (
int i = 0; i < num_per_ent; i++)
2021 getline(input, buff);
2022 getline(input, buff);
2025 for (
int j=0; j<num_nodes; j++)
2027 input >> slave >> master;
2028 v2v[slave - 1] = master - 1;
2030 getline(input, buff);
2034 if (mesh_order == 1)
2036 this->SetCurvature(1,
true, spaceDim, Ordering::byVDIM);
2041 for (
int i = 0; i < this->GetNE(); i++)
2043 Element *el = this->GetElement(i);
2046 for (
int j = 0; j < nv; j++)
2053 for (
int i = 0; i < this->GetNBE(); i++)
2055 Element *el = this->GetBdrElement(i);
2058 for (
int j = 0; j < nv; j++)
2066 this->RemoveUnusedVertices();
2069 this->RemoveInternalBoundaries();
2071 this->FinalizeTopology();
2076 SetCurvature(mesh_order, periodic, spaceDim, Ordering::byVDIM);
2079 Nodes->ProjectCoefficient(NodesCoef);
2084 #ifdef MFEM_USE_NETCDF
2085 void Mesh::ReadCubit(
const char *filename,
int &curved,
int &read_gf)
2092 const int sideMapTri3[3][2] =
2099 const int sideMapQuad4[4][2] =
2107 const int sideMapTri6[3][3] =
2114 const int sideMapQuad9[4][3] =
2122 const int sideMapTet4[4][3] =
2130 const int sideMapTet10[4][6] =
2138 const int sideMapHex8[6][4] =
2148 const int sideMapHex27[6][9] =
2150 {1,2,6,5,9,14,17,13,26},
2151 {2,3,7,6,10,15,18,14,25},
2152 {4,3,7,8,11,15,19,16,27},
2153 {1,4,8,5,12,16,20,13,24},
2154 {1,4,3,2,12,11,10,9,22},
2155 {5,8,7,6,20,19,18,17,23}
2160 const int mfemToGenesisTet10[10] = {1,2,3,4,5,7,8,6,9,10};
2163 const int mfemToGenesisHex27[27] = {1,2,3,4,5,6,7,8,9,10,11,
2165 12,17,18,19,20,13,14,15,
2167 16,22,26,25,27,24,23,21
2170 const int mfemToGenesisTri6[6] = {1,2,3,4,5,6};
2171 const int mfemToGenesisQuad9[9] = {1,2,3,4,5,6,7,8,9};
2178 char str_dummy[256];
2185 if ((retval = nc_open(filename, NC_NOWRITE, &ncid)))
2187 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2193 size_t num_dim=0, num_nodes=0, num_elem=0, num_el_blk=0, num_side_sets=0;
2195 if ((retval = nc_inq_dimid(ncid,
"num_dim", &
id)) ||
2196 (retval = nc_inq_dim(ncid,
id, str_dummy, &num_dim)) ||
2198 (retval = nc_inq_dimid(ncid,
"num_nodes", &
id)) ||
2199 (retval = nc_inq_dim(ncid,
id, str_dummy, &num_nodes)) ||
2201 (retval = nc_inq_dimid(ncid,
"num_elem", &
id)) ||
2202 (retval = nc_inq_dim(ncid,
id, str_dummy, &num_elem)) ||
2204 (retval = nc_inq_dimid(ncid,
"num_el_blk", &
id)) ||
2205 (retval = nc_inq_dim(ncid,
id, str_dummy, &num_el_blk)))
2207 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2209 if ((retval = nc_inq_dimid(ncid,
"num_side_sets", &
id)) ||
2210 (retval = nc_inq_dim(ncid,
id, str_dummy, &num_side_sets)))
2218 size_t *num_el_in_blk =
new size_t[num_el_blk];
2219 size_t num_node_per_el;
2221 int previous_num_node_per_el = 0;
2222 for (
int i = 0; i < (int) num_el_blk; i++)
2224 sprintf(temp_str,
"num_el_in_blk%d", i+1);
2225 if ((retval = nc_inq_dimid(ncid, temp_str, &temp_id)) ||
2226 (retval = nc_inq_dim(ncid, temp_id, str_dummy, &num_el_in_blk[i])))
2228 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2231 sprintf(temp_str,
"num_nod_per_el%d", i+1);
2232 if ((retval = nc_inq_dimid(ncid, temp_str, &temp_id)) ||
2233 (retval = nc_inq_dim(ncid, temp_id, str_dummy, &num_node_per_el)))
2235 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2242 if ((
int) num_node_per_el != previous_num_node_per_el)
2244 MFEM_ABORT(
"Element blocks of different element types not supported");
2247 previous_num_node_per_el = num_node_per_el;
2251 enum CubitElementType
2273 CubitElementType cubit_element_type = ELEMENT_TRI3;
2274 CubitFaceType cubit_face_type = FACE_EDGE2;
2275 int num_element_linear_nodes = 0;
2279 switch (num_node_per_el)
2283 cubit_element_type = ELEMENT_TRI3;
2284 cubit_face_type = FACE_EDGE2;
2285 num_element_linear_nodes = 3;
2290 cubit_element_type = ELEMENT_TRI6;
2291 cubit_face_type = FACE_EDGE3;
2292 num_element_linear_nodes = 3;
2297 cubit_element_type = ELEMENT_QUAD4;
2298 cubit_face_type = FACE_EDGE2;
2299 num_element_linear_nodes = 4;
2304 cubit_element_type = ELEMENT_QUAD9;
2305 cubit_face_type = FACE_EDGE3;
2306 num_element_linear_nodes = 4;
2311 MFEM_ABORT(
"Don't know what to do with a " << num_node_per_el <<
2312 " node 2D element\n");
2316 else if (num_dim == 3)
2318 switch (num_node_per_el)
2322 cubit_element_type = ELEMENT_TET4;
2323 cubit_face_type = FACE_TRI3;
2324 num_element_linear_nodes = 4;
2329 cubit_element_type = ELEMENT_TET10;
2330 cubit_face_type = FACE_TRI6;
2331 num_element_linear_nodes = 4;
2336 cubit_element_type = ELEMENT_HEX8;
2337 cubit_face_type = FACE_QUAD4;
2338 num_element_linear_nodes = 8;
2343 cubit_element_type = ELEMENT_HEX27;
2344 cubit_face_type = FACE_QUAD9;
2345 num_element_linear_nodes = 8;
2350 MFEM_ABORT(
"Don't know what to do with a " << num_node_per_el <<
2351 " node 3D element\n");
2357 MFEM_ABORT(
"Invalid dimension: num_dim = " << num_dim);
2362 if (cubit_element_type == ELEMENT_TRI3 || cubit_element_type == ELEMENT_QUAD4 ||
2363 cubit_element_type == ELEMENT_TET4 || cubit_element_type == ELEMENT_HEX8)
2367 else if (cubit_element_type == ELEMENT_TRI6 ||
2368 cubit_element_type == ELEMENT_QUAD9 ||
2369 cubit_element_type == ELEMENT_TET10 || cubit_element_type == ELEMENT_HEX27)
2375 size_t *num_side_in_ss =
new size_t[num_side_sets];
2376 for (
int i = 0; i < (int) num_side_sets; i++)
2378 sprintf(temp_str,
"num_side_ss%d", i+1);
2379 if ((retval = nc_inq_dimid(ncid, temp_str, &temp_id)) ||
2380 (retval = nc_inq_dim(ncid, temp_id, str_dummy, &num_side_in_ss[i])))
2382 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2387 double *coordx =
new double[num_nodes];
2388 double *coordy =
new double[num_nodes];
2389 double *coordz =
new double[num_nodes];
2391 if ((retval = nc_inq_varid(ncid,
"coordx", &
id)) ||
2392 (retval = nc_get_var_double(ncid,
id, coordx)) ||
2393 (retval = nc_inq_varid(ncid,
"coordy", &
id)) ||
2394 (retval = nc_get_var_double(ncid,
id, coordy)))
2396 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2401 if ((retval = nc_inq_varid(ncid,
"coordz", &
id)) ||
2402 (retval = nc_get_var_double(ncid,
id, coordz)))
2404 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2409 int **elem_blk =
new int*[num_el_blk];
2410 for (
int i = 0; i < (int) num_el_blk; i++)
2412 elem_blk[i] =
new int[num_el_in_blk[i] * num_node_per_el];
2413 sprintf(temp_str,
"connect%d", i+1);
2414 if ((retval = nc_inq_varid(ncid, temp_str, &temp_id)) ||
2415 (retval = nc_get_var_int(ncid, temp_id, elem_blk[i])))
2417 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2420 int *ebprop =
new int[num_el_blk];
2421 if ((retval = nc_inq_varid(ncid,
"eb_prop1", &
id)) ||
2422 (retval = nc_get_var_int(ncid,
id, ebprop)))
2424 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2429 int **elem_ss =
new int*[num_side_sets];
2430 int **side_ss =
new int*[num_side_sets];
2432 for (
int i = 0; i < (int) num_side_sets; i++)
2434 elem_ss[i] =
new int[num_side_in_ss[i]];
2435 side_ss[i] =
new int[num_side_in_ss[i]];
2437 sprintf(temp_str,
"elem_ss%d", i+1);
2438 if ((retval = nc_inq_varid(ncid, temp_str, &temp_id)) ||
2439 (retval = nc_get_var_int(ncid, temp_id, elem_ss[i])))
2441 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2444 sprintf(temp_str,
"side_ss%d",i+1);
2445 if ((retval = nc_inq_varid(ncid, temp_str, &temp_id)) ||
2446 (retval = nc_get_var_int(ncid, temp_id, side_ss[i])))
2448 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2452 int *ssprop =
new int[num_side_sets];
2453 if ((num_side_sets > 0) &&
2454 ((retval = nc_inq_varid(ncid,
"ss_prop1", &
id)) ||
2455 (retval = nc_get_var_int(ncid,
id, ssprop))))
2457 MFEM_ABORT(
"Fatal NetCDF error: " << nc_strerror(retval));
2463 int num_face_nodes = 0;
2464 int num_face_linear_nodes = 0;
2466 switch (cubit_face_type)
2471 num_face_linear_nodes = 2;
2477 num_face_linear_nodes = 2;
2483 num_face_linear_nodes = 3;
2489 num_face_linear_nodes = 3;
2495 num_face_linear_nodes = 4;
2501 num_face_linear_nodes = 4;
2508 int *start_of_block =
new int[num_el_blk+1];
2509 start_of_block[0] = 0;
2510 for (
int i = 1; i < (int) num_el_blk+1; i++)
2512 start_of_block[i] = start_of_block[i-1] + num_el_in_blk[i-1];
2515 int **ss_node_id =
new int*[num_side_sets];
2517 for (
int i = 0; i < (int) num_side_sets; i++)
2519 ss_node_id[i] =
new int[num_side_in_ss[i]*num_face_nodes];
2520 for (
int j = 0; j < (int) num_side_in_ss[i]; j++)
2522 int glob_ind = elem_ss[i][j]-1;
2525 while (iblk < (
int) num_el_blk && glob_ind >= start_of_block[iblk+1])
2529 if (iblk >= (
int) num_el_blk)
2531 MFEM_ABORT(
"Sideset element does not exist");
2533 loc_ind = glob_ind - start_of_block[iblk];
2534 int this_side = side_ss[i][j];
2535 int ielem = loc_ind*num_node_per_el;
2537 for (
int k = 0; k < num_face_nodes; k++)
2540 switch (cubit_element_type)
2542 case (ELEMENT_TRI3):
2544 inode = sideMapTri3[this_side-1][k];
2547 case (ELEMENT_TRI6):
2549 inode = sideMapTri6[this_side-1][k];
2552 case (ELEMENT_QUAD4):
2554 inode = sideMapQuad4[this_side-1][k];
2557 case (ELEMENT_QUAD9):
2559 inode = sideMapQuad9[this_side-1][k];
2562 case (ELEMENT_TET4):
2564 inode = sideMapTet4[this_side-1][k];
2567 case (ELEMENT_TET10):
2569 inode = sideMapTet10[this_side-1][k];
2572 case (ELEMENT_HEX8):
2574 inode = sideMapHex8[this_side-1][k];
2577 case (ELEMENT_HEX27):
2579 inode = sideMapHex27[this_side-1][k];
2583 ss_node_id[i][j*num_face_nodes+k] =
2584 elem_blk[iblk][ielem + inode - 1];
2590 std::vector<int> uniqueVertexID;
2592 for (
int iblk = 0; iblk < (int) num_el_blk; iblk++)
2594 for (
int i = 0; i < (int) num_el_in_blk[iblk]; i++)
2596 for (
int j = 0; j < num_element_linear_nodes; j++)
2598 uniqueVertexID.push_back(elem_blk[iblk][i*num_node_per_el + j]);
2602 std::sort(uniqueVertexID.begin(), uniqueVertexID.end());
2603 std::vector<int>::iterator newEnd;
2604 newEnd = std::unique(uniqueVertexID.begin(), uniqueVertexID.end());
2605 uniqueVertexID.resize(std::distance(uniqueVertexID.begin(), newEnd));
2611 std::map<int,int> cubitToMFEMVertMap;
2612 for (
int i = 0; i < (int) uniqueVertexID.size(); i++)
2614 cubitToMFEMVertMap[uniqueVertexID[i]] = i+1;
2616 MFEM_ASSERT(cubitToMFEMVertMap.size() == uniqueVertexID.size(),
2617 "This should never happen\n");
2623 NumOfVertices = uniqueVertexID.size();
2624 vertices.SetSize(NumOfVertices);
2625 for (
int i = 0; i < (int) uniqueVertexID.size(); i++)
2627 vertices[i](0) = coordx[uniqueVertexID[i] - 1];
2628 vertices[i](1) = coordy[uniqueVertexID[i] - 1];
2631 vertices[i](2) = coordz[uniqueVertexID[i] - 1];
2635 NumOfElements = num_elem;
2636 elements.SetSize(num_elem);
2638 int renumberedVertID[8];
2639 for (
int iblk = 0; iblk < (int) num_el_blk; iblk++)
2641 int NumNodePerEl = num_node_per_el;
2642 for (
int i = 0; i < (int) num_el_in_blk[iblk]; i++)
2644 for (
int j = 0; j < num_element_linear_nodes; j++)
2646 renumberedVertID[j] =
2647 cubitToMFEMVertMap[elem_blk[iblk][i*NumNodePerEl+j]]-1;
2650 switch (cubit_element_type)
2652 case (ELEMENT_TRI3):
2653 case (ELEMENT_TRI6):
2655 elements[elcount] =
new Triangle(renumberedVertID,ebprop[iblk]);
2658 case (ELEMENT_QUAD4):
2659 case (ELEMENT_QUAD9):
2661 elements[elcount] =
new Quadrilateral(renumberedVertID,ebprop[iblk]);
2664 case (ELEMENT_TET4):
2665 case (ELEMENT_TET10):
2667 #ifdef MFEM_USE_MEMALLOC
2668 elements[elcount] = TetMemory.Alloc();
2669 elements[elcount]->SetVertices(renumberedVertID);
2670 elements[elcount]->SetAttribute(ebprop[iblk]);
2672 elements[elcount] =
new Tetrahedron(renumberedVertID,
2677 case (ELEMENT_HEX8):
2678 case (ELEMENT_HEX27):
2680 elements[elcount] =
new Hexahedron(renumberedVertID,ebprop[iblk]);
2690 NumOfBdrElements = 0;
2691 for (
int iss = 0; iss < (int) num_side_sets; iss++)
2693 NumOfBdrElements += num_side_in_ss[iss];
2695 boundary.SetSize(NumOfBdrElements);
2697 for (
int iss = 0; iss < (int) num_side_sets; iss++)
2699 for (
int i = 0; i < (int) num_side_in_ss[iss]; i++)
2701 for (
int j = 0; j < num_face_linear_nodes; j++)
2703 renumberedVertID[j] =
2704 cubitToMFEMVertMap[ss_node_id[iss][i*num_face_nodes+j]] - 1;
2706 switch (cubit_face_type)
2711 boundary[sidecount] =
new Segment(renumberedVertID,ssprop[iss]);
2717 boundary[sidecount] =
new Triangle(renumberedVertID,ssprop[iss]);
2723 boundary[sidecount] =
new Quadrilateral(renumberedVertID,ssprop[iss]);
2736 switch (cubit_element_type)
2738 case (ELEMENT_TRI6):
2740 mymap = (
int *) mfemToGenesisTri6;
2743 case (ELEMENT_QUAD9):
2745 mymap = (
int *) mfemToGenesisQuad9;
2748 case (ELEMENT_TET10):
2750 mymap = (
int *) mfemToGenesisTet10;
2753 case (ELEMENT_HEX27):
2755 mymap = (
int *) mfemToGenesisHex27;
2758 case (ELEMENT_TRI3):
2759 case (ELEMENT_QUAD4):
2760 case (ELEMENT_TET4):
2761 case (ELEMENT_HEX8):
2763 MFEM_ABORT(
"Something went wrong. Linear elements detected when order is 2.");
2775 Nodes->MakeOwner(fec);
2783 for (
int i = 0; i < NumOfElements; i++)
2790 for (
int l = 0; l < dofs.
Size(); l++) { vdofs[l] = dofs[l]; }
2794 while (iblk < (
int) num_el_blk && i >= start_of_block[iblk+1]) { iblk++; }
2795 loc_ind = i - start_of_block[iblk];
2796 for (
int j = 0; j < dofs.
Size(); j++)
2798 int point_id = elem_blk[iblk][loc_ind*num_node_per_el + mymap[j] - 1] - 1;
2799 (*Nodes)(vdofs[j]) = coordx[point_id];
2800 (*Nodes)(vdofs[j]+1) = coordy[point_id];
2803 (*Nodes)(vdofs[j]+2) = coordz[point_id];
2813 for (
int i = 0; i < (int) num_side_sets; i++)
2815 delete [] elem_ss[i];
2816 delete [] side_ss[i];
2821 delete [] num_el_in_blk;
2822 delete [] num_side_in_ss;
2827 for (
int i = 0; i < (int) num_el_blk; i++)
2829 delete [] elem_blk[i];
2833 delete [] start_of_block;
2835 for (
int i = 0; i < (int) num_side_sets; i++)
2837 delete [] ss_node_id[i];
2839 delete [] ss_node_id;
2844 #endif // #ifdef MFEM_USE_NETCDF
Arbitrary order non-uniform rational B-splines (NURBS) finite elements.
Mesh * Make3D(int nsteps, double rstep, double aspect, int order, bool sfc)
int Size() const
Return the logical size of the array.
Class for grid function - Vector with associated FE space.
virtual void GetVertices(Array< int > &v) const =0
Returns element's vertices.
void GmshHOSegmentMapping(int order, int *map)
Generate Gmsh vertex mapping for a Segment.
void SetSize(int s)
Resize the vector to size s.
void MakeOwner(FiniteElementCollection *_fec)
Make the GridFunction the owner of fec and fes.
int Size() const
Returns the size of the vector.
virtual void SetVertices(const int *ind)
Set the vertices according to the given input.
Data type quadrilateral element.
void skip_comment_lines(std::istream &is, const char comment_char)
Check if the stream starts with comment_char. If so skip it.
void DeleteAll()
Delete the whole array.
Mesh * Make2D(int nsteps, double rstep, double phi, double aspect, int order, bool sfc)
Data type hexahedron element.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
Type
Constants for the classes derived from Element.
virtual void GetElementDofs(int i, Array< int > &dofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Data type triangle element.
A class for non-conforming AMR on higher-order hexahedral, prismatic, quadrilateral or triangular mes...
void GmshHOQuadrilateralMapping(int order, int *map)
Generate Gmsh vertex mapping for a Quadrilateral.
Data type tetrahedron element.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
void GmshHOTriangleMapping(int order, int *map)
Generate Gmsh vertex mapping for a Triangle.
void GmshHOTetrahedronMapping(int order, int *map)
Generate Gmsh vertex mapping for a Tetrahedron.
void Destroy()
Destroy a vector.
int index(int i, int j, int nx, int ny)
virtual int GetNVertices() const =0
void SetAttribute(const int attr)
Set element's attribute.
Piecewise-(bi)quadratic continuous finite elements.
virtual void SetSpace(FiniteElementSpace *f)
Associate a new FiniteElementSpace with the GridFunction.
void filter_dos(std::string &line)
Check for, and remove, a trailing '\r' from and std::string.
Vector coefficient defined by a vector GridFunction.
void GmshHOHexahedronMapping(int order, int *map)
Generate Gmsh vertex mapping for a Hexahedron.
Arbitrary order H1-conforming (continuous) finite elements.
void GmshHOWedgeMapping(int order, int *map)
Generate Gmsh vertex mapping for a Wedge.
Abstract data type element.
Data type line segment element.
Arbitrary order "L2-conforming" discontinuous finite elements.
void DofsToVDofs(Array< int > &dofs, int ndofs=-1) const