22#include <boost/algorithm/string.hpp>
23#include <boost/archive/binary_iarchive.hpp>
24#include <boost/io/ios_state.hpp>
25#include <boost/property_tree/ptree.hpp>
26#include <boost/property_tree/xml_parser.hpp>
27#include <boost/serialization/serialization.hpp>
29#ifdef DEAL_II_GMSH_WITH_API
44#ifdef DEAL_II_WITH_ASSIMP
45# include <assimp/Importer.hpp>
46# include <assimp/postprocess.h>
47# include <assimp/scene.h>
50#ifdef DEAL_II_TRILINOS_WITH_SEACAS
77 template <
int spacedim>
79 assign_1d_boundary_ids(
84 for (
auto &cell : triangulation.active_cell_iterators())
86 if (cell->face(face_no)->at_boundary())
87 for (
const auto &pair : boundary_ids)
88 if (cell->face(face_no)->vertex(0) == pair.
first)
90 cell->face(face_no)->set_boundary_id(pair.second);
96 template <
int dim,
int spacedim>
98 assign_1d_boundary_ids(
110 template <
int dim,
int spacedim>
118 const auto n_hypercube_vertices =
119 ReferenceCells::get_hypercube<dim>().n_vertices();
120 bool is_only_hypercube =
true;
122 if (cell.vertices.
size() != n_hypercube_vertices)
124 is_only_hypercube =
false;
129 if constexpr (dim == spacedim)
132 if (is_only_hypercube)
142 template <
class CharT,
class Traits,
class Allocator>
143 std::basic_istream<CharT, Traits> &
144 getline_dos_or_unix(std::basic_istream<CharT, Traits> &input,
145 std::basic_string<CharT, Traits, Allocator> &line)
147 std::getline(input, line);
156 if ((line.size() > 0) && (line.back() ==
'\r'))
157 line.erase(line.size() - 1);
166template <
int dim,
int spacedim>
168 : tria(nullptr, typeid(*this).name())
169 , default_format(ucd)
174template <
int dim,
int spacedim>
176 : tria(&t, typeid(*this).name())
177 , default_format(ucd)
182template <
int dim,
int spacedim>
191template <
int dim,
int spacedim>
196 std::string vtk_version;
207 text[3] =
"DATASET UNSTRUCTURED_GRID";
209 for (
unsigned int i = 0; i < 4; ++i)
215 if (i == 2 || i == 3)
217 line.compare(text[i]) == 0,
220 "While reading VTK file, failed to find a header line with text <") +
225 vtk_version = text[0].substr(23, 3);
231 std::vector<Point<spacedim>> vertices;
232 std::vector<CellData<dim>> cells;
241 if (keyword ==
"POINTS")
243 unsigned int n_vertices;
248 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
252 in >> x[0] >> x[1] >> x[2];
254 vertices.emplace_back();
255 for (
unsigned int d = 0; d < spacedim; ++d)
256 vertices.back()[d] = x[d];
263 "While reading VTK file, failed to find POINTS section"));
267 unsigned int n_geometric_objects = 0;
269 std::vector<unsigned int> n_points_per_cell;
271 if (keyword ==
"CELLS")
274 std::vector<unsigned int> cell_types;
276 std::streampos oldpos = in.tellg();
279 while (in >> keyword)
280 if (keyword ==
"CELL_TYPES")
284 cell_types.resize(n_ints);
286 for (
unsigned int i = 0; i < n_ints; ++i)
295 in >> n_geometric_objects;
298 if (vtk_version ==
"5.1")
304 keyword ==
"OFFSETS",
306 "While reading VTK file, failed to find OFFSETS array which must exist in a VTK file with version 5.1."));
310 unsigned int n_offsets = n_geometric_objects;
318 unsigned int new_index = 0;
319 unsigned int old_index = 0;
322 for (
unsigned int p = 0; p < n_offsets; ++p)
324 unsigned int n_points_per_cell_tmp;
332 "While reading VTK file, the first index in the OFFSETS array should be 0"));
335 n_points_per_cell_tmp = new_index - old_index;
336 n_points_per_cell.push_back(n_points_per_cell_tmp);
338 old_index = new_index;
342 n_points_per_cell.size() == cell_types.size(),
344 "The number of cells inferred from the OFFSETS array (" +
345 std::to_string(n_points_per_cell.size()) +
346 ") does not match the number of entries in the CELL_TYPES array (" +
347 std::to_string(cell_types.size()) +
")"));
353 keyword ==
"CONNECTIVITY",
355 "While reading VTK file, failed to find CONNECTIVITY array which must exist in a VTK file containing an OFFSETS array."));
361 n_geometric_objects = n_points_per_cell.size();
365 if constexpr (dim == 3)
367 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
369 unsigned int n_vertices;
371 if (vtk_version ==
"3.0")
373 else if (vtk_version ==
"5.1")
375 n_vertices = n_points_per_cell[count];
380 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
383 if (cell_types[count] == 10 || cell_types[count] == 12)
391 cells.emplace_back(n_vertices);
393 for (
unsigned int j = 0; j < n_vertices;
395 in >> cells.back().vertices[j];
399 if (cell_types[count] == 12)
401 std::swap(cells.back().vertices[2],
402 cells.back().vertices[3]);
403 std::swap(cells.back().vertices[6],
404 cells.back().vertices[7]);
407 cells.back().material_id = 0;
410 else if (cell_types[count] == 5 || cell_types[count] == 9)
419 for (
unsigned int j = 0; j < n_vertices;
426 else if (cell_types[count] == 3)
430 for (
unsigned int j = 0; j < n_vertices;
441 "While reading VTK file, unknown cell type encountered"));
444 else if constexpr (dim == 2)
446 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
448 unsigned int n_vertices;
450 if (vtk_version ==
"3.0")
452 else if (vtk_version ==
"5.1")
454 n_vertices = n_points_per_cell[count];
459 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
462 if (cell_types[count] == 5 || cell_types[count] == 9)
469 cells.emplace_back(n_vertices);
471 for (
unsigned int j = 0; j < n_vertices;
473 in >> cells.back().vertices[j];
477 if (cell_types[count] == 9)
481 std::swap(cells.back().vertices[2],
482 cells.back().vertices[3]);
485 cells.back().material_id = 0;
488 else if (cell_types[count] == 3)
494 for (
unsigned int j = 0; j < n_vertices;
507 "While reading VTK file, unknown cell type encountered"));
510 else if constexpr (dim == 1)
512 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
514 unsigned int n_vertices;
515 if (vtk_version ==
"3.0")
517 else if (vtk_version ==
"5.1")
519 n_vertices = n_points_per_cell[count];
524 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
527 cell_types[count] == 3 && n_vertices == 2,
529 "While reading VTK file, unknown cell type encountered"));
530 cells.emplace_back(n_vertices);
532 for (
unsigned int j = 0; j < n_vertices; ++j)
533 in >> cells.back().vertices[j];
535 cells.back().material_id = 0;
541 "While reading VTK file, failed to find CELLS section"));
548 keyword ==
"CELL_TYPES",
550 "While reading VTK file, missing CELL_TYPES section. Found <" +
551 keyword +
"> instead.")));
556 n_ints == n_geometric_objects,
557 ExcMessage(
"The VTK reader found a CELL_DATA statement "
558 "that lists a total of " +
560 " cell data objects, but this needs to "
561 "equal the number of cells (which is " +
563 ") plus the number of quads (" +
565 " in 3d or the number of lines (" +
570 for (
unsigned int i = 0; i < n_ints; ++i)
577 while (in >> keyword)
579 if (keyword ==
"CELL_DATA")
585 n_ids == n_geometric_objects,
587 "The VTK reader found a CELL_DATA statement "
588 "that lists a total of " +
590 " cell data objects, but this needs to "
591 "equal the number of cells (which is " +
593 ") plus the number of quads (" +
595 " in 3d or the number of lines (" +
599 const std::vector<std::string> data_sets{
"MaterialID",
603 for (
unsigned int i = 0; i < data_sets.size(); ++i)
606 if (keyword ==
"SCALARS")
611 std::string field_name;
613 if (std::find(data_sets.begin(),
615 field_name) == data_sets.end())
627 getline_dos_or_unix(in, line);
631 std::min(
static_cast<std::size_t
>(3),
632 line.size() - 1)) ==
"int",
634 "While reading VTK file, material- and manifold IDs can only have type 'int'."));
638 keyword ==
"LOOKUP_TABLE",
640 "While reading VTK file, missing keyword 'LOOKUP_TABLE'."));
644 keyword ==
"default",
646 "While reading VTK file, missing keyword 'default'."));
653 for (
unsigned int i = 0; i < cells.size(); ++i)
657 if (field_name ==
"MaterialID")
658 cells[i].material_id =
660 else if (field_name ==
"ManifoldID")
661 cells[i].manifold_id =
667 if constexpr (dim == 3)
673 if (field_name ==
"MaterialID")
674 boundary_quad.material_id =
676 else if (field_name ==
"ManifoldID")
677 boundary_quad.manifold_id =
686 if (field_name ==
"MaterialID")
687 boundary_line.material_id =
689 else if (field_name ==
"ManifoldID")
690 boundary_line.manifold_id =
696 else if constexpr (dim == 2)
702 if (field_name ==
"MaterialID")
703 boundary_line.material_id =
705 else if (field_name ==
"ManifoldID")
706 boundary_line.manifold_id =
716 std::streampos oldpos = in.tellg();
718 if (keyword ==
"SCALARS")
729 else if (keyword ==
"FIELD")
731 unsigned int n_fields;
734 keyword ==
"FieldData",
736 "While reading VTK file, missing keyword FieldData"));
740 for (
unsigned int i = 0; i < n_fields; ++i)
742 std::string section_name;
743 std::string data_type;
744 unsigned int temp, n_ids;
750 n_ids == n_geometric_objects,
752 "The VTK reader found a FIELD statement "
753 "that lists a total of " +
755 " cell data objects, but this needs to equal the number of cells (which is " +
757 ") plus the number of quads (" +
760 " in 3d or the number of lines (" +
767 for (
unsigned int j = 0; j < n_ids; ++j)
770 if (j < cells.size())
773 this->cell_data[section_name] = std::move(temp_data);
784 apply_grid_fixup_functions(vertices, cells, subcelldata);
785 tria->create_triangulation(vertices, cells, subcelldata);
790 "While reading VTK file, failed to find CELLS section"));
793template <
int dim,
int spacedim>
794const std::map<std::string, Vector<double>> &
797 return this->cell_data;
800template <
int dim,
int spacedim>
804 namespace pt = boost::property_tree;
806 pt::read_xml(in, tree);
807 auto section = tree.get_optional<std::string>(
"VTKFile.dealiiData");
811 "While reading a VTU file, failed to find dealiiData section. "
812 "Notice that we can only read grid files in .vtu format that "
813 "were created by the deal.II library, using a call to "
814 "GridOut::write_vtu(), where the flag "
815 "GridOutFlags::Vtu::serialize_triangulation is set to true."));
819 const auto string_archive =
821 std::istringstream in_stream(string_archive);
822 boost::archive::binary_iarchive ia(in_stream);
827template <
int dim,
int spacedim>
831 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
835 skip_comment_lines(in,
'#');
846 "Expected '-1' before and after a section."));
858 getline_dos_or_unix(in, line);
860 boost::algorithm::trim(line);
861 if (line.compare(
"-1") == 0)
872 std::vector<Point<spacedim>> vertices;
891 in >> dummy >> dummy >> dummy;
894 in >> x[0] >> x[1] >> x[2];
896 vertices.emplace_back();
898 for (
unsigned int d = 0; d < spacedim; ++d)
899 vertices.back()[d] = x[d];
913 AssertThrow(tmp == 2412, ExcUnknownSectionType(tmp));
915 std::vector<CellData<dim>> cells;
942 in >> type >> dummy >> dummy >> dummy >> dummy;
944 AssertThrow((type == 11) || (type == 44) || (type == 94) || (type == 115),
945 ExcUnknownElementType(type));
947 if ((((type == 44) || (type == 94)) && (dim == 2)) ||
948 ((type == 115) && (dim == 3)))
950 const auto reference_cell = ReferenceCells::get_hypercube<dim>();
951 cells.emplace_back();
956 .vertices[reference_cell.unv_vertex_to_deal_vertex(v)];
958 cells.back().material_id = 0;
961 cells.back().vertices[v] =
vertex_indices[cells.back().vertices[v]];
963 cell_indices[object_index] = n_cells;
967 else if (((type == 11) && (dim == 2)) ||
968 ((type == 11) && (dim == 3)))
971 in >> dummy >> dummy >> dummy;
976 for (
unsigned int &vertex :
982 for (
unsigned int &vertex :
986 line_indices[object_index] = n_lines;
990 else if (((type == 44) || (type == 94)) && (dim == 3))
1001 .vertices[reference_cell.unv_vertex_to_deal_vertex(v)];
1005 for (
unsigned int &vertex :
1009 quad_indices[object_index] = n_quads;
1017 "> when running in dim=" +
1036 AssertThrow((tmp == 2467) || (tmp == 2477), ExcUnknownSectionType(tmp));
1052 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
1063 getline_dos_or_unix(in, line);
1066 "The line before the line containing an ID has too "
1067 "many entries. This is not a valid UNV file."));
1069 getline_dos_or_unix(in, line);
1071 std::istringstream id_stream(line);
1074 !id_stream.fail() && id_stream.eof(),
1076 "The given UNV file contains a boundary or material id set to '" +
1078 "', which cannot be parsed as a fixed-width integer, whereas "
1079 "deal.II only supports integer boundary and material ids. To fix "
1080 "this, ensure that all such ids are given integer values."));
1083 id <=
long(std::numeric_limits<types::material_id>::max()),
1084 ExcMessage(
"The provided integer id '" + std::to_string(
id) +
1085 "' is not convertible to either types::material_id nor "
1086 "types::boundary_id."));
1088 const unsigned int n_lines =
1089 (n_entities % 2 == 0) ? (n_entities / 2) : ((n_entities + 1) / 2);
1091 for (
unsigned int line = 0; line < n_lines; ++line)
1093 unsigned int n_fragments;
1095 if (line == n_lines - 1)
1096 n_fragments = (n_entities % 2 == 0) ? (2) : (1);
1100 for (
unsigned int no_fragment = 0; no_fragment < n_fragments;
1104 in >> dummy >> no >> dummy >> dummy;
1106 if (cell_indices.count(no) > 0)
1107 cells[cell_indices[no]].material_id = id;
1109 if (line_indices.count(no) > 0)
1113 if (quad_indices.count(no) > 0)
1121 apply_grid_fixup_functions(vertices, cells, subcelldata);
1122 tria->create_triangulation(vertices, cells, subcelldata);
1129 if constexpr (dim == 1)
1131 if (type_string ==
"line")
1133 return ReferenceCells::Invalid<1>;
1135 else if constexpr (dim == 2)
1137 if (type_string ==
"quad")
1139 if (type_string ==
"tri")
1141 return ReferenceCells::Invalid<2>;
1143 else if constexpr (dim == 3)
1145 if (type_string ==
"hex")
1147 if (type_string ==
"tet")
1149 if (type_string ==
"prism")
1151 if (type_string ==
"pyr")
1153 return ReferenceCells::Invalid<3>;
1158template <
int dim,
int spacedim>
1161 const bool apply_all_indicators_to_manifolds)
1163 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
1167 skip_comment_lines(in,
'#');
1170 unsigned int n_vertices;
1171 unsigned int n_cells;
1174 in >> n_vertices >> n_cells >> dummy
1180 std::vector<Point<spacedim>> vertices(n_vertices);
1186 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1193 in >> vertex_number >> x[0] >> x[1] >> x[2];
1196 for (
unsigned int d = 0; d < spacedim; ++d)
1197 vertices[vertex][d] = x[d];
1205 std::vector<CellData<dim>> cells;
1209 vertices_for_this_element(0);
1211 subcell_vertices_for_this_element(0);
1213 for (
unsigned int cell = 0; cell < n_cells; ++cell)
1222 std::string cell_type;
1226 unsigned int material_id;
1232 if (((dim == 1) && (cell_type ==
"line")) ||
1233 ((dim == 2) && (cell_type ==
"quad")) ||
1234 ((dim == 3) && (cell_type ==
"hex")) ||
1235 ((dim == 2) && (cell_type ==
"tri")) ||
1236 ((dim == 3) && (cell_type ==
"tet")) ||
1237 ((dim == 3) && (cell_type ==
"prism")) ||
1238 ((dim == 3) && (cell_type ==
"pyr")))
1242 cells.emplace_back();
1243 const auto ref_cell =
1244 get_reference_cell_from_UCD_string<dim>(cell_type);
1245 vertices_for_this_element.resize(ref_cell.n_vertices());
1246 for (
const unsigned int i : ref_cell.vertex_indices())
1248 vertices_for_this_element[ref_cell.ucd_vertex_to_deal_vertex(i)];
1250 cells.back().vertices = vertices_for_this_element;
1252 Assert(material_id <= std::numeric_limits<types::material_id>::max(),
1255 std::numeric_limits<types::material_id>::max()));
1260 if (apply_all_indicators_to_manifolds)
1261 cells.back().manifold_id =
1263 cells.back().material_id = material_id;
1267 for (
const unsigned int i : ref_cell.vertex_indices())
1271 cells.back().vertices[i] =
1277 ExcInvalidVertexIndex(cell,
1278 cells.back().vertices[i]));
1283 else if (((dim == 2) || (dim == 3)) && (cell_type ==
"line"))
1291 Assert(material_id <= std::numeric_limits<types::boundary_id>::max(),
1294 std::numeric_limits<types::boundary_id>::max()));
1303 if (apply_all_indicators_to_manifolds)
1320 for (
unsigned int &vertex :
1328 AssertThrow(
false, ExcInvalidVertexIndex(cell, vertex));
1332 else if (((dim == 3) && (cell_type ==
"quad")) ||
1333 ((dim == 3) && (cell_type ==
"tri")))
1336 const auto ref_cell =
1337 get_reference_cell_from_UCD_string<2>(cell_type);
1338 subcell_vertices_for_this_element.resize(ref_cell.n_vertices());
1340 for (
const unsigned int i : ref_cell.vertex_indices())
1341 in >> subcell_vertices_for_this_element
1342 [ref_cell.ucd_vertex_to_deal_vertex(i)];
1345 subcell_vertices_for_this_element;
1348 Assert(material_id <= std::numeric_limits<types::boundary_id>::max(),
1351 std::numeric_limits<types::boundary_id>::max()));
1360 if (apply_all_indicators_to_manifolds)
1377 for (
unsigned int &vertex :
1385 Assert(
false, ExcInvalidVertexIndex(cell, vertex));
1391 AssertThrow(
false, ExcUnknownIdentifier(cell_type));
1396 apply_grid_fixup_functions(vertices, cells, subcelldata);
1397 tria->create_triangulation(vertices, cells, subcelldata);
1402 template <
int dim,
int spacedim>
1409 read_in_abaqus(std::istream &in);
1411 write_out_avs_ucd(std::ostream &out)
const;
1414 const double tolerance;
1417 get_global_node_numbers(
const int face_cell_no,
1418 const int face_cell_face_no)
const;
1421 std::vector<std::vector<double>> node_list;
1424 std::vector<std::vector<double>> cell_list;
1426 std::vector<std::vector<double>> face_list;
1429 std::map<std::string, std::vector<int>> elsets_list;
1432 get_reference_cell_from_element_type(
const std::string &type_string);
1438template <
int dim,
int spacedim>
1441 const bool apply_all_indicators_to_manifolds)
1443 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
1448 Assert((spacedim == 2 && dim == spacedim) ||
1449 (spacedim == 3 && (dim == spacedim || dim == spacedim - 1)),
1455 Abaqus_to_UCD<dim, spacedim> abaqus_to_ucd;
1456 abaqus_to_ucd.read_in_abaqus(in);
1458 std::stringstream in_ucd;
1459 abaqus_to_ucd.write_out_avs_ucd(in_ucd);
1467 read_ucd(in_ucd, apply_all_indicators_to_manifolds);
1469 catch (std::exception &exc)
1471 std::cerr <<
"Exception on processing internal UCD data: " << std::endl
1472 << exc.what() << std::endl;
1477 "Internal conversion from ABAQUS file to UCD format was unsuccessful. "
1478 "More information is provided in an error message printed above. "
1479 "Are you sure that your ABAQUS mesh file conforms with the requirements "
1480 "listed in the documentation?"));
1487 "Internal conversion from ABAQUS file to UCD format was unsuccessful. "
1488 "Are you sure that your ABAQUS mesh file conforms with the requirements "
1489 "listed in the documentation?"));
1494template <
int dim,
int spacedim>
1498 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
1504 skip_comment_lines(in,
'#');
1510 AssertThrow(line ==
"MeshVersionFormatted 0", ExcInvalidDBMESHInput(line));
1512 skip_empty_lines(in);
1516 AssertThrow(line ==
"Dimension", ExcInvalidDBMESHInput(line));
1517 unsigned int dimension;
1519 AssertThrow(dimension == dim, ExcDBMESHWrongDimension(dimension));
1520 skip_empty_lines(in);
1533 while (getline(in, line), line.find(
"# END") == std::string::npos)
1535 skip_empty_lines(in);
1540 AssertThrow(line ==
"Vertices", ExcInvalidDBMESHInput(line));
1542 unsigned int n_vertices;
1546 std::vector<Point<spacedim>> vertices(n_vertices);
1547 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1550 for (
unsigned int d = 0; d < dim; ++d)
1551 in >> vertices[vertex][d];
1557 skip_empty_lines(in);
1563 AssertThrow(line ==
"Edges", ExcInvalidDBMESHInput(line));
1565 unsigned int n_edges;
1567 for (
unsigned int edge = 0; edge < n_edges; ++edge)
1570 in >> dummy >> dummy;
1576 skip_empty_lines(in);
1585 AssertThrow(line ==
"CrackedEdges", ExcInvalidDBMESHInput(line));
1588 for (
unsigned int edge = 0; edge < n_edges; ++edge)
1591 in >> dummy >> dummy;
1597 skip_empty_lines(in);
1603 AssertThrow(line ==
"Quadrilaterals", ExcInvalidDBMESHInput(line));
1605 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
1606 {0, 1, 5, 4, 2, 3, 7, 6}};
1607 std::vector<CellData<dim>> cells;
1609 unsigned int n_cells;
1611 for (
unsigned int cell = 0; cell < n_cells; ++cell)
1615 cells.emplace_back();
1619 cells.back().vertices[dim == 3 ? local_vertex_numbering[i] :
1623 (
static_cast<unsigned int>(cells.back().vertices[i]) <=
1625 ExcInvalidVertexIndex(cell, cells.back().vertices[i]));
1627 --cells.back().vertices[i];
1635 skip_empty_lines(in);
1643 while (getline(in, line), ((line.find(
"End") == std::string::npos) && (in)))
1649 apply_grid_fixup_functions(vertices, cells, subcelldata);
1650 tria->create_triangulation(vertices, cells, subcelldata);
1655template <
int dim,
int spacedim>
1659 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
1662 const auto reference_cell = ReferenceCells::get_hypercube<dim>();
1666 getline_dos_or_unix(in, line);
1668 unsigned int n_vertices;
1669 unsigned int n_cells;
1673 getline_dos_or_unix(in, line);
1676 getline_dos_or_unix(in, line);
1679 for (
unsigned int i = 0; i < 8; ++i)
1680 getline_dos_or_unix(in, line);
1683 std::vector<CellData<dim>> cells(n_cells);
1694 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
1695 in >> cell.vertices[reference_cell.exodusii_vertex_to_deal_vertex(i)];
1699 std::vector<Point<spacedim>> vertices(n_vertices);
1702 for (
unsigned int d = 0; d < spacedim; ++d)
1704 for (
unsigned int d = spacedim; d < 3; ++d)
1713 apply_grid_fixup_functions(vertices, cells, subcelldata);
1714 tria->create_triangulation(vertices, cells, subcelldata);
1719template <
int dim,
int spacedim>
1723 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
1736 std::stringstream whole_file;
1741 getline_dos_or_unix(in, line);
1749 if ((line.size() > 0) && (line.back() ==
'\r'))
1750 line.erase(line.size() - 1);
1755 if (line.find(
'#') != std::string::npos)
1756 line.erase(line.find(
'#'), std::string::npos);
1757 while ((line.size() > 0) && (line.back() ==
' '))
1758 line.erase(line.size() - 1);
1760 if (line.size() > 0)
1761 whole_file <<
'\n' << line;
1780 unsigned int version_major, version_minor;
1781 whole_file >> version_major >> version_minor;
1782 AssertThrow((version_major == 0) && (version_minor == 1),
1783 ExcMessage(
"deal.II can currently only read version 0.1 "
1784 "of the mphtxt file format."));
1789 unsigned int n_tags;
1790 whole_file >> n_tags;
1791 for (
unsigned int i = 0; i < n_tags; ++i)
1794 while (whole_file.peek() ==
'\n')
1796 getline_dos_or_unix(whole_file, dummy);
1802 unsigned int n_types;
1803 whole_file >> n_types;
1804 for (
unsigned int i = 0; i < n_types; ++i)
1807 while (whole_file.peek() ==
'\n')
1809 getline_dos_or_unix(whole_file, dummy);
1829 whole_file >> dummy >> dummy >> dummy;
1833 while (whole_file.peek() ==
'\n')
1835 getline_dos_or_unix(whole_file, s);
1837 ExcMessage(
"Expected '4 Mesh', but got '" + s +
"'."));
1840 unsigned int version;
1841 whole_file >> version;
1845 unsigned int file_space_dim;
1846 whole_file >> file_space_dim;
1850 "The mesh file uses a different number of space dimensions "
1851 "than the triangulation you want to read it into."));
1853 unsigned int n_vertices;
1854 whole_file >> n_vertices;
1856 unsigned int starting_vertex_index;
1857 whole_file >> starting_vertex_index;
1859 std::vector<Point<spacedim>> vertices(n_vertices);
1860 for (
unsigned int v = 0; v < n_vertices; ++v)
1861 whole_file >> vertices[v];
1891 std::vector<CellData<dim>> cells;
1894 unsigned int n_types;
1895 whole_file >> n_types;
1896 for (
unsigned int type = 0; type < n_types; ++type)
1903 whole_file >> dummy;
1907 std::string object_name;
1908 whole_file >> object_name;
1910 const std::set<std::string> known_object_names = {
1911 "vtx",
"edg",
"tri",
"quad",
"tet",
"prism"
1915 AssertThrow(known_object_names.find(object_name) !=
1916 known_object_names.end(),
1917 ExcMessage(
"The input file contains a cell type <" +
1919 "> that the reader does not "
1920 "current support"));
1922 unsigned int n_vertices_per_element;
1923 whole_file >> n_vertices_per_element;
1925 unsigned int n_elements;
1926 whole_file >> n_elements;
1929 if ((dim >= 3) && (object_name ==
"tet"))
1932 ExcMessage(
"Tetrahedra should not appear in input files "
1933 "for 1d or 2d meshes."));
1936 else if ((dim >= 3) && (object_name ==
"prism"))
1940 "Prisms (wedges) should not appear in input files "
1941 "for 1d or 2d meshes."));
1944 else if ((dim >= 2) && (object_name ==
"tri"))
1947 ExcMessage(
"Triangles should not appear in input files "
1951 else if ((dim >= 2) && (object_name ==
"quad"))
1955 "Quadrilaterals should not appear in input files "
1959 else if (object_name ==
"edg")
1963 else if (object_name ==
"vtx")
1986 ReferenceCells::max_n_vertices<dim>()>
1987 vertices_for_this_element(n_vertices_per_element);
1988 for (
unsigned int e = 0; e < n_elements; ++e)
1991 for (
unsigned int v = 0; v < n_vertices_per_element; ++v)
1993 whole_file >> vertices_for_this_element[v];
1994 vertices_for_this_element[v] -= starting_vertex_index;
1998 ((object_name ==
"tet") || (object_name ==
"prism")))
2000 if constexpr (dim == 3)
2002 cells.emplace_back();
2003 cells.back().vertices = vertices_for_this_element;
2008 else if ((dim >= 2) &&
2009 ((object_name ==
"tri") || (object_name ==
"quad")))
2011 if constexpr (dim == 2)
2013 cells.emplace_back();
2014 cells.back().vertices = vertices_for_this_element;
2020 vertices_for_this_element.begin(),
2021 vertices_for_this_element.end());
2024 else if (object_name ==
"edg")
2026 if constexpr (dim == 1)
2028 cells.emplace_back();
2029 cells.back().vertices = vertices_for_this_element;
2035 vertices_for_this_element.begin(),
2036 vertices_for_this_element.end());
2039 else if (object_name ==
"vtx")
2050 unsigned int n_geom_entity_indices;
2051 whole_file >> n_geom_entity_indices;
2053 (n_geom_entity_indices == n_elements),
2060 if (n_geom_entity_indices != 0)
2062 for (
unsigned int e = 0; e < n_geom_entity_indices; ++e)
2065 unsigned int geometric_entity_index;
2066 whole_file >> geometric_entity_index;
2067 if (object_name ==
"vtx")
2069 else if (object_name ==
"edg")
2071 if constexpr (dim == 1)
2072 cells[cells.size() - n_elements + e].material_id =
2073 geometric_entity_index;
2078 .boundary_id = geometric_entity_index;
2080 else if ((dim >= 2) &&
2081 ((object_name ==
"tri") || (object_name ==
"quad")))
2083 if constexpr (dim == 2)
2084 cells[cells.size() - n_elements + e].material_id =
2085 geometric_entity_index;
2090 .boundary_id = geometric_entity_index;
2092 else if ((dim >= 3) &&
2093 ((object_name ==
"tet") || (object_name ==
"prism")))
2095 if constexpr (dim == 3)
2096 cells[cells.size() - n_elements + e].material_id =
2097 geometric_entity_index;
2113 tria->create_triangulation(vertices, cells, {});
2118 if constexpr (dim >= 2)
2123 if (line.vertices[1] < line.vertices[0])
2124 std::swap(line.vertices[0], line.vertices[1]);
2129 return std::lexicographical_compare(a.vertices.begin(),
2147 if constexpr (dim >= 3)
2151 Assert((face.vertices.size() == 3) || (face.vertices.size() == 4),
2153 std::sort(face.vertices.begin(), face.vertices.end());
2158 return std::lexicographical_compare(a.vertices.begin(),
2166 if constexpr (dim >= 2)
2168 for (
const auto &cell : tria->active_cell_iterators())
2169 for (
const auto &face : cell->face_iterators())
2170 if (face->at_boundary())
2174 if constexpr (dim == 2)
2176 std::array<unsigned int, 2> face_vertex_indices = {
2177 {face->vertex_index(0), face->vertex_index(1)}};
2178 if (face_vertex_indices[0] > face_vertex_indices[1])
2179 std::swap(face_vertex_indices[0], face_vertex_indices[1]);
2185 face_vertex_indices,
2187 const std::array<unsigned int, 2>
2188 &face_vertex_indices) ->
bool {
2189 return std::lexicographical_compare(
2192 face_vertex_indices.begin(),
2193 face_vertex_indices.end());
2197 (p->vertices[0] == face_vertex_indices[0]) &&
2198 (p->vertices[1] == face_vertex_indices[1]))
2200 face->set_boundary_id(p->boundary_id);
2203 else if constexpr (dim == 3)
2213 face_vertex_indices(face->n_vertices());
2214 for (
unsigned int v = 0; v < face->n_vertices(); ++v)
2215 face_vertex_indices[v] = face->vertex_index(v);
2216 std::sort(face_vertex_indices.
begin(),
2217 face_vertex_indices.
end());
2220 const auto p = std::lower_bound(
2223 face_vertex_indices,
2225 const auto &face_vertex_indices) ->
bool {
2226 return std::lexicographical_compare(
2229 face_vertex_indices.begin(),
2230 face_vertex_indices.end());
2234 (std::equal(p->vertices.begin(),
2236 face_vertex_indices.
begin(),
2237 face_vertex_indices.
end())))
2239 face->set_boundary_id(p->boundary_id);
2244 for (
unsigned int e = 0; e < face->n_lines(); ++e)
2246 const auto edge = face->line(e);
2248 std::array<unsigned int, 2> edge_vertex_indices = {
2249 {edge->vertex_index(0), edge->vertex_index(1)}};
2250 if (edge_vertex_indices[0] > edge_vertex_indices[1])
2251 std::swap(edge_vertex_indices[0],
2252 edge_vertex_indices[1]);
2258 edge_vertex_indices,
2260 const std::array<unsigned int, 2>
2261 &edge_vertex_indices) ->
bool {
2262 return std::lexicographical_compare(
2265 edge_vertex_indices.begin(),
2266 edge_vertex_indices.end());
2270 (p->vertices[0] == edge_vertex_indices[0]) &&
2271 (p->vertices[1] == edge_vertex_indices[1]))
2273 edge->set_boundary_id(p->boundary_id);
2283template <
int dim,
int spacedim>
2287 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
2290 unsigned int n_vertices;
2291 unsigned int n_cells;
2297 std::array<std::map<int, int>, 4> tag_maps;
2300 std::string stripped_file;
2304 while (getline_dos_or_unix(input_stream, line))
2306 if (line ==
"@f$Comments")
2308 while (getline_dos_or_unix(input_stream, line))
2310 if (line ==
"@f$EndComments")
2317 stripped_file += line +
'\n';
2321 std::istringstream in(stripped_file);
2326 unsigned int gmsh_file_format = 0;
2327 if (line ==
"@f$NOD")
2328 gmsh_file_format = 10;
2329 else if (line ==
"@f$MeshFormat")
2330 gmsh_file_format = 20;
2336 if (gmsh_file_format == 20)
2339 unsigned int file_type, data_size;
2341 in >> version >> file_type >> data_size;
2344 gmsh_file_format =
static_cast<unsigned int>(version * 10);
2352 AssertThrow(line ==
"@f$EndMeshFormat", ExcInvalidGMSHInput(line));
2356 if (line ==
"@f$PhysicalNames")
2362 while (line !=
"@f$EndPhysicalNames");
2367 if (line ==
"@f$Entities")
2369 unsigned long n_points, n_curves, n_surfaces, n_volumes;
2371 in >> n_points >> n_curves >> n_surfaces >> n_volumes;
2372 for (
unsigned int i = 0; i < n_points; ++i)
2376 unsigned int n_physicals;
2377 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2381 if (gmsh_file_format > 40)
2383 in >> tag >> box_min_x >> box_min_y >> box_min_z >>
2385 box_max_x = box_min_x;
2386 box_max_y = box_min_y;
2387 box_max_z = box_min_z;
2391 in >> tag >> box_min_x >> box_min_y >> box_min_z >>
2392 box_max_x >> box_max_y >> box_max_z >> n_physicals;
2397 ExcMessage(
"More than one tag is not supported!"));
2399 int physical_tag = 0;
2400 for (
unsigned int j = 0; j < n_physicals; ++j)
2402 tag_maps[0][tag] = physical_tag;
2404 for (
unsigned int i = 0; i < n_curves; ++i)
2408 unsigned int n_physicals;
2409 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2413 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2414 box_max_y >> box_max_z >> n_physicals;
2418 ExcMessage(
"More than one tag is not supported!"));
2420 int physical_tag = 0;
2421 for (
unsigned int j = 0; j < n_physicals; ++j)
2423 tag_maps[1][tag] = physical_tag;
2428 for (
unsigned int j = 0; j < n_points; ++j)
2432 for (
unsigned int i = 0; i < n_surfaces; ++i)
2436 unsigned int n_physicals;
2437 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2441 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2442 box_max_y >> box_max_z >> n_physicals;
2446 ExcMessage(
"More than one tag is not supported!"));
2448 int physical_tag = 0;
2449 for (
unsigned int j = 0; j < n_physicals; ++j)
2451 tag_maps[2][tag] = physical_tag;
2456 for (
unsigned int j = 0; j < n_curves; ++j)
2459 for (
unsigned int i = 0; i < n_volumes; ++i)
2463 unsigned int n_physicals;
2464 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2468 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2469 box_max_y >> box_max_z >> n_physicals;
2473 ExcMessage(
"More than one tag is not supported!"));
2475 int physical_tag = 0;
2476 for (
unsigned int j = 0; j < n_physicals; ++j)
2478 tag_maps[3][tag] = physical_tag;
2483 for (
unsigned int j = 0; j < n_surfaces; ++j)
2487 AssertThrow(line ==
"@f$EndEntities", ExcInvalidGMSHInput(line));
2492 if (line ==
"@f$PartitionedEntities")
2498 while (line !=
"@f$EndPartitionedEntities");
2505 AssertThrow(line ==
"@f$Nodes", ExcInvalidGMSHInput(line));
2509 int n_entity_blocks = 1;
2510 if (gmsh_file_format > 40)
2514 in >> n_entity_blocks >> n_vertices >> min_node_tag >> max_node_tag;
2516 else if (gmsh_file_format == 40)
2518 in >> n_entity_blocks >> n_vertices;
2522 std::vector<Point<spacedim>> vertices(n_vertices);
2529 unsigned int global_vertex = 0;
2530 for (
int entity_block = 0; entity_block < n_entity_blocks; ++entity_block)
2533 unsigned long numNodes;
2535 if (gmsh_file_format < 40)
2537 numNodes = n_vertices;
2544 int tagEntity, dimEntity;
2545 in >> tagEntity >> dimEntity >> parametric >> numNodes;
2548 std::vector<int> vertex_numbers;
2550 if (gmsh_file_format > 40)
2551 for (
unsigned long vertex_per_entity = 0;
2552 vertex_per_entity < numNodes;
2553 ++vertex_per_entity)
2555 in >> vertex_number;
2556 vertex_numbers.push_back(vertex_number);
2559 for (
unsigned long vertex_per_entity = 0; vertex_per_entity < numNodes;
2560 ++vertex_per_entity, ++global_vertex)
2566 if (gmsh_file_format > 40)
2568 vertex_number = vertex_numbers[vertex_per_entity];
2569 in >> x[0] >> x[1] >> x[2];
2572 in >> vertex_number >> x[0] >> x[1] >> x[2];
2575 global_vertex < n_vertices,
2577 "The Gmsh file lists more nodes than were declared in the "
2578 "header of the @f$Nodes section."));
2580 for (
unsigned int d = 0; d < spacedim; ++d)
2581 vertices[global_vertex][d] = x[d];
2586 if (parametric != 0)
2601 const std::array<std::string, 2> end_nodes_marker{{
"@f$ENDNOD",
"@f$EndNodes"}};
2602 AssertThrow(line == end_nodes_marker[gmsh_file_format == 10 ? 0 : 1],
2603 ExcInvalidGMSHInput(line));
2607 const std::array<std::string, 2> begin_elements_marker{{
"@f$ELM",
"@f$Elements"}};
2608 AssertThrow(line == begin_elements_marker[gmsh_file_format == 10 ? 0 : 1],
2609 ExcInvalidGMSHInput(line));
2612 if (gmsh_file_format > 40)
2616 in >> n_entity_blocks >> n_cells >> min_node_tag >> max_node_tag;
2618 else if (gmsh_file_format == 40)
2620 in >> n_entity_blocks >> n_cells;
2624 n_entity_blocks = 1;
2631 std::vector<CellData<dim>> cells;
2633 std::map<unsigned int, types::boundary_id> boundary_ids_1d;
2639 std::map<unsigned int, unsigned int> vertex_counts;
2642 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
2643 {0, 1, 5, 4, 2, 3, 7, 6}};
2644 unsigned int global_cell = 0;
2645 for (
int entity_block = 0; entity_block < n_entity_blocks; ++entity_block)
2647 unsigned int material_id;
2648 unsigned long numElements;
2651 if (gmsh_file_format < 40)
2655 numElements = n_cells;
2657 else if (gmsh_file_format == 40)
2660 unsigned int dimEntity;
2661 in >> tagEntity >> dimEntity >> cell_type >> numElements;
2663 ExcInvalidGMSHInput(std::to_string(dimEntity)));
2664 material_id = tag_maps[dimEntity][tagEntity];
2670 unsigned int dimEntity;
2671 in >> dimEntity >> tagEntity >> cell_type >> numElements;
2673 ExcInvalidGMSHInput(std::to_string(dimEntity)));
2674 material_id = tag_maps[dimEntity][tagEntity];
2677 for (
unsigned int cell_per_entity = 0; cell_per_entity < numElements;
2678 ++cell_per_entity, ++global_cell)
2687 unsigned int nod_num;
2708 unsigned int elm_number = 0;
2709 if (gmsh_file_format < 40)
2715 if (gmsh_file_format < 20)
2721 else if (gmsh_file_format < 40)
2726 unsigned int n_tags;
2733 for (
unsigned int i = 1; i < n_tags; ++i)
2738 else if (cell_type == 2)
2740 else if (cell_type == 3)
2742 else if (cell_type == 4)
2744 else if (cell_type == 5)
2755 else if (cell_type == 2)
2757 else if (cell_type == 3)
2759 else if (cell_type == 4)
2761 else if (cell_type == 5)
2787 if (((cell_type == 1) && (dim == 1)) ||
2788 ((cell_type == 2) && (dim == 2)) ||
2789 ((cell_type == 3) && (dim == 2)) ||
2790 ((cell_type == 4) && (dim == 3)) ||
2791 ((cell_type == 5) && (dim == 3)))
2794 unsigned int vertices_per_cell = 0;
2796 vertices_per_cell = 2;
2797 else if (cell_type == 2)
2798 vertices_per_cell = 3;
2799 else if (cell_type == 3)
2800 vertices_per_cell = 4;
2801 else if (cell_type == 4)
2802 vertices_per_cell = 4;
2803 else if (cell_type == 5)
2804 vertices_per_cell = 8;
2808 "Number of nodes does not coincide with the "
2809 "number required for this object"));
2812 cells.emplace_back();
2815 for (
unsigned int i = 0; i < vertices_per_cell; ++i)
2818 if (vertices_per_cell ==
2821 local_vertex_numbering[i] :
2829 std::numeric_limits<types::material_id>::max(),
2833 std::numeric_limits<types::material_id>::max()));
2844 for (
unsigned int i = 0; i < vertices_per_cell; ++i)
2848 ExcInvalidVertexIndexGmsh(cell_per_entity,
2853 if constexpr (dim == 1)
2854 vertex_counts[vertex] += 1u;
2858 else if ((cell_type == 1) &&
2859 ((dim == 2) || (dim == 3)))
2868 std::numeric_limits<types::boundary_id>::max(),
2872 std::numeric_limits<types::boundary_id>::max()));
2885 for (
unsigned int &vertex :
2894 ExcInvalidVertexIndex(cell_per_entity,
2899 else if ((cell_type == 2 || cell_type == 3) &&
2903 unsigned int vertices_per_cell = 0;
2906 vertices_per_cell = 3;
2907 else if (cell_type == 3)
2908 vertices_per_cell = 4;
2916 for (
unsigned int i = 0; i < vertices_per_cell; ++i)
2921 std::numeric_limits<types::boundary_id>::max(),
2925 std::numeric_limits<types::boundary_id>::max()));
2938 for (
unsigned int &vertex :
2947 ExcInvalidVertexIndex(cell_per_entity,
2952 else if (cell_type == 15)
2955 unsigned int node_index = 0;
2956 if (gmsh_file_format < 20)
2971 if constexpr (dim == 1)
2976 AssertThrow(
false, ExcGmshUnsupportedGeometry(cell_type));
2984 const std::array<std::string, 2> end_elements_marker{
2985 {
"@f$ENDELM",
"@f$EndElements"}};
2986 AssertThrow(line == end_elements_marker[gmsh_file_format == 10 ? 0 : 1],
2987 ExcInvalidGMSHInput(line));
2999 if constexpr (dim == 1)
3000 for (
const auto &pair : vertex_counts)
3001 if (pair.second == 1u)
3002 boundary_id_pairs.emplace_back(vertices[pair.first],
3003 boundary_ids_1d[pair.first]);
3005 apply_grid_fixup_functions(vertices, cells, subcelldata);
3006 tria->create_triangulation(vertices, cells, subcelldata);
3010 if constexpr (dim == 1)
3011 assign_1d_boundary_ids(boundary_id_pairs, *tria);
3016template <
int dim,
int spacedim>
3020#ifdef DEAL_II_GMSH_WITH_API
3021 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
3023 const std::map<int, std::uint8_t> gmsh_to_dealii_type = {
3024 {{15, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {7, 5}, {6, 6}, {5, 7}}};
3027 const std::array<std::vector<unsigned int>, 8> gmsh_to_dealii = {
3034 {{0, 1, 2, 3, 4, 5}},
3035 {{0, 1, 3, 2, 4, 5, 7, 6}}}};
3037 std::vector<Point<spacedim>> vertices;
3038 std::vector<CellData<dim>> cells;
3040 std::map<unsigned int, types::boundary_id> boundary_ids_1d;
3046 std::map<unsigned int, unsigned int> vertex_counts;
3048# if DEAL_II_GMSH_WITH_API_VERSION_GTE(4, 9, 4)
3050 ExcMessage(
"The GMSH API may only be called after GMSH is "
3051 "initialized, e.g., via the InitFinalize or "
3052 "MPI_InitFinalize classes or the gmsh::initialize() "
3055 gmsh::option::setNumber(
"General.Verbosity", 0);
3060 ExcMessage(
"You are trying to read a gmsh file with dimension " +
3061 std::to_string(gmsh::model::getDimension()) +
3062 " into a grid of dimension " + std::to_string(dim)));
3067 gmsh::model::mesh::removeDuplicateNodes();
3068 gmsh::model::mesh::renumberNodes();
3069 std::vector<std::size_t> node_tags;
3070 std::vector<double> coord;
3071 std::vector<double> parametricCoord;
3072 gmsh::model::mesh::getNodes(
3073 node_tags, coord, parametricCoord, -1, -1,
false,
false);
3074 vertices.resize(node_tags.size());
3075 for (
unsigned int i = 0; i < node_tags.size(); ++i)
3079 for (
unsigned int d = 0; d < spacedim; ++d)
3080 vertices[i][d] = coord[i * 3 + d];
3084 for (
unsigned int d = spacedim; d < 3; ++d)
3087 "The grid you are reading contains nodes that are "
3088 "nonzero in the coordinate with index " +
3090 ", but you are trying to save "
3091 "it on a grid embedded in a " +
3092 std::to_string(spacedim) +
" dimensional space."));
3099 std::vector<std::pair<int, int>> entities;
3100 gmsh::model::getEntities(entities);
3102 for (
const auto &[entity_dim, entity_tag] : entities)
3111 std::vector<int> physical_tags;
3112 gmsh::model::getPhysicalGroupsForEntity(entity_dim,
3117 if (physical_tags.size())
3118 for (
auto physical_tag : physical_tags)
3121 gmsh::model::getPhysicalName(entity_dim, physical_tag, name);
3128 std::map<std::string, int> id_names;
3130 bool found_unrecognized_tag =
false;
3131 bool found_boundary_id =
false;
3134 for (
const auto &[name,
id] : id_names)
3136 if (entity_dim == dim && name ==
"MaterialID")
3139 found_boundary_id =
true;
3141 else if (entity_dim < dim && name ==
"BoundaryID")
3144 found_boundary_id =
true;
3146 else if (name ==
"ManifoldID")
3152 found_unrecognized_tag =
true;
3157 if (found_unrecognized_tag && !found_boundary_id)
3158 boundary_id = physical_tag;
3166 boundary_id = physical_tag;
3172 std::vector<int> element_types;
3173 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3174 gmsh::model::mesh::getElements(
3175 element_types, element_ids, element_nodes, entity_dim, entity_tag);
3177 for (
unsigned int i = 0; i < element_types.size(); ++i)
3179 const auto &type = gmsh_to_dealii_type.at(element_types[i]);
3180 const auto n_vertices = gmsh_to_dealii[type].size();
3181 const auto &elements = element_ids[i];
3182 const auto &nodes = element_nodes[i];
3183 for (
unsigned int j = 0; j < elements.size(); ++j)
3185 if (entity_dim == dim)
3187 cells.emplace_back(n_vertices);
3188 auto &cell = cells.back();
3189 for (
unsigned int v = 0; v < n_vertices; ++v)
3192 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3193 if constexpr (dim == 1)
3194 vertex_counts[cell.vertices[v]] += 1u;
3196 cell.manifold_id = manifold_id;
3197 cell.material_id = boundary_id;
3199 else if (entity_dim == 2)
3203 for (
unsigned int v = 0; v < n_vertices; ++v)
3205 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3207 face.manifold_id = manifold_id;
3208 face.boundary_id = boundary_id;
3210 else if (entity_dim == 1)
3214 for (
unsigned int v = 0; v < n_vertices; ++v)
3216 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3218 line.manifold_id = manifold_id;
3219 line.boundary_id = boundary_id;
3221 else if (entity_dim == 0)
3225 for (
unsigned int j = 0; j < elements.size(); ++j)
3226 boundary_ids_1d[nodes[j] - 1] = boundary_id;
3236 if constexpr (dim == 1)
3237 for (
const auto &pair : vertex_counts)
3238 if (pair.second == 1u)
3239 boundary_id_pairs.emplace_back(vertices[pair.first],
3240 boundary_ids_1d[pair.first]);
3242 apply_grid_fixup_functions(vertices, cells, subcelldata);
3243 tria->create_triangulation(vertices, cells, subcelldata);
3247 if constexpr (dim == 1)
3248 assign_1d_boundary_ids(boundary_id_pairs, *tria);
3259template <
int dim,
int spacedim>
3262 const std::string &file_suffix)
3264#ifdef DEAL_II_GMSH_WITH_API
3265 auto *parallel_tria =
3271 ExcMessage(
"Triangulation is not fully distributed!"));
3274 MPI_Comm mpi_comm = parallel_tria->get_mpi_communicator();
3280 file_prefix +
"_" + std::to_string(rank + 1) +
"." + file_suffix;
3284 fname = file_prefix +
"." + file_suffix;
3291 for (
unsigned int i = 1; i <= nprocs; ++i)
3293 const std::string check_fname =
3294 file_prefix +
"_" + std::to_string(i) +
"." + file_suffix;
3297 ExcMessage(
"Missing mesh file: " + check_fname));
3300 const std::string extra_fname =
3301 file_prefix +
"_" + std::to_string(nprocs + 1) +
"." + file_suffix;
3302 AssertThrow(!std::filesystem::exists(extra_fname),
3303 ExcMessage(
"Expected " + std::to_string(nprocs) +
3304 " mesh files, but found extra: " + extra_fname));
3307 const std::map<int, std::uint8_t> gmsh_to_dealii_type = {
3308 {15, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {7, 5}, {6, 6}, {5, 7}};
3310 const std::array<std::vector<unsigned int>, 8> gmsh_to_dealii = {
3318 {0, 1, 3, 2, 4, 5, 7, 6}}};
3320# if DEAL_II_GMSH_WITH_API_VERSION_GTE(4, 9, 4)
3322 ExcMessage(
"The GMSH API may only be called after GMSH is "
3323 "initialized, e.g., via the InitFinalize or "
3324 "MPI_InitFinalize classes or the gmsh::initialize() "
3327 gmsh::option::setNumber(
"General.Verbosity", 0);
3331 std::map<unsigned long, unsigned int> ghost_map;
3333 std::vector<std::pair<int, int>> entities;
3334 gmsh::model::getEntities(entities);
3336 for (
const auto &e : entities)
3338 const int entity_dim = e.first;
3339 const int entity_tag = e.second;
3341 if (entity_dim == dim)
3343 std::vector<std::size_t> element_tags;
3344 std::vector<int> partitions;
3346 gmsh::model::mesh::getGhostElements(entity_dim,
3351 for (std::size_t i = 0; i < element_tags.size(); ++i)
3352 ghost_map[element_tags[i]] =
3353 static_cast<unsigned int>(partitions[i] - 1);
3357 std::vector<std::size_t> node_tags;
3358 std::vector<double> coords, parametric_coords;
3359 gmsh::model::mesh::getNodes(node_tags, coords, parametric_coords);
3362 triangulation_description;
3363 triangulation_description.
comm = mpi_comm;
3365 triangulation_description.
cell_infos.resize(1);
3369 std::map<std::size_t, unsigned int> node_tag_to_index;
3370 for (
unsigned int i = 0; i < node_tags.size(); ++i)
3372 node_tag_to_index[node_tags[i]] = i;
3373 for (
unsigned int d = 0; d < spacedim; ++d)
3383 std::vector<std::pair<int, int>> physical_groups;
3384 gmsh::model::getPhysicalGroups(physical_groups);
3386 for (
const auto &[physical_dim, physical_tag] : physical_groups)
3388 std::vector<int> physical_entities;
3389 gmsh::model::getEntitiesForPhysicalGroup(physical_dim,
3393 for (
const int ent : physical_entities)
3396 if (physical_dim == dim - 1)
3397 entity_to_boundary[{physical_dim, ent}] = physical_tag;
3398 if (physical_dim == dim)
3399 entity_to_material[{physical_dim, ent}] = physical_tag;
3408 for (
const auto &e : entities)
3409 if (e.first == dim - 1)
3410 if (
auto it = entity_to_boundary.find({e.first, e.second});
3411 it != entity_to_boundary.end())
3415 std::vector<int> element_types;
3416 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3419 gmsh::model::mesh::getElements(
3420 element_types, element_ids, element_nodes, e.first, e.second);
3422 for (
unsigned int i = 0; i < element_types.size(); ++i)
3424 if (element_ids[i].empty())
3427 const unsigned int n_nodes_per_elem =
3428 element_nodes[i].size() / element_ids[i].size();
3430 for (
unsigned int j = 0; j < element_ids[i].size(); ++j)
3432 std::set<unsigned int> face_vertices;
3433 for (
unsigned int k = 0; k < n_nodes_per_elem; ++k)
3435 std::size_t node_tag =
3436 element_nodes[i][j * n_nodes_per_elem + k];
3437 face_vertices.insert(node_tag_to_index[node_tag]);
3442 boundary_face_map[face_vertices] = boundary_id;
3450 std::size_t total_volume_elements = 0;
3451 for (
const auto &[entity_dim, entity_tag] : entities)
3453 if (entity_dim == dim)
3455 std::vector<int> count_element_types;
3456 std::vector<std::vector<std::size_t>> count_element_ids,
3457 count_element_nodes;
3459 gmsh::model::mesh::getElements(count_element_types,
3461 count_element_nodes,
3465 for (
const auto &count_element_id : count_element_ids)
3466 total_volume_elements += count_element_id.size();
3471 triangulation_description.
coarse_cells.reserve(total_volume_elements);
3473 total_volume_elements);
3474 triangulation_description.
cell_infos[0].reserve(total_volume_elements);
3476 for (
const auto &[entity_dim, entity_tag] : entities)
3478 if (entity_dim == dim)
3480 std::vector<int> element_types;
3481 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3483 gmsh::model::mesh::getElements(
3484 element_types, element_ids, element_nodes, entity_dim, entity_tag);
3486 for (
unsigned int i = 0; i < element_types.size(); ++i)
3488 if (element_ids[i].empty())
3491 const unsigned int n_vertices =
3492 element_nodes[i].size() / element_ids[i].size();
3494 for (
unsigned int j = 0; j < element_ids[i].size(); ++j)
3497 if (
auto it = entity_to_material.find({dim, entity_tag});
3498 it != entity_to_material.end())
3501 const auto &type = gmsh_to_dealii_type.at(element_types[i]);
3503 for (
unsigned int v = 0; v < n_vertices; ++v)
3505 const std::size_t node_tag =
3507 [j * n_vertices + gmsh_to_dealii[type][v]];
3509 node_tag_to_index.end(),
3511 std::to_string(node_tag) +
3512 " not found in node list!"));
3513 cell.
vertices[v] = node_tag_to_index[node_tag];
3518 CellId(element_ids[i][j], {}).
template to_binary<dim>();
3520 auto it = ghost_map.find(element_ids[i][j]);
3521 if (it != ghost_map.end())
3530 if constexpr (dim > 0)
3534 ReferenceCells::n_vertices_to_reference_cell<dim>(
3538 const unsigned int n_faces = ref_cell.
n_faces();
3540 for (
unsigned int f = 0; f < n_faces; ++f)
3542 std::set<unsigned int> face_vertices;
3544 if constexpr (dim == 1)
3547 face_vertices.insert(cell.
vertices[f]);
3549 else if constexpr (dim == 2)
3556 face_vertices.insert(cell.
vertices[f]);
3557 face_vertices.insert(
3560 else if (ref_cell ==
3563 const unsigned int n_face_vertices =
3566 for (
unsigned int fv = 0;
3567 fv < n_face_vertices;
3570 const unsigned int vertex_index =
3575 default_geometric_orientation);
3576 face_vertices.insert(
3581 else if constexpr (dim == 3)
3584 const unsigned int n_face_vertices =
3586 for (
unsigned int fv = 0; fv < n_face_vertices;
3589 const unsigned int vertex_index =
3594 face_vertices.insert(
3600 if (
auto it = boundary_face_map.find(face_vertices);
3601 it != boundary_face_map.end())
3606 triangulation_description.
coarse_cells.push_back(cell);
3608 .push_back(element_ids[i][j]);
3609 triangulation_description.
cell_infos[0].push_back(cell_info);
3615 triangulation_description.
settings =
3618 parallel_tria->create_triangulation(triangulation_description);
3621# ifdef DEAL_II_WITH_MPI
3622 const int mpi_ierr = MPI_Barrier(mpi_comm);
3635template <
int dim,
int spacedim>
3638 std::string &header,
3639 std::vector<unsigned int> &tecplot2deal,
3640 unsigned int &n_vars,
3641 unsigned int &n_vertices,
3642 unsigned int &n_cells,
3643 std::vector<unsigned int> &IJK,
3668 std::transform(header.begin(),
3671 static_cast<int (*)(
int)
>(std::toupper));
3675 std::replace(header.begin(), header.end(),
'\t',
' ');
3676 std::replace(header.begin(), header.end(),
',',
' ');
3677 std::replace(header.begin(), header.end(),
'\n',
' ');
3681 std::string::size_type pos = header.find(
'=');
3683 while (pos !=
static_cast<std::string::size_type
>(std::string::npos))
3684 if (header[pos + 1] ==
' ')
3685 header.erase(pos + 1, 1);
3686 else if (header[pos - 1] ==
' ')
3688 header.erase(pos - 1, 1);
3692 pos = header.find(
'=', ++pos);
3695 std::vector<std::string> entries =
3699 for (
unsigned int i = 0; i < entries.size(); ++i)
3708 tecplot2deal[0] = 0;
3711 while (entries[i][0] ==
'"')
3713 if (entries[i] ==
"\"X\"")
3714 tecplot2deal[0] = n_vars;
3715 else if (entries[i] ==
"\"Y\"")
3720 if constexpr (dim > 1)
3721 tecplot2deal[1] = n_vars;
3723 else if (entries[i] ==
"\"Z\"")
3728 if constexpr (dim > 2)
3729 tecplot2deal[2] = n_vars;
3741 "Tecplot file must contain at least one variable for each dimension"));
3742 for (
unsigned int d = 1; d < dim; ++d)
3744 tecplot2deal[d] > 0,
3746 "Tecplot file must contain at least one variable for each dimension."));
3751 "ZONETYPE=FELINESEG") &&
3755 "ZONETYPE=FEQUADRILATERAL") &&
3759 "ZONETYPE=FEBRICK") &&
3767 "The tecplot file contains an unsupported ZONETYPE."));
3770 "DATAPACKING=POINT"))
3773 "DATAPACKING=BLOCK"))
3796 "ET=QUADRILATERAL") &&
3808 "The tecplot file contains an unsupported ElementType."));
3816 dim > 1 || IJK[1] == 1,
3818 "Parameter 'J=' found in tecplot, although this is only possible for dimensions greater than 1."));
3824 dim > 2 || IJK[2] == 1,
3826 "Parameter 'K=' found in tecplot, although this is only possible for dimensions greater than 2."));
3841 for (
unsigned int d = 0; d < dim; ++d)
3846 "Tecplot file does not contain a complete and consistent set of parameters"));
3847 n_vertices *= IJK[d];
3848 n_cells *= (IJK[d] - 1);
3856 "Tecplot file does not contain a complete and consistent set of parameters"));
3862 n_cells = *std::max_element(IJK.begin(), IJK.end());
3866 "Tecplot file does not contain a complete and consistent set of parameters"));
3876 const unsigned int dim = 2;
3877 const unsigned int spacedim = 2;
3878 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
3882 skip_comment_lines(in,
'#');
3885 std::string line, header;
3892 std::string letters =
"abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ";
3895 while (line.find_first_of(letters) != std::string::npos)
3897 header +=
" " + line;
3904 std::vector<unsigned int> tecplot2deal(dim);
3905 std::vector<unsigned int> IJK(dim);
3906 unsigned int n_vars, n_vertices, n_cells;
3907 bool structured, blocked;
3909 parse_tecplot_header(header,
3924 std::vector<Point<spacedim>> vertices(n_vertices + 1);
3927 std::vector<CellData<dim>> cells(n_cells);
3943 unsigned int next_index = 0;
3947 if (tecplot2deal[0] == 0)
3951 std::vector<std::string> first_var =
3954 for (
unsigned int i = 1; i < first_var.size() + 1; ++i)
3955 vertices[i][0] = std::strtod(first_var[i - 1].c_str(), &endptr);
3960 for (
unsigned int j = first_var.size() + 1; j < n_vertices + 1; ++j)
3961 in >> vertices[j][next_index];
3968 for (
unsigned int i = 1; i < n_vars; ++i)
3977 if (next_index == dim && structured)
3980 if ((next_index < dim) && (i == tecplot2deal[next_index]))
3983 for (
unsigned int j = 1; j < n_vertices + 1; ++j)
3984 in >> vertices[j][next_index];
3991 for (
unsigned int j = 1; j < n_vertices + 1; ++j)
4003 std::vector<double> vars(n_vars);
4008 std::vector<std::string> first_vertex =
4011 for (
unsigned int d = 0; d < dim; ++d)
4013 std::strtod(first_vertex[tecplot2deal[d]].c_str(), &endptr);
4017 for (
unsigned int v = 2; v < n_vertices + 1; ++v)
4019 for (
unsigned int i = 0; i < n_vars; ++i)
4025 for (
unsigned int i = 0; i < dim; ++i)
4026 vertices[v][i] = vars[tecplot2deal[i]];
4034 unsigned int I = IJK[0], J = IJK[1];
4036 unsigned int cell = 0;
4038 for (
unsigned int j = 0; j < J - 1; ++j)
4039 for (
unsigned int i = 1; i < I; ++i)
4041 cells[cell].vertices[0] = i + j * I;
4042 cells[cell].vertices[1] = i + 1 + j * I;
4043 cells[cell].vertices[2] = i + (j + 1) * I;
4044 cells[cell].vertices[3] = i + 1 + (j + 1) * I;
4048 std::vector<unsigned int> boundary_vertices(2 * I + 2 * J - 4);
4050 for (
unsigned int i = 1; i < I + 1; ++i)
4052 boundary_vertices[k] = i;
4054 boundary_vertices[k] = i + (J - 1) * I;
4057 for (
unsigned int j = 1; j < J - 1; ++j)
4059 boundary_vertices[k] = 1 + j * I;
4061 boundary_vertices[k] = I + j * I;
4080 for (
unsigned int i = 0; i < n_cells; ++i)
4097 apply_grid_fixup_functions(vertices, cells, subcelldata);
4098 tria->create_triangulation(vertices, cells, subcelldata);
4103template <
int dim,
int spacedim>
4112template <
int dim,
int spacedim>
4115 const unsigned int mesh_index,
4116 const bool remove_duplicates,
4118 const bool ignore_unsupported_types)
4120#ifdef DEAL_II_WITH_ASSIMP
4125 Assimp::Importer importer;
4128 const aiScene *scene =
4129 importer.ReadFile(filename.c_str(),
4130 aiProcess_RemoveComponent |
4131 aiProcess_JoinIdenticalVertices |
4132 aiProcess_ImproveCacheLocality | aiProcess_SortByPType |
4133 aiProcess_OptimizeGraph | aiProcess_OptimizeMeshes);
4139 ExcMessage(
"Input file contains no meshes."));
4142 (mesh_index < scene->mNumMeshes),
4145 unsigned int start_mesh =
4147 unsigned int end_mesh =
4152 std::vector<Point<spacedim>> vertices;
4153 std::vector<CellData<dim>> cells;
4157 unsigned int v_offset = 0;
4158 unsigned int c_offset = 0;
4160 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
4161 {0, 1, 5, 4, 2, 3, 7, 6}};
4163 for (
unsigned int m = start_mesh; m < end_mesh; ++m)
4165 const aiMesh *mesh = scene->mMeshes[m];
4169 if ((dim == 2) && mesh->mPrimitiveTypes != aiPrimitiveType_POLYGON)
4172 ExcMessage(
"Incompatible mesh " + std::to_string(m) +
4173 "/" + std::to_string(scene->mNumMeshes)));
4176 else if ((dim == 1) && mesh->mPrimitiveTypes != aiPrimitiveType_LINE)
4179 ExcMessage(
"Incompatible mesh " + std::to_string(m) +
4180 "/" + std::to_string(scene->mNumMeshes)));
4184 const unsigned int n_vertices = mesh->mNumVertices;
4185 const aiVector3D *mVertices = mesh->mVertices;
4188 const unsigned int n_faces = mesh->mNumFaces;
4189 const aiFace *mFaces = mesh->mFaces;
4191 vertices.resize(v_offset + n_vertices);
4192 cells.resize(c_offset + n_faces);
4194 for (
unsigned int i = 0; i < n_vertices; ++i)
4195 for (
unsigned int d = 0; d < spacedim; ++d)
4196 vertices[i + v_offset][d] = mVertices[i][d];
4198 unsigned int valid_cell = c_offset;
4199 for (
unsigned int i = 0; i < n_faces; ++i)
4206 .vertices[dim == 3 ? local_vertex_numbering[f] :
4208 mFaces[i].mIndices[f] + v_offset;
4210 cells[valid_cell].material_id = m;
4216 ExcMessage(
"Face " + std::to_string(i) +
" of mesh " +
4217 std::to_string(m) +
" has " +
4218 std::to_string(mFaces[i].mNumIndices) +
4219 " vertices. We expected only " +
4224 cells.resize(valid_cell);
4229 v_offset += n_vertices;
4230 c_offset = valid_cell;
4237 if (remove_duplicates)
4242 unsigned int n_verts = 0;
4243 while (n_verts != vertices.size())
4245 n_verts = vertices.size();
4246 std::vector<unsigned int> considered_vertices;
4248 vertices, cells, subcelldata, considered_vertices, tol);
4252 apply_grid_fixup_functions(vertices, cells, subcelldata);
4253 tria->create_triangulation(vertices, cells, subcelldata);
4258 (void)remove_duplicates;
4260 (void)ignore_unsupported_types;
4267template <
int dim,
int spacedim>
4272 ExcMessage(
"The ugrid format reader currently supports only 2- and "
4273 "3-dimensional meshes."));
4274 Assert(tria !=
nullptr, ExcNoTriangulationSelected());
4281 unsigned int n_nodes, n_tris, n_quads, n_tets, n_pyramids, n_wedges, n_hexes;
4282 in >> n_nodes >> n_tris >> n_quads >> n_tets >> n_pyramids >> n_wedges >>
4284 if constexpr (dim == 2)
4286 n_tris + n_quads > 0,
4288 "When reading a 2-dimensional triangulation, "
4289 "there need to be more than zero triangles or quadrilaterals."));
4291 AssertThrow(n_tets + n_pyramids + n_wedges + n_hexes > 0,
4292 ExcMessage(
"When reading a 3-dimensional triangulation, "
4293 "there need to be more than zero tetrahedra, "
4294 "pyramids, wedges, or hexahedra."));
4297 std::vector<Point<spacedim>> vertices(n_nodes);
4304 for (
unsigned int d = spacedim; d < 3; ++d)
4311 "You are reading a mesh in spacedim=" + std::to_string(spacedim) +
4312 " but some of the vertex positions have trailing coordinates "
4313 "that are not zero."));
4318 std::vector<CellData<2>> objects_2d;
4319 objects_2d.reserve(n_tris + n_quads);
4320 for (
unsigned int i = 0; i < n_tris; ++i)
4326 for (
unsigned int &vertex_index :
object.vertices)
4331 objects_2d.emplace_back(
object);
4333 for (
unsigned int i = 0; i < n_quads; ++i)
4338 "Reading quadrilaterals is not currently implemented by the ugrid "
4339 "reader because we do not know the order of vertices and have no example "
4340 "to look at. If you have a test file, please contact us and/or help us "
4341 "implement this missing case."));
4348 for (
auto &
object : objects_2d)
4349 if constexpr (dim == 2)
4350 in >>
object.material_id;
4352 in >>
object.boundary_id;
4356 std::vector<CellData<3>> objects_3d;
4357 objects_3d.reserve(n_tets + n_pyramids + n_wedges + n_hexes);
4358 for (
unsigned int i = 0; i < n_tets; ++i)
4363 "Reading tetrahedra is not currently implemented by the ugrid "
4364 "reader because we do not know the order of vertices and have no example "
4365 "to look at. If you have a test file, please contact us and/or help us "
4366 "implement this missing case."));
4368 for (
unsigned int i = 0; i < n_pyramids; ++i)
4373 "Reading pyramids is not currently implemented by the ugrid "
4374 "reader because we do not know the order of vertices and have no example "
4375 "to look at. If you have a test file, please contact us and/or help us "
4376 "implement this missing case."));
4378 for (
unsigned int i = 0; i < n_wedges; ++i)
4383 "Reading wedges is not currently implemented by the ugrid "
4384 "reader because we do not know the order of vertices and have no example "
4385 "to look at. If you have a test file, please contact us and/or help us "
4386 "implement this missing case."));
4388 for (
unsigned int i = 0; i < n_hexes; ++i)
4393 "Reading hexahdrea is not currently implemented by the ugrid "
4394 "reader because we do not know the order of vertices and have no example "
4395 "to look at. If you have a test file, please contact us and/or help us "
4396 "implement this missing case."));
4419 unsigned int n_lines;
4421 std::vector<CellData<1>> objects_1d(n_lines);
4424 line.vertices.resize(2);
4427 for (
unsigned int &vertex_index : line.vertices)
4434 in >> line.boundary_id;
4438 if constexpr (dim == 2)
4442 tria->create_triangulation(vertices, objects_2d, face_data);
4450#ifdef DEAL_II_TRILINOS_WITH_SEACAS
4459 exodusii_name_to_type(
const std::string &type_name,
4460 const int n_nodes_per_element)
4466 std::string type_name_2 = type_name;
4467 std::transform(type_name_2.begin(),
4469 type_name_2.begin(),
4470 static_cast<int (*)(
int)
>(std::toupper));
4471 const std::string
numbers =
"0123456789";
4472 type_name_2.erase(std::find_first_of(type_name_2.begin(),
4479 if constexpr (dim == 1)
4481 if (type_name_2 ==
"BAR" || type_name_2 ==
"BEAM" ||
4482 type_name_2 ==
"EDGE" || type_name_2 ==
"TRUSS")
4485 else if constexpr (dim == 2)
4487 if (type_name_2 ==
"TRI" || type_name_2 ==
"TRIANGLE")
4489 else if (type_name_2 ==
"QUAD" || type_name_2 ==
"QUADRILATERAL")
4491 else if (type_name_2 ==
"SHELL")
4493 if (n_nodes_per_element == 3)
4499 else if constexpr (dim == 3)
4501 if (type_name_2 ==
"TET" || type_name_2 ==
"TETRA" ||
4502 type_name_2 ==
"TETRAHEDRON")
4504 else if (type_name_2 ==
"PYRA" || type_name_2 ==
"PYRAMID")
4506 else if (type_name_2 ==
"WEDGE")
4508 else if (type_name_2 ==
"HEX" || type_name_2 ==
"HEXAHEDRON")
4512 return ReferenceCells::Invalid<dim>;
4518 template <
int dim,
int spacedim = dim>
4519 std::pair<SubCellData, std::vector<std::vector<int>>>
4520 read_exodusii_sidesets(
const int ex_id,
4521 const int n_sidesets,
4523 const bool apply_all_indicators_to_manifolds)
4526 std::vector<std::vector<int>> b_or_m_id_to_sideset_ids;
4528 b_or_m_id_to_sideset_ids.emplace_back();
4534 if (dim == spacedim && n_sidesets > 0)
4536 std::vector<int> sideset_ids(n_sidesets);
4537 int ierr = ex_get_ids(ex_id, EX_SIDE_SET, sideset_ids.data());
4539 std::sort(sideset_ids.begin(), sideset_ids.end());
4546 std::size_t n_total_sides = 0;
4547 for (
const int &sideset_id : sideset_ids)
4550 int n_distribution_factors = -1;
4552 ierr = ex_get_set_param(ex_id,
4556 &n_distribution_factors);
4559 n_total_sides += std::size_t(n_sides);
4561 std::vector<std::pair<std::size_t, int>> face_sidesets;
4562 face_sidesets.reserve(n_total_sides);
4564 for (
const int &sideset_id : sideset_ids)
4567 int n_distribution_factors = -1;
4569 ierr = ex_get_set_param(ex_id,
4573 &n_distribution_factors);
4577 std::vector<int> elements(n_sides);
4578 std::vector<int> faces(n_sides);
4579 ierr = ex_get_set(ex_id,
4592 for (
int side_n = 0; side_n < n_sides; ++side_n)
4594 const long cell_n = elements[side_n] - 1;
4596 const long face_n = faces[side_n] - 1;
4598 const std::size_t face_id =
4599 cell_n * ReferenceCells::max_n_faces<dim>() + face_n;
4600 face_sidesets.emplace_back(face_id, sideset_id);
4605 std::sort(face_sidesets.begin(), face_sidesets.end());
4610 std::deque<ArrayView<std::pair<std::size_t, int>>>
4611 face_id_to_sideset_ids;
4612 if (face_sidesets.size() > 0)
4614 auto start = face_sidesets.begin();
4615 for (
auto it = face_sidesets.begin() + 1; it < face_sidesets.end();
4617 if (start->first != it->first)
4619 face_id_to_sideset_ids.emplace_back(
4623 face_id_to_sideset_ids.emplace_back(
4630 std::stable_sort(face_id_to_sideset_ids.begin(),
4631 face_id_to_sideset_ids.end(),
4632 [](
const auto &a,
const auto &b) {
4633 return std::lexicographical_compare(
4638 [](const auto &c, const auto &d) {
4639 return c.second < d.second;
4643 if constexpr (dim == 2)
4644 subcelldata.
boundary_lines.reserve(face_id_to_sideset_ids.size());
4645 else if constexpr (dim == 3)
4646 subcelldata.
boundary_quads.reserve(face_id_to_sideset_ids.size());
4648 std::vector<int> face_sideset_ids;
4649 for (
const auto &pairs : face_id_to_sideset_ids)
4651 const std::size_t face_id = pairs[0].first;
4652 Assert(std::all_of(pairs.begin(),
4654 [&](
const auto &a) {
4655 return a.first == face_id;
4658 face_sideset_ids.resize(pairs.size());
4659 for (std::size_t i = 0; i < pairs.size(); ++i)
4660 face_sideset_ids[i] = pairs[i].
second;
4662 if (face_sideset_ids != b_or_m_id_to_sideset_ids.back())
4667 Assert(std::find(b_or_m_id_to_sideset_ids.begin(),
4668 b_or_m_id_to_sideset_ids.end(),
4669 face_sideset_ids) ==
4670 b_or_m_id_to_sideset_ids.end(),
4672 ++current_b_or_m_id;
4673 b_or_m_id_to_sideset_ids.emplace_back(face_sideset_ids.begin(),
4674 face_sideset_ids.end());
4675 Assert(current_b_or_m_id == b_or_m_id_to_sideset_ids.size() - 1,
4679 const unsigned int local_face_n =
4680 face_id % ReferenceCells::max_n_faces<dim>();
4682 cells[face_id / ReferenceCells::max_n_faces<dim>()];
4684 ReferenceCells::n_vertices_to_reference_cell<dim>(
4686 const unsigned int deal_face_n =
4688 const auto face_reference_cell =
4694 if constexpr (dim == 2)
4696 CellData<1> boundary_line(face_reference_cell.n_vertices());
4697 if (apply_all_indicators_to_manifolds)
4698 boundary_line.manifold_id = current_b_or_m_id;
4700 boundary_line.boundary_id = current_b_or_m_id;
4701 for (
unsigned int j = 0; j < face_reference_cell.n_vertices();
4703 boundary_line.vertices[j] =
4705 deal_face_n, j, 0)];
4709 else if constexpr (dim == 3)
4711 CellData<2> boundary_quad(face_reference_cell.n_vertices());
4712 if (apply_all_indicators_to_manifolds)
4713 boundary_quad.manifold_id = current_b_or_m_id;
4715 boundary_quad.boundary_id = current_b_or_m_id;
4716 for (
unsigned int j = 0; j < face_reference_cell.n_vertices();
4718 boundary_quad.vertices[j] =
4720 deal_face_n, j, 0)];
4727 return std::make_pair(std::move(subcelldata),
4728 std::move(b_or_m_id_to_sideset_ids));
4733template <
int dim,
int spacedim>
4736 const std::string &filename,
4737 const bool apply_all_indicators_to_manifolds)
4739#ifdef DEAL_II_TRILINOS_WITH_SEACAS
4741 int component_word_size =
sizeof(double);
4743 int floating_point_word_size = 0;
4744 float ex_version = 0.0;
4746 const int ex_id = ex_open(filename.c_str(),
4748 &component_word_size,
4749 &floating_point_word_size,
4752 ExcMessage(
"ExodusII failed to open the specified input file."));
4755 std::vector<char> string_temp(MAX_LINE_LENGTH + 1,
'\0');
4756 int mesh_dimension = 0;
4759 int n_element_blocks = 0;
4763 int ierr = ex_get_init(ex_id,
4782 std::vector<Point<spacedim>> vertices;
4783 vertices.reserve(n_nodes);
4785 std::vector<double> xs(n_nodes);
4786 std::vector<double> ys(n_nodes);
4787 std::vector<double> zs(n_nodes);
4789 ierr = ex_get_coord(ex_id, xs.data(), ys.data(), zs.data());
4792 for (
int vertex_n = 0; vertex_n < n_nodes; ++vertex_n)
4797 vertices.emplace_back(xs[vertex_n]);
4800 vertices.emplace_back(xs[vertex_n], ys[vertex_n]);
4803 vertices.emplace_back(xs[vertex_n], ys[vertex_n], zs[vertex_n]);
4811 std::vector<int> element_block_ids(n_element_blocks);
4812 ierr = ex_get_ids(ex_id, EX_ELEM_BLOCK, element_block_ids.data());
4815 std::vector<CellData<dim>> cells;
4816 cells.reserve(n_elements);
4820 for (
const int element_block_id : element_block_ids)
4822 std::fill(string_temp.begin(), string_temp.end(),
'\0');
4823 int n_block_elements = 0;
4824 int n_nodes_per_element = 0;
4825 int n_edges_per_element = 0;
4826 int n_faces_per_element = 0;
4827 int n_attributes_per_element = 0;
4830 ierr = ex_get_block(ex_id,
4835 &n_nodes_per_element,
4836 &n_edges_per_element,
4837 &n_faces_per_element,
4838 &n_attributes_per_element);
4841 exodusii_name_to_type<dim>(string_temp.data(), n_nodes_per_element);
4844 "The ExodusII block " + std::to_string(element_block_id) +
4845 " with element type " + std::string(string_temp.data()) +
4846 " does not have a corresponding ReferenceCell<dim> with a"
4847 " dimension matching the topological mesh dimension " +
4848 std::to_string(dim) +
"."));
4855 std::vector<int> connection(n_nodes_per_element * n_block_elements);
4856 ierr = ex_get_conn(ex_id,
4864 for (
unsigned int elem_n = 0; elem_n < connection.size();
4865 elem_n += n_nodes_per_element)
4868 for (
const unsigned int i : type.vertex_indices())
4870 cell.
vertices[type.exodusii_vertex_to_deal_vertex(i)] =
4871 connection[elem_n + i] - 1;
4874 cells.push_back(std::move(cell));
4879 auto pair = read_exodusii_sidesets<dim, spacedim>(
4880 ex_id, n_sidesets, cells, apply_all_indicators_to_manifolds);
4881 ierr = ex_close(ex_id);
4884 apply_grid_fixup_functions(vertices, cells, pair.first);
4885 tria->create_triangulation(vertices, cells, pair.first);
4891 (void)apply_all_indicators_to_manifolds;
4898template <
int dim,
int spacedim>
4912 if (std::find_if(line.begin(), line.end(), [](
const char c) {
4917 for (
int i = line.size() - 1; i >= 0; --i)
4918 in.putback(line[i]);
4928template <
int dim,
int spacedim>
4931 const char comment_start)
4936 while (in.get(c) && c == comment_start)
4939 while (in.get() !=
'\n')
4949 skip_empty_lines(in);
4954template <
int dim,
int spacedim>
4969 const std::vector<
Point<2>> &vertices,
4972 double min_x = vertices[cells[0].vertices[0]][0],
4973 max_x = vertices[cells[0].vertices[0]][0],
4974 min_y = vertices[cells[0].vertices[0]][1],
4975 max_y = vertices[cells[0].vertices[0]][1];
4977 for (
unsigned int i = 0; i < cells.size(); ++i)
4979 for (
const auto vertex : cells[i].vertices)
4981 const Point<2> &p = vertices[vertex];
4993 out <<
"# cell " << i << std::endl;
4995 for (
const auto vertex : cells[i].vertices)
4996 center += vertices[vertex];
4999 out <<
"set label \"" << i <<
"\" at " << center[0] <<
',' << center[1]
5000 <<
" center" << std::endl;
5003 for (
unsigned int f = 0; f < 2; ++f)
5004 out <<
"set arrow from " << vertices[cells[i].vertices[f]][0] <<
','
5005 << vertices[cells[i].vertices[f]][1] <<
" to "
5006 << vertices[cells[i].vertices[(f + 1) % 4]][0] <<
','
5007 << vertices[cells[i].vertices[(f + 1) % 4]][1] << std::endl;
5009 for (
unsigned int f = 2; f < 4; ++f)
5010 out <<
"set arrow from " << vertices[cells[i].vertices[(f + 1) % 4]][0]
5011 <<
',' << vertices[cells[i].vertices[(f + 1) % 4]][1] <<
" to "
5012 << vertices[cells[i].vertices[f]][0] <<
','
5013 << vertices[cells[i].vertices[f]][1] << std::endl;
5019 <<
"set nokey" << std::endl
5020 <<
"pl [" << min_x <<
':' << max_x <<
"][" << min_y <<
':' << max_y
5021 <<
"] " << min_y << std::endl
5022 <<
"pause -1" << std::endl;
5030 const std::vector<
Point<3>> &vertices,
5033 for (
const auto &cell : cells)
5036 out << vertices[cell.
vertices[0]] << std::endl
5037 << vertices[cell.
vertices[1]] << std::endl
5041 out << vertices[cell.
vertices[1]] << std::endl
5042 << vertices[cell.
vertices[2]] << std::endl
5046 out << vertices[cell.
vertices[3]] << std::endl
5047 << vertices[cell.
vertices[2]] << std::endl
5051 out << vertices[cell.
vertices[0]] << std::endl
5052 << vertices[cell.
vertices[3]] << std::endl
5056 out << vertices[cell.
vertices[4]] << std::endl
5057 << vertices[cell.
vertices[5]] << std::endl
5061 out << vertices[cell.
vertices[5]] << std::endl
5062 << vertices[cell.
vertices[6]] << std::endl
5066 out << vertices[cell.
vertices[7]] << std::endl
5067 << vertices[cell.
vertices[6]] << std::endl
5071 out << vertices[cell.
vertices[4]] << std::endl
5072 << vertices[cell.
vertices[7]] << std::endl
5076 out << vertices[cell.
vertices[0]] << std::endl
5077 << vertices[cell.
vertices[4]] << std::endl
5081 out << vertices[cell.
vertices[1]] << std::endl
5082 << vertices[cell.
vertices[5]] << std::endl
5086 out << vertices[cell.
vertices[2]] << std::endl
5087 << vertices[cell.
vertices[6]] << std::endl
5091 out << vertices[cell.
vertices[3]] << std::endl
5092 << vertices[cell.
vertices[7]] << std::endl
5100template <
int dim,
int spacedim>
5107 if (format == Default)
5109 const std::string::size_type slashpos = filename.find_last_of(
'/');
5110 const std::string::size_type dotpos = filename.find_last_of(
'.');
5111 if (dotpos < filename.size() &&
5112 (dotpos > slashpos || slashpos == std::string::npos))
5114 std::string ext = filename.substr(dotpos + 1);
5115 format = parse_format(ext);
5119 if (format == assimp)
5121 read_assimp(filename);
5123 else if (format == exodusii)
5125 read_exodusii(filename);
5129 std::ifstream in(filename);
5135template <
int dim,
int spacedim>
5139 if (format == Default)
5140 format = default_format;
5186 ExcMessage(
"There is no read_assimp(istream &) function. "
5187 "Use the read_assimp(string &filename, ...) "
5188 "functions, instead."));
5193 ExcMessage(
"There is no read_exodusii(istream &) function. "
5194 "Use the read_exodusii(string &filename, ...) "
5195 "function, instead."));
5206template <
int dim,
int spacedim>
5237 return ".unknown_format";
5243template <
int dim,
int spacedim>
5247 if (format_name ==
"dbmesh")
5250 if (format_name ==
"exodusii")
5253 if (format_name ==
"msh")
5256 if (format_name ==
"unv")
5259 if (format_name ==
"vtk")
5262 if (format_name ==
"vtu")
5266 if (format_name ==
"inp")
5269 if (format_name ==
"ucd")
5272 if (format_name ==
"xda")
5275 if (format_name ==
"tecplot")
5278 if (format_name ==
"dat")
5281 if (format_name ==
"ugrid")
5284 if (format_name ==
"plt")
5303template <
int dim,
int spacedim>
5307 return "dbmesh|exodusii|msh|unv|vtk|vtu|ucd|abaqus|xda|tecplot|assimp|ugrid";
5314 template <
int dim,
int spacedim>
5315 Abaqus_to_UCD<dim, spacedim>::Abaqus_to_UCD()
5319 AssertThrow(spacedim == 1 || spacedim == 2 || spacedim == 3,
5329 from_string(T &t,
const std::string &s, std::ios_base &(*f)(std::ios_base &))
5331 std::istringstream iss(s);
5332 return !(iss >> f >> t).fail();
5339 extract_int(
const std::string &s)
5342 for (
const char c : s)
5344 if (std::isdigit(c) != 0)
5351 from_string(number, tmp, std::dec);
5358 extract_value(
const std::string &line,
const std::string &target)
5360 std::size_t pos = line.find(target);
5363 if (pos != std::string::npos)
5365 std::size_t value_start = pos + target.length();
5366 std::size_t comma_pos = line.find(
',', value_start);
5370 if (comma_pos != std::string::npos)
5372 return line.substr(value_start, comma_pos - value_start);
5376 std::string result = line.substr(value_start);
5378 while (!result.empty() &&
5379 !std::isalnum(
static_cast<unsigned char>(result.back())))
5395 template <
int dim,
int spacedim>
5397 Abaqus_to_UCD<dim, spacedim>::get_reference_cell_from_element_type(
5398 const std::string &type_string)
5400 if constexpr (dim == 1)
5402 if (type_string ==
"B31")
5404 if (type_string ==
"B31R")
5406 return ReferenceCells::Invalid<1>;
5408 else if constexpr (dim == 2)
5410 if (type_string ==
"S3")
5412 if (type_string ==
"S4")
5414 if (type_string ==
"S4R")
5416 if (type_string ==
"CPS3")
5418 if (type_string ==
"CPS4")
5420 if (type_string ==
"CPS4R")
5422 if (type_string ==
"CPE3")
5424 if (type_string ==
"CPE4")
5426 if (type_string ==
"CPE4R")
5428 return ReferenceCells::Invalid<2>;
5430 else if constexpr (dim == 3)
5432 if (type_string ==
"C3D8")
5434 if (type_string ==
"C3D8I")
5436 if (type_string ==
"C3D8R")
5438 if (type_string ==
"C3D4")
5440 if (type_string ==
"C3D6")
5442 if (type_string ==
"C3D5")
5444 if (type_string ==
"C3D5H")
5446 if (type_string ==
"F3D8")
5448 return ReferenceCells::Invalid<3>;
5454 template <
int dim,
int spacedim>
5456 Abaqus_to_UCD<dim, spacedim>::read_in_abaqus(std::istream &input_stream)
5465 while (getline_dos_or_unix(input_stream, line))
5468 std::transform(line.begin(),
5471 static_cast<int (*)(
int)
>(std::toupper));
5473 if (line.compare(
"*HEADING") == 0 || line.compare(0, 2,
"**") == 0 ||
5474 line.compare(0, 5,
"*PART") == 0)
5477 while (getline_dos_or_unix(input_stream, line))
5483 else if (line.compare(0, 5,
"*NODE") == 0)
5492 while (getline_dos_or_unix(input_stream, line))
5497 std::vector<double> node(spacedim + 1);
5499 std::istringstream iss(line);
5501 for (
unsigned int i = 0; i < spacedim + 1; ++i)
5502 iss >> node[i] >> comma;
5504 node_list.push_back(node);
5507 else if (line.compare(0, 8,
"*ELEMENT") == 0)
5520 const std::string element_type_name =
"TYPE=";
5521 std::string element_name = extract_value(line, element_type_name);
5522 ref_cell = get_reference_cell_from_element_type(element_name);
5525 ref_cell.get_dimension() == dim,
5527 "Element dimension does not match Triangulation dimension."));
5532 const std::string before_material =
"ELSET=EB";
5533 const std::size_t idx = line.find(before_material);
5534 if (idx != std::string::npos)
5536 from_string(material,
5537 line.substr(idx + before_material.size()),
5541 const unsigned int n_data_per_cell = 1 + ref_cell.n_vertices();
5543 while (getline_dos_or_unix(input_stream, line))
5548 std::istringstream iss(line);
5555 std::vector<double> cell(n_data_per_cell);
5556 for (
unsigned int i = 0; i < n_data_per_cell; ++i)
5557 iss >> cell[i] >> comma;
5559 cell[0] =
static_cast<double>(material);
5560 cell_list.push_back(cell);
5563 else if (line.compare(0, 8,
"*SURFACE") == 0)
5574 const std::string name_key =
"NAME=";
5575 const std::size_t name_idx_start =
5576 line.find(name_key) + name_key.size();
5577 std::size_t name_idx_end = line.find(
',', name_idx_start);
5578 if (name_idx_end == std::string::npos)
5580 name_idx_end = line.size();
5582 const int b_indicator = extract_int(
5583 line.substr(name_idx_start, name_idx_end - name_idx_start));
5590 while (getline_dos_or_unix(input_stream, line))
5596 std::transform(line.begin(),
5599 static_cast<int (*)(
int)
>(std::toupper));
5604 std::istringstream iss(line);
5611 std::vector<double> face_node_list;
5612 const std::string elset_name = line.substr(0, line.find(
','));
5613 if (elsets_list.count(elset_name) != 0)
5617 iss >> stmp >> temp >> face_number;
5619 const std::vector<int> cells = elsets_list[elset_name];
5620 for (
const int cell : cells)
5624 get_global_node_numbers(el_idx, face_number);
5625 face_node_list.insert(face_node_list.begin(),
5628 face_list.push_back(face_node_list);
5635 iss >> el_idx >> comma >> temp >> face_number;
5637 get_global_node_numbers(el_idx, face_number);
5638 face_node_list.insert(face_node_list.begin(), b_indicator);
5640 face_list.push_back(face_node_list);
5644 else if (line.compare(0, 6,
"*ELSET") == 0)
5648 std::string elset_name;
5650 const std::string elset_key =
"*ELSET, ELSET=";
5651 const std::size_t idx = line.find(elset_key);
5652 if (idx != std::string::npos)
5654 const std::string comma =
",";
5655 const std::size_t first_comma = line.find(comma);
5656 const std::size_t second_comma =
5657 line.find(comma, first_comma + 1);
5658 const std::size_t elset_name_start =
5659 line.find(elset_key) + elset_key.size();
5660 elset_name = line.substr(elset_name_start,
5661 second_comma - elset_name_start);
5671 std::vector<int> elements;
5672 const std::size_t generate_idx = line.find(
"GENERATE");
5673 if (generate_idx != std::string::npos)
5676 getline_dos_or_unix(input_stream, line);
5677 std::istringstream iss(line);
5687 iss >> elid_start >> comma >> elid_end;
5691 "While reading an ABAQUS file, the reader "
5692 "expected a comma but found a <") +
5693 comma +
"> in the line <" + line +
">."));
5695 elid_start <= elid_end,
5698 "While reading an ABAQUS file, the reader encountered "
5699 "a GENERATE statement in which the upper bound <") +
5701 "> for the element numbers is not larger or equal "
5702 "than the lower bound <" +
5706 if (iss.rdbuf()->in_avail() != 0)
5707 iss >> comma >> elis_step;
5711 "While reading an ABAQUS file, the reader "
5712 "expected a comma but found a <") +
5713 comma +
"> in the line <" + line +
">."));
5715 for (
int i = elid_start; i <= elid_end; i += elis_step)
5716 elements.push_back(i);
5717 elsets_list[elset_name] = elements;
5719 getline_dos_or_unix(input_stream, line);
5724 while (getline_dos_or_unix(input_stream, line))
5729 std::istringstream iss(line);
5734 iss >> elid >> comma;
5739 "While reading an ABAQUS file, the reader "
5740 "expected a comma but found a <") +
5741 comma +
"> in the line <" + line +
">."));
5743 elements.push_back(elid);
5747 elsets_list[elset_name] = elements;
5752 else if (line.compare(0, 5,
"*NSET") == 0)
5755 while (getline_dos_or_unix(input_stream, line))
5761 else if (line.compare(0, 14,
"*SOLID SECTION") == 0)
5765 const std::string elset_key =
"ELSET=";
5766 const std::size_t elset_start =
5767 line.find(
"ELSET=") + elset_key.size();
5768 const std::size_t elset_end = line.find(
',', elset_start + 1);
5769 const std::string elset_name =
5770 line.substr(elset_start, elset_end - elset_start);
5775 const std::string material_key =
"MATERIAL=";
5776 const std::size_t last_equal =
5777 line.find(
"MATERIAL=") + material_key.size();
5778 const std::size_t material_id_start = line.find(
'-', last_equal);
5780 from_string(material_id,
5781 line.substr(material_id_start + 1),
5785 const std::vector<int> &elset_cells = elsets_list[elset_name];
5786 for (
const int elset_cell : elset_cells)
5788 const int cell_id = elset_cell - 1;
5796 template <
int dim,
int spacedim>
5798 Abaqus_to_UCD<dim, spacedim>::get_global_node_numbers(
5799 const int face_cell_no,
5800 const int face_cell_face_no)
const
5803 Assert((face_cell_no >= 1) &&
5804 (
static_cast<typename decltype(cell_list)::
size_type>(
5805 face_cell_no) <= cell_list.size()),
5808 const auto &cell_data = cell_list[face_cell_no - 1];
5811 const unsigned int n_vertices = cell_data.size() - 1;
5813 std::vector<double> face_nodes;
5815 if constexpr (dim == 2)
5817 if (n_vertices == 3)
5819 face_nodes.resize(2);
5820 if (face_cell_face_no == 1)
5822 face_nodes[0] = cell_data[1];
5823 face_nodes[1] = cell_data[2];
5825 else if (face_cell_face_no == 2)
5827 face_nodes[0] = cell_data[2];
5828 face_nodes[1] = cell_data[3];
5830 else if (face_cell_face_no == 3)
5832 face_nodes[0] = cell_data[3];
5833 face_nodes[1] = cell_data[1];
5837 ExcMessage(
"Invalid face number for Triangle in 2d"));
5839 else if (n_vertices == 4)
5841 face_nodes.resize(2);
5842 if (face_cell_face_no == 1)
5844 face_nodes[0] = cell_data[1];
5845 face_nodes[1] = cell_data[2];
5847 else if (face_cell_face_no == 2)
5849 face_nodes[0] = cell_data[2];
5850 face_nodes[1] = cell_data[3];
5852 else if (face_cell_face_no == 3)
5854 face_nodes[0] = cell_data[3];
5855 face_nodes[1] = cell_data[4];
5857 else if (face_cell_face_no == 4)
5859 face_nodes[0] = cell_data[4];
5860 face_nodes[1] = cell_data[1];
5864 ExcMessage(
"Invalid face number for Quad in 2d"));
5869 else if constexpr (dim == 3)
5871 if (n_vertices == 4)
5873 face_nodes.resize(3);
5874 if (face_cell_face_no == 1)
5876 face_nodes[0] = cell_data[1];
5877 face_nodes[1] = cell_data[2];
5878 face_nodes[2] = cell_data[3];
5880 else if (face_cell_face_no == 2)
5882 face_nodes[0] = cell_data[1];
5883 face_nodes[1] = cell_data[4];
5884 face_nodes[2] = cell_data[2];
5886 else if (face_cell_face_no == 3)
5888 face_nodes[0] = cell_data[2];
5889 face_nodes[1] = cell_data[4];
5890 face_nodes[2] = cell_data[3];
5892 else if (face_cell_face_no == 4)
5894 face_nodes[0] = cell_data[3];
5895 face_nodes[1] = cell_data[4];
5896 face_nodes[2] = cell_data[1];
5900 ExcMessage(
"Invalid face number for Tet in 3d"));
5902 else if (n_vertices == 5)
5904 if (face_cell_face_no == 1)
5906 face_nodes.resize(4);
5907 face_nodes[0] = cell_data[1];
5908 face_nodes[1] = cell_data[2];
5909 face_nodes[2] = cell_data[3];
5910 face_nodes[3] = cell_data[4];
5912 else if (face_cell_face_no == 2 || face_cell_face_no == 3 ||
5913 face_cell_face_no == 4 || face_cell_face_no == 5)
5915 face_nodes.resize(3);
5916 face_nodes[0] = cell_data[5];
5917 if (face_cell_face_no == 2)
5919 face_nodes[1] = cell_data[1];
5920 face_nodes[2] = cell_data[2];
5922 else if (face_cell_face_no == 3)
5924 face_nodes[1] = cell_data[2];
5925 face_nodes[2] = cell_data[3];
5927 else if (face_cell_face_no == 4)
5929 face_nodes[1] = cell_data[3];
5930 face_nodes[2] = cell_data[4];
5932 else if (face_cell_face_no == 5)
5934 face_nodes[1] = cell_data[4];
5935 face_nodes[2] = cell_data[1];
5939 false,
ExcMessage(
"Invalid face number for Pyramid in 3d"));
5942 else if (n_vertices == 6)
5944 if (face_cell_face_no == 1 || face_cell_face_no == 2)
5946 face_nodes.resize(3);
5947 if (face_cell_face_no == 1)
5949 face_nodes[0] = cell_data[4];
5950 face_nodes[1] = cell_data[5];
5951 face_nodes[2] = cell_data[6];
5953 else if (face_cell_face_no == 2)
5955 face_nodes[0] = cell_data[1];
5956 face_nodes[1] = cell_data[2];
5957 face_nodes[2] = cell_data[3];
5960 else if (face_cell_face_no >= 3 && face_cell_face_no <= 5)
5962 face_nodes.resize(4);
5963 if (face_cell_face_no == 3)
5965 face_nodes[0] = cell_data[4];
5966 face_nodes[1] = cell_data[1];
5967 face_nodes[2] = cell_data[2];
5968 face_nodes[3] = cell_data[5];
5970 else if (face_cell_face_no == 4)
5972 face_nodes[0] = cell_data[5];
5973 face_nodes[1] = cell_data[2];
5974 face_nodes[2] = cell_data[3];
5975 face_nodes[3] = cell_data[6];
5977 else if (face_cell_face_no == 5)
5979 face_nodes[0] = cell_data[4];
5980 face_nodes[1] = cell_data[1];
5981 face_nodes[2] = cell_data[3];
5982 face_nodes[3] = cell_data[6];
5987 ExcMessage(
"Invalid face number for Wedge in 3d"));
5989 else if (n_vertices == 8)
5991 face_nodes.resize(4);
5992 if (face_cell_face_no == 1)
5994 face_nodes[0] = cell_data[1];
5995 face_nodes[1] = cell_data[4];
5996 face_nodes[2] = cell_data[3];
5997 face_nodes[3] = cell_data[2];
5999 else if (face_cell_face_no == 2)
6001 face_nodes[0] = cell_data[5];
6002 face_nodes[1] = cell_data[8];
6003 face_nodes[2] = cell_data[7];
6004 face_nodes[3] = cell_data[6];
6006 else if (face_cell_face_no == 3)
6008 face_nodes[0] = cell_data[1];
6009 face_nodes[1] = cell_data[2];
6010 face_nodes[2] = cell_data[6];
6011 face_nodes[3] = cell_data[5];
6013 else if (face_cell_face_no == 4)
6015 face_nodes[0] = cell_data[2];
6016 face_nodes[1] = cell_data[3];
6017 face_nodes[2] = cell_data[7];
6018 face_nodes[3] = cell_data[6];
6020 else if (face_cell_face_no == 5)
6022 face_nodes[0] = cell_data[3];
6023 face_nodes[1] = cell_data[4];
6024 face_nodes[2] = cell_data[8];
6025 face_nodes[3] = cell_data[7];
6027 else if (face_cell_face_no == 6)
6029 face_nodes[0] = cell_data[1];
6030 face_nodes[1] = cell_data[5];
6031 face_nodes[2] = cell_data[8];
6032 face_nodes[3] = cell_data[4];
6036 ExcMessage(
"Invalid face number for Hex in 3d"));
6050 n_vertices_to_ucd_string(
unsigned int dim,
int n_vertices_per_cell)
6059 if (n_vertices_per_cell == 2)
6068 "Higher-order line elements are not implemented yet")));
6073 if (n_vertices_per_cell == 3)
6077 else if (n_vertices_per_cell == 4)
6086 "Higher-order 2d elements are not implemented yet.")));
6091 if (n_vertices_per_cell == 4)
6095 if (n_vertices_per_cell == 5)
6099 else if (n_vertices_per_cell == 6)
6103 else if (n_vertices_per_cell == 8)
6112 "Higher-order elements are not implemented yet in 3D.")));
6117 AssertThrow(dim != 0 || dim != 1 || dim != 2 || dim != 3,
6121 return "Error. Something went wrong in n_vertices_to_ucd_string().";
6124 template <
int dim,
int spacedim>
6126 Abaqus_to_UCD<dim, spacedim>::write_out_avs_ucd(std::ostream &output)
const
6135 const boost::io::ios_base_all_saver formatting_saver(output);
6139 output <<
"# Abaqus to UCD mesh conversion" <<
'\n';
6140 output <<
"# Mesh type: AVS UCD" <<
'\n';
6169 output << node_list.size() <<
"\t" << (cell_list.size() + face_list.size())
6170 <<
"\t0\t0\t0" <<
'\n';
6174 output.setf(std::ios::scientific, std::ios::floatfield);
6175 for (
const auto &node : node_list)
6179 output << static_cast<int>(node[0]) <<
"\t";
6183 for (
unsigned int jj = 1; jj < spacedim + 1; ++jj)
6186 output.precision(16);
6189 if (
std::abs(node[jj]) > tolerance)
6190 output << static_cast<double>(node[jj]) <<
"\t";
6192 output << 0.0 <<
"\t";
6195 output << 0.0 <<
"\t";
6199 output.unsetf(std::ios::floatfield);
6202 for (
unsigned int ii = 0; ii < cell_list.size(); ++ii)
6204 int n_vertices_per_cell = cell_list[ii].size() - 1;
6205 output << ii + 1 <<
"\t" << cell_list[ii][0] <<
"\t"
6206 << (n_vertices_to_ucd_string(dim, n_vertices_per_cell))
6208 for (
int jj = 1; jj < n_vertices_per_cell + 1; ++jj)
6209 output << cell_list[ii][jj] <<
"\t";
6215 for (
unsigned int ii = 0; ii < face_list.size(); ++ii)
6217 int n_vertices_per_cell = face_list[ii].size() - 1;
6218 output << ii + 1 <<
"\t" << face_list[ii][0] <<
"\t"
6219 << (n_vertices_to_ucd_string(dim - 1, n_vertices_per_cell))
6221 for (
int jj = 1; jj < n_vertices_per_cell + 1; ++jj)
6222 output << face_list[ii][jj] <<
"\t";
6227 output << std::flush;
6233#include "grid/grid_in.inst"
* * for(const auto &cell :triangulation.active_cell_iterators())
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
void read_vtk(std::istream &in)
static void skip_empty_lines(std::istream &in)
void read_partitioned_msh(const std::string &file_prefix, const std::string &file_suffix="msh")
void read_assimp(const std::string &filename, const unsigned int mesh_index=numbers::invalid_unsigned_int, const bool remove_duplicates=true, const double tol=1e-12, const bool ignore_unsupported_element_types=true)
void read_ugrid(std::istream &in)
void read_abaqus(std::istream &in, const bool apply_all_indicators_to_manifolds=false)
static std::string default_suffix(const Format format)
void read_xda(std::istream &in)
void read_comsol_mphtxt(std::istream &in)
static void skip_comment_lines(std::istream &in, const char comment_start)
void attach_triangulation(Triangulation< dim, spacedim > &tria)
const std::map< std::string, Vector< double > > & get_cell_data() const
void read_msh(std::istream &in)
static Format parse_format(const std::string &format_name)
void read_vtu(std::istream &in)
void read_tecplot(std::istream &in)
ExodusIIData read_exodusii(const std::string &filename, const bool apply_all_indicators_to_manifolds=false)
void read_dbmesh(std::istream &in)
void read_ucd(std::istream &in, const bool apply_all_indicators_to_manifolds=false)
void read(std::istream &in, Format format=Default)
static void debug_output_grid(const std::vector< CellData< dim > > &cells, const std::vector< Point< spacedim > > &vertices, std::ostream &out)
static std::string get_format_names()
void read_unv(std::istream &in)
static void parse_tecplot_header(std::string &header, std::vector< unsigned int > &tecplot2deal, unsigned int &n_vars, unsigned int &n_vertices, unsigned int &n_cells, std::vector< unsigned int > &IJK, bool &structured, bool &blocked)
constexpr ReferenceCell< dim - 1 > face_reference_cell(const unsigned int face_index) const
constexpr unsigned int n_faces() const
unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const types::geometric_orientation face_orientation) const
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
constexpr iterator end() noexcept
constexpr size_type size() const noexcept
constexpr iterator begin() noexcept
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
ReferenceCell< dim > get_reference_cell_from_UCD_string(const std::string &type_string)
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcFileNotOpen(std::string arg1)
static ::ExceptionBase & ExcNeedsAssimp()
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcNeedsGMSHAPI()
static ::ExceptionBase & ExcNeedsExodusII()
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
#define AssertThrowExodusII(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcIndexRange(std::size_t arg1, std::size_t arg2, std::size_t arg3)
static ::ExceptionBase & ExcInvalidState()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void consistently_order_cells(std::vector< CellData< dim > > &cells)
std::vector< index_type > data
types::global_dof_index size_type
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
* * if(update_pressure &update_flags) * compute_pressure(constitutive_request
* * * * std::vector< Number > ThermoPlasticMaterial< dim, ViscoplasticYieldLaw, Number >::get_state_parameters const
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr ReferenceCell< 3 > Tetrahedron
constexpr ReferenceCell< 3 > Pyramid
constexpr ReferenceCell< 3 > Wedge
unsigned int n_mpi_processes(const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
std::pair< int, unsigned int > get_integer_at_position(const std::string &name, const unsigned int position)
std::vector< unsigned char > decode_base64(const std::string &base64_input)
std::vector< std::string > break_text_into_lines(const std::string &original_text, const unsigned int width, const char delimiter=' ')
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
bool match_at_string_start(const std::string &name, const std::string &pattern)
std::string decompress(const std::string &compressed_input)
constexpr unsigned int invalid_unsigned_int
constexpr types::boundary_id internal_face_boundary_id
constexpr types::boundary_id invalid_boundary_id
constexpr types::manifold_id flat_manifold_id
constexpr types::material_id invalid_material_id
constexpr types::geometric_orientation default_geometric_orientation
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
std_cxx26::inplace_vector< unsigned int, ReferenceCells::max_n_vertices< structdim >()> vertices
types::material_id material_id
static std_cxx20::ranges::iota_view< unsigned int, unsigned int > vertex_indices()
std::vector< std::vector< int > > id_to_sideset_ids
std::vector< CellData< 2 > > boundary_quads
bool check_consistency(const unsigned int dim) const
std::vector< CellData< 1 > > boundary_lines
types::subdomain_id subdomain_id
types::subdomain_id level_subdomain_id
std_cxx26::inplace_vector< std::pair< unsigned int, types::boundary_id >, ReferenceCells::max_n_faces< dim >()> boundary_ids
types::material_id material_id
std::vector< std::vector< CellData< dim > > > cell_infos
std::vector<::CellData< dim > > coarse_cells
std::vector< Point< spacedim > > coarse_cell_vertices
std::vector< types::coarse_cell_id > coarse_cell_index_to_coarse_cell_id