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(
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 =
120 bool is_only_hypercube =
true;
122 if (cell.vertices.size() != n_hypercube_vertices)
124 is_only_hypercube =
false;
132 if (is_only_hypercube)
137template <
int dim,
int spacedim>
139 :
tria(nullptr, typeid(*this).name())
145template <
int dim,
int spacedim>
147 :
tria(&t, typeid(*this).name())
153template <
int dim,
int spacedim>
162template <
int dim,
int spacedim>
167 std::string vtk_version;
178 text[3] =
"DATASET UNSTRUCTURED_GRID";
180 for (
unsigned int i = 0; i < 4; ++i)
186 if (i == 2 || i == 3)
188 line.compare(text[i]) == 0,
191 "While reading VTK file, failed to find a header line with text <") +
196 vtk_version = text[0].substr(23, 3);
202 std::vector<Point<spacedim>> vertices;
203 std::vector<CellData<dim>> cells;
212 if (keyword ==
"POINTS")
214 unsigned int n_vertices;
219 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
223 in >> x[0] >> x[1] >> x[2];
225 vertices.emplace_back();
226 for (
unsigned int d = 0; d < spacedim; ++d)
227 vertices.back()[d] = x[d];
234 "While reading VTK file, failed to find POINTS section"));
238 unsigned int n_geometric_objects = 0;
240 std::vector<unsigned int> n_points_per_cell;
242 if (keyword ==
"CELLS")
245 std::vector<unsigned int> cell_types;
247 std::streampos oldpos = in.tellg();
250 while (in >> keyword)
251 if (keyword ==
"CELL_TYPES")
255 cell_types.resize(n_ints);
257 for (
unsigned int i = 0; i < n_ints; ++i)
266 in >> n_geometric_objects;
269 if (vtk_version ==
"5.1")
275 keyword ==
"OFFSETS",
277 "While reading VTK file, failed to find OFFSETS array which must exist in a VTK file with version 5.1."));
281 unsigned int n_offsets = n_geometric_objects;
289 unsigned int new_index = 0;
290 unsigned int old_index = 0;
293 for (
unsigned int p = 0; p < n_offsets; ++p)
295 unsigned int n_points_per_cell_tmp;
303 "While reading VTK file, the first index in the OFFSETS array should be 0"));
306 n_points_per_cell_tmp = new_index - old_index;
307 n_points_per_cell.push_back(n_points_per_cell_tmp);
309 old_index = new_index;
313 n_points_per_cell.size() == cell_types.size(),
315 "The number of cells inferred from the OFFSETS array (" +
316 std::to_string(n_points_per_cell.size()) +
317 ") does not match the number of entries in the CELL_TYPES array (" +
318 std::to_string(cell_types.size()) +
")"));
324 keyword ==
"CONNECTIVITY",
326 "While reading VTK file, failed to find CONNECTIVITY array which must exist in a VTK file containing an OFFSETS array."));
332 n_geometric_objects = n_points_per_cell.size();
338 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
340 unsigned int n_vertices;
342 if (vtk_version ==
"3.0")
344 else if (vtk_version ==
"5.1")
346 n_vertices = n_points_per_cell[count];
351 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
354 if (cell_types[count] == 10 || cell_types[count] == 12)
362 cells.emplace_back(n_vertices);
364 for (
unsigned int j = 0; j < n_vertices;
366 in >> cells.back().vertices[j];
370 if (cell_types[count] == 12)
372 std::swap(cells.back().vertices[2],
373 cells.back().vertices[3]);
374 std::swap(cells.back().vertices[6],
375 cells.back().vertices[7]);
378 cells.back().material_id = 0;
381 else if (cell_types[count] == 5 || cell_types[count] == 9)
390 for (
unsigned int j = 0; j < n_vertices;
397 else if (cell_types[count] == 3)
401 for (
unsigned int j = 0; j < n_vertices;
412 "While reading VTK file, unknown cell type encountered"));
417 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
419 unsigned int n_vertices;
421 if (vtk_version ==
"3.0")
423 else if (vtk_version ==
"5.1")
425 n_vertices = n_points_per_cell[count];
430 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
433 if (cell_types[count] == 5 || cell_types[count] == 9)
440 cells.emplace_back(n_vertices);
442 for (
unsigned int j = 0; j < n_vertices;
444 in >> cells.back().vertices[j];
448 if (cell_types[count] == 9)
452 std::swap(cells.back().vertices[2],
453 cells.back().vertices[3]);
456 cells.back().material_id = 0;
459 else if (cell_types[count] == 3)
465 for (
unsigned int j = 0; j < n_vertices;
478 "While reading VTK file, unknown cell type encountered"));
483 for (
unsigned int count = 0; count < n_geometric_objects; ++count)
485 unsigned int n_vertices;
486 if (vtk_version ==
"3.0")
488 else if (vtk_version ==
"5.1")
490 n_vertices = n_points_per_cell[count];
495 "Unknown VTK version encountered...Only VTK versions 3.0 and 5.1 are supported."));
498 cell_types[count] == 3 && n_vertices == 2,
500 "While reading VTK file, unknown cell type encountered"));
501 cells.emplace_back(n_vertices);
503 for (
unsigned int j = 0; j < n_vertices; ++j)
504 in >> cells.back().vertices[j];
506 cells.back().material_id = 0;
512 "While reading VTK file, failed to find CELLS section"));
519 keyword ==
"CELL_TYPES",
521 "While reading VTK file, missing CELL_TYPES section. Found <" +
522 keyword +
"> instead.")));
527 n_ints == n_geometric_objects,
528 ExcMessage(
"The VTK reader found a CELL_DATA statement "
529 "that lists a total of " +
531 " cell data objects, but this needs to "
532 "equal the number of cells (which is " +
534 ") plus the number of quads (" +
536 " in 3d or the number of lines (" +
541 for (
unsigned int i = 0; i < n_ints; ++i)
548 while (in >> keyword)
550 if (keyword ==
"CELL_DATA")
556 n_ids == n_geometric_objects,
558 "The VTK reader found a CELL_DATA statement "
559 "that lists a total of " +
561 " cell data objects, but this needs to "
562 "equal the number of cells (which is " +
564 ") plus the number of quads (" +
566 " in 3d or the number of lines (" +
570 const std::vector<std::string> data_sets{
"MaterialID",
574 for (
unsigned int i = 0; i < data_sets.size(); ++i)
577 if (keyword ==
"SCALARS")
582 std::string field_name;
584 if (std::find(data_sets.begin(),
586 field_name) == data_sets.end())
598 std::getline(in, line);
602 std::min(
static_cast<std::size_t
>(3),
603 line.size() - 1)) ==
"int",
605 "While reading VTK file, material- and manifold IDs can only have type 'int'."));
609 keyword ==
"LOOKUP_TABLE",
611 "While reading VTK file, missing keyword 'LOOKUP_TABLE'."));
615 keyword ==
"default",
617 "While reading VTK file, missing keyword 'default'."));
624 for (
unsigned int i = 0; i < cells.size(); ++i)
628 if (field_name ==
"MaterialID")
629 cells[i].material_id =
631 else if (field_name ==
"ManifoldID")
632 cells[i].manifold_id =
644 if (field_name ==
"MaterialID")
645 boundary_quad.material_id =
647 else if (field_name ==
"ManifoldID")
648 boundary_quad.manifold_id =
657 if (field_name ==
"MaterialID")
658 boundary_line.material_id =
660 else if (field_name ==
"ManifoldID")
661 boundary_line.manifold_id =
673 if (field_name ==
"MaterialID")
674 boundary_line.material_id =
676 else if (field_name ==
"ManifoldID")
677 boundary_line.manifold_id =
687 std::streampos oldpos = in.tellg();
689 if (keyword ==
"SCALARS")
700 else if (keyword ==
"FIELD")
702 unsigned int n_fields;
705 keyword ==
"FieldData",
707 "While reading VTK file, missing keyword FieldData"));
711 for (
unsigned int i = 0; i < n_fields; ++i)
713 std::string section_name;
714 std::string data_type;
715 unsigned int temp, n_ids;
721 n_ids == n_geometric_objects,
723 "The VTK reader found a FIELD statement "
724 "that lists a total of " +
726 " cell data objects, but this needs to equal the number of cells (which is " +
728 ") plus the number of quads (" +
731 " in 3d or the number of lines (" +
738 for (
unsigned int j = 0; j < n_ids; ++j)
741 if (j < cells.size())
744 this->
cell_data[section_name] = std::move(temp_data);
755 apply_grid_fixup_functions(vertices, cells, subcelldata);
756 tria->create_triangulation(vertices, cells, subcelldata);
761 "While reading VTK file, failed to find CELLS section"));
764template <
int dim,
int spacedim>
765const std::map<std::string, Vector<double>> &
771template <
int dim,
int spacedim>
775 namespace pt = boost::property_tree;
777 pt::read_xml(in, tree);
778 auto section = tree.get_optional<std::string>(
"VTKFile.dealiiData");
782 "While reading a VTU file, failed to find dealiiData section. "
783 "Notice that we can only read grid files in .vtu format that "
784 "were created by the deal.II library, using a call to "
785 "GridOut::write_vtu(), where the flag "
786 "GridOutFlags::Vtu::serialize_triangulation is set to true."));
790 const auto string_archive =
792 std::istringstream in_stream(string_archive);
793 boost::archive::binary_iarchive ia(in_stream);
798template <
int dim,
int spacedim>
817 "Expected '-1' before and after a section."));
829 std::getline(in, line);
831 boost::algorithm::trim(line);
832 if (line.compare(
"-1") == 0)
843 std::vector<Point<spacedim>> vertices;
862 in >> dummy >> dummy >> dummy;
865 in >> x[0] >> x[1] >> x[2];
867 vertices.emplace_back();
869 for (
unsigned int d = 0; d < spacedim; ++d)
870 vertices.back()[d] = x[d];
872 vertex_indices[vertex_index] = n_vertices;
886 std::vector<CellData<dim>> cells;
913 in >> type >> dummy >> dummy >> dummy >> dummy;
915 AssertThrow((type == 11) || (type == 44) || (type == 94) || (type == 115),
918 if ((((type == 44) || (type == 94)) && (dim == 2)) ||
919 ((type == 115) && (dim == 3)))
922 cells.emplace_back();
927 .vertices[reference_cell.unv_vertex_to_deal_vertex(v)];
929 cells.back().material_id = 0;
932 cells.back().vertices[v] = vertex_indices[cells.back().vertices[v]];
934 cell_indices[object_index] = n_cells;
938 else if (((type == 11) && (dim == 2)) ||
939 ((type == 11) && (dim == 3)))
942 in >> dummy >> dummy >> dummy;
947 for (
unsigned int &vertex :
953 for (
unsigned int &vertex :
955 vertex = vertex_indices[vertex];
957 line_indices[object_index] = n_lines;
961 else if (((type == 44) || (type == 94)) && (dim == 3))
972 .vertices[reference_cell.unv_vertex_to_deal_vertex(v)];
976 for (
unsigned int &vertex :
978 vertex = vertex_indices[vertex];
980 quad_indices[object_index] = n_quads;
988 "> when running in dim=" +
1023 in >> dummy >> dummy >> dummy >> dummy >> dummy >> dummy >>
1034 std::getline(in, line);
1037 "The line before the line containing an ID has too "
1038 "many entries. This is not a valid UNV file."));
1040 std::getline(in, line);
1042 std::istringstream id_stream(line);
1045 !id_stream.fail() && id_stream.eof(),
1047 "The given UNV file contains a boundary or material id set to '" +
1049 "', which cannot be parsed as a fixed-width integer, whereas "
1050 "deal.II only supports integer boundary and material ids. To fix "
1051 "this, ensure that all such ids are given integer values."));
1054 id <=
long(std::numeric_limits<types::material_id>::max()),
1055 ExcMessage(
"The provided integer id '" + std::to_string(
id) +
1056 "' is not convertible to either types::material_id nor "
1057 "types::boundary_id."));
1059 const unsigned int n_lines =
1060 (n_entities % 2 == 0) ? (n_entities / 2) : ((n_entities + 1) / 2);
1062 for (
unsigned int line = 0; line < n_lines; ++line)
1064 unsigned int n_fragments;
1066 if (line == n_lines - 1)
1067 n_fragments = (n_entities % 2 == 0) ? (2) : (1);
1071 for (
unsigned int no_fragment = 0; no_fragment < n_fragments;
1075 in >> dummy >> no >> dummy >> dummy;
1077 if (cell_indices.count(no) > 0)
1078 cells[cell_indices[no]].material_id = id;
1080 if (line_indices.count(no) > 0)
1084 if (quad_indices.count(no) > 0)
1092 apply_grid_fixup_functions(vertices, cells, subcelldata);
1093 tria->create_triangulation(vertices, cells, subcelldata);
1098template <
int dim,
int spacedim>
1101 const bool apply_all_indicators_to_manifolds)
1110 unsigned int n_vertices;
1111 unsigned int n_cells;
1114 in >> n_vertices >> n_cells >> dummy
1120 std::vector<Point<spacedim>> vertices(n_vertices);
1124 std::map<int, int> vertex_indices;
1126 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1133 in >> vertex_number >> x[0] >> x[1] >> x[2];
1136 for (
unsigned int d = 0; d < spacedim; ++d)
1137 vertices[vertex][d] = x[d];
1141 vertex_indices[vertex_number] = vertex;
1145 std::vector<CellData<dim>> cells;
1148 for (
unsigned int cell = 0; cell < n_cells; ++cell)
1157 std::string cell_type;
1161 unsigned int material_id;
1167 if (((cell_type ==
"line") && (dim == 1)) ||
1168 ((cell_type ==
"quad") && (dim == 2)) ||
1169 ((cell_type ==
"hex") && (dim == 3)))
1173 cells.emplace_back();
1178 Assert(material_id <= std::numeric_limits<types::material_id>::max(),
1181 std::numeric_limits<types::material_id>::max()));
1186 if (apply_all_indicators_to_manifolds)
1187 cells.back().manifold_id =
1189 cells.back().material_id = material_id;
1194 if (vertex_indices.find(cells.back().vertices[i]) !=
1195 vertex_indices.end())
1197 cells.back().vertices[i] =
1198 vertex_indices[cells.back().vertices[i]];
1204 cells.back().vertices[i]));
1209 else if ((cell_type ==
"line") && ((dim == 2) || (dim == 3)))
1217 Assert(material_id <= std::numeric_limits<types::boundary_id>::max(),
1220 std::numeric_limits<types::boundary_id>::max()));
1229 if (apply_all_indicators_to_manifolds)
1246 for (
unsigned int &vertex :
1248 if (vertex_indices.find(vertex) != vertex_indices.end())
1250 vertex = vertex_indices[vertex];
1258 else if ((cell_type ==
"quad") && (dim == 3))
1267 Assert(material_id <= std::numeric_limits<types::boundary_id>::max(),
1270 std::numeric_limits<types::boundary_id>::max()));
1279 if (apply_all_indicators_to_manifolds)
1296 for (
unsigned int &vertex :
1298 if (vertex_indices.find(vertex) != vertex_indices.end())
1300 vertex = vertex_indices[vertex];
1315 apply_grid_fixup_functions(vertices, cells, subcelldata);
1316 tria->create_triangulation(vertices, cells, subcelldata);
1321 template <
int dim,
int spacedim>
1328 read_in_abaqus(std::istream &in);
1330 write_out_avs_ucd(std::ostream &out)
const;
1333 const double tolerance;
1336 get_global_node_numbers(
const int face_cell_no,
1337 const int face_cell_face_no)
const;
1340 std::vector<std::vector<double>> node_list;
1343 std::vector<std::vector<double>> cell_list;
1345 std::vector<std::vector<double>> face_list;
1348 std::map<std::string, std::vector<int>> elsets_list;
1352template <
int dim,
int spacedim>
1355 const bool apply_all_indicators_to_manifolds)
1362 Assert((spacedim == 2 && dim == spacedim) ||
1363 (spacedim == 3 && (dim == spacedim || dim == spacedim - 1)),
1369 Abaqus_to_UCD<dim, spacedim> abaqus_to_ucd;
1370 abaqus_to_ucd.read_in_abaqus(in);
1372 std::stringstream in_ucd;
1373 abaqus_to_ucd.write_out_avs_ucd(in_ucd);
1381 read_ucd(in_ucd, apply_all_indicators_to_manifolds);
1383 catch (std::exception &exc)
1385 std::cerr <<
"Exception on processing internal UCD data: " << std::endl
1386 << exc.what() << std::endl;
1391 "Internal conversion from ABAQUS file to UCD format was unsuccessful. "
1392 "More information is provided in an error message printed above. "
1393 "Are you sure that your ABAQUS mesh file conforms with the requirements "
1394 "listed in the documentation?"));
1401 "Internal conversion from ABAQUS file to UCD format was unsuccessful. "
1402 "Are you sure that your ABAQUS mesh file conforms with the requirements "
1403 "listed in the documentation?"));
1408template <
int dim,
int spacedim>
1447 while (getline(in, line), line.find(
"# END") == std::string::npos)
1456 unsigned int n_vertices;
1460 std::vector<Point<spacedim>> vertices(n_vertices);
1461 for (
unsigned int vertex = 0; vertex < n_vertices; ++vertex)
1464 for (
unsigned int d = 0; d < dim; ++d)
1465 in >> vertices[vertex][d];
1479 unsigned int n_edges;
1481 for (
unsigned int edge = 0; edge < n_edges; ++edge)
1484 in >> dummy >> dummy;
1502 for (
unsigned int edge = 0; edge < n_edges; ++edge)
1505 in >> dummy >> dummy;
1519 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
1520 {0, 1, 5, 4, 2, 3, 7, 6}};
1521 std::vector<CellData<dim>> cells;
1523 unsigned int n_cells;
1525 for (
unsigned int cell = 0; cell < n_cells; ++cell)
1529 cells.emplace_back();
1533 cells.back().vertices[dim == 3 ? local_vertex_numbering[i] :
1537 (
static_cast<unsigned int>(cells.back().vertices[i]) <=
1541 --cells.back().vertices[i];
1557 while (getline(in, line), ((line.find(
"End") == std::string::npos) && (in)))
1563 apply_grid_fixup_functions(vertices, cells, subcelldata);
1564 tria->create_triangulation(vertices, cells, subcelldata);
1569template <
int dim,
int spacedim>
1580 std::getline(in, line);
1582 unsigned int n_vertices;
1583 unsigned int n_cells;
1587 std::getline(in, line);
1590 std::getline(in, line);
1593 for (
unsigned int i = 0; i < 8; ++i)
1594 std::getline(in, line);
1597 std::vector<CellData<dim>> cells(n_cells);
1608 for (
unsigned int i = 0; i < GeometryInfo<dim>::vertices_per_cell; ++i)
1609 in >> cell.vertices[reference_cell.exodusii_vertex_to_deal_vertex(i)];
1613 std::vector<Point<spacedim>> vertices(n_vertices);
1616 for (
unsigned int d = 0; d < spacedim; ++d)
1618 for (
unsigned int d = spacedim; d < 3; ++d)
1627 apply_grid_fixup_functions(vertices, cells, subcelldata);
1628 tria->create_triangulation(vertices, cells, subcelldata);
1633template <
int dim,
int spacedim>
1650 std::stringstream whole_file;
1655 std::getline(in, line);
1663 if ((line.size() > 0) && (line.back() ==
'\r'))
1664 line.erase(line.size() - 1);
1669 if (line.find(
'#') != std::string::npos)
1670 line.erase(line.find(
'#'), std::string::npos);
1671 while ((line.size() > 0) && (line.back() ==
' '))
1672 line.erase(line.size() - 1);
1674 if (line.size() > 0)
1675 whole_file <<
'\n' << line;
1694 unsigned int version_major, version_minor;
1695 whole_file >> version_major >> version_minor;
1696 AssertThrow((version_major == 0) && (version_minor == 1),
1697 ExcMessage(
"deal.II can currently only read version 0.1 "
1698 "of the mphtxt file format."));
1703 unsigned int n_tags;
1704 whole_file >> n_tags;
1705 for (
unsigned int i = 0; i < n_tags; ++i)
1708 while (whole_file.peek() ==
'\n')
1710 std::getline(whole_file, dummy);
1716 unsigned int n_types;
1717 whole_file >> n_types;
1718 for (
unsigned int i = 0; i < n_types; ++i)
1721 while (whole_file.peek() ==
'\n')
1723 std::getline(whole_file, dummy);
1743 whole_file >> dummy >> dummy >> dummy;
1747 while (whole_file.peek() ==
'\n')
1749 std::getline(whole_file, s);
1751 ExcMessage(
"Expected '4 Mesh', but got '" + s +
"'."));
1754 unsigned int version;
1755 whole_file >> version;
1759 unsigned int file_space_dim;
1760 whole_file >> file_space_dim;
1764 "The mesh file uses a different number of space dimensions "
1765 "than the triangulation you want to read it into."));
1767 unsigned int n_vertices;
1768 whole_file >> n_vertices;
1770 unsigned int starting_vertex_index;
1771 whole_file >> starting_vertex_index;
1773 std::vector<Point<spacedim>> vertices(n_vertices);
1774 for (
unsigned int v = 0; v < n_vertices; ++v)
1775 whole_file >> vertices[v];
1805 std::vector<CellData<dim>> cells;
1808 unsigned int n_types;
1809 whole_file >> n_types;
1810 for (
unsigned int type = 0; type < n_types; ++type)
1817 whole_file >> dummy;
1821 std::string object_name;
1822 whole_file >> object_name;
1824 const std::set<std::string> known_object_names = {
1825 "vtx",
"edg",
"tri",
"quad",
"tet",
"prism"
1829 AssertThrow(known_object_names.find(object_name) !=
1830 known_object_names.end(),
1831 ExcMessage(
"The input file contains a cell type <" +
1833 "> that the reader does not "
1834 "current support"));
1836 unsigned int n_vertices_per_element;
1837 whole_file >> n_vertices_per_element;
1839 unsigned int n_elements;
1840 whole_file >> n_elements;
1843 if ((dim >= 3) && (object_name ==
"tet"))
1846 ExcMessage(
"Tetrahedra should not appear in input files "
1847 "for 1d or 2d meshes."));
1850 else if ((dim >= 3) && (object_name ==
"prism"))
1854 "Prisms (wedges) should not appear in input files "
1855 "for 1d or 2d meshes."));
1858 else if ((dim >= 2) && (object_name ==
"tri"))
1861 ExcMessage(
"Triangles should not appear in input files "
1865 else if ((dim >= 2) && (object_name ==
"quad"))
1869 "Quadrilaterals should not appear in input files "
1873 else if (object_name ==
"edg")
1877 else if (object_name ==
"vtx")
1901 vertices_for_this_element(n_vertices_per_element);
1902 for (
unsigned int e = 0; e < n_elements; ++e)
1905 for (
unsigned int v = 0; v < n_vertices_per_element; ++v)
1907 whole_file >> vertices_for_this_element[v];
1908 vertices_for_this_element[v] -= starting_vertex_index;
1912 ((object_name ==
"tet") || (object_name ==
"prism")))
1916 cells.emplace_back();
1917 cells.back().vertices = vertices_for_this_element;
1922 else if ((dim >= 2) &&
1923 ((object_name ==
"tri") || (object_name ==
"quad")))
1927 cells.emplace_back();
1928 cells.back().vertices = vertices_for_this_element;
1934 vertices_for_this_element.begin(),
1935 vertices_for_this_element.end());
1938 else if (object_name ==
"edg")
1942 cells.emplace_back();
1943 cells.back().vertices = vertices_for_this_element;
1949 vertices_for_this_element.begin(),
1950 vertices_for_this_element.end());
1953 else if (object_name ==
"vtx")
1964 unsigned int n_geom_entity_indices;
1965 whole_file >> n_geom_entity_indices;
1967 (n_geom_entity_indices == n_elements),
1974 if (n_geom_entity_indices != 0)
1976 for (
unsigned int e = 0; e < n_geom_entity_indices; ++e)
1979 unsigned int geometric_entity_index;
1980 whole_file >> geometric_entity_index;
1981 if (object_name ==
"vtx")
1983 else if (object_name ==
"edg")
1986 cells[cells.size() - n_elements + e].material_id =
1987 geometric_entity_index;
1992 .boundary_id = geometric_entity_index;
1994 else if ((dim >= 2) &&
1995 ((object_name ==
"tri") || (object_name ==
"quad")))
1998 cells[cells.size() - n_elements + e].material_id =
1999 geometric_entity_index;
2004 .boundary_id = geometric_entity_index;
2006 else if ((dim >= 3) &&
2007 ((object_name ==
"tet") || (object_name ==
"prism")))
2010 cells[cells.size() - n_elements + e].material_id =
2011 geometric_entity_index;
2027 tria->create_triangulation(vertices, cells, {});
2037 if (line.vertices[1] < line.vertices[0])
2038 std::swap(line.vertices[0], line.vertices[1]);
2043 return std::lexicographical_compare(a.vertices.begin(),
2065 Assert((face.vertices.size() == 3) || (face.vertices.size() == 4),
2067 std::sort(face.vertices.begin(), face.vertices.end());
2072 return std::lexicographical_compare(a.vertices.begin(),
2082 for (
const auto &cell :
tria->active_cell_iterators())
2083 for (
const auto &face : cell->face_iterators())
2084 if (face->at_boundary())
2090 std::array<unsigned int, 2> face_vertex_indices = {
2091 {face->vertex_index(0), face->vertex_index(1)}};
2092 if (face_vertex_indices[0] > face_vertex_indices[1])
2093 std::swap(face_vertex_indices[0], face_vertex_indices[1]);
2099 face_vertex_indices,
2101 const std::array<unsigned int, 2>
2102 &face_vertex_indices) ->
bool {
2103 return std::lexicographical_compare(
2106 face_vertex_indices.begin(),
2107 face_vertex_indices.end());
2111 (p->vertices[0] == face_vertex_indices[0]) &&
2112 (p->vertices[1] == face_vertex_indices[1]))
2114 face->set_boundary_id(p->boundary_id);
2124 face_vertex_indices(face->n_vertices());
2125 for (
unsigned int v = 0; v < face->n_vertices(); ++v)
2126 face_vertex_indices[v] = face->vertex_index(v);
2127 std::sort(face_vertex_indices.begin(),
2128 face_vertex_indices.end());
2131 const auto p = std::lower_bound(
2134 face_vertex_indices,
2136 const auto &face_vertex_indices) ->
bool {
2137 return std::lexicographical_compare(
2140 face_vertex_indices.begin(),
2141 face_vertex_indices.end());
2145 (p->vertices == face_vertex_indices))
2147 face->set_boundary_id(p->boundary_id);
2152 for (
unsigned int e = 0; e < face->n_lines(); ++e)
2154 const auto edge = face->line(e);
2156 std::array<unsigned int, 2> edge_vertex_indices = {
2157 {edge->vertex_index(0), edge->vertex_index(1)}};
2158 if (edge_vertex_indices[0] > edge_vertex_indices[1])
2159 std::swap(edge_vertex_indices[0],
2160 edge_vertex_indices[1]);
2166 edge_vertex_indices,
2168 const std::array<unsigned int, 2>
2169 &edge_vertex_indices) ->
bool {
2170 return std::lexicographical_compare(
2173 edge_vertex_indices.begin(),
2174 edge_vertex_indices.end());
2178 (p->vertices[0] == edge_vertex_indices[0]) &&
2179 (p->vertices[1] == edge_vertex_indices[1]))
2181 edge->set_boundary_id(p->boundary_id);
2191template <
int dim,
int spacedim>
2198 unsigned int n_vertices;
2199 unsigned int n_cells;
2205 std::array<std::map<int, int>, 4> tag_maps;
2208 std::string stripped_file;
2212 while (std::getline(input_stream, line))
2214 if (line ==
"@f$Comments")
2216 while (std::getline(input_stream, line))
2218 if (line ==
"@f$EndComments")
2225 stripped_file += line +
'\n';
2229 std::istringstream in(stripped_file);
2234 unsigned int gmsh_file_format = 0;
2235 if (line ==
"@f$NOD")
2236 gmsh_file_format = 10;
2237 else if (line ==
"@f$MeshFormat")
2238 gmsh_file_format = 20;
2244 if (gmsh_file_format == 20)
2247 unsigned int file_type, data_size;
2249 in >> version >> file_type >> data_size;
2252 gmsh_file_format =
static_cast<unsigned int>(version * 10);
2264 if (line ==
"@f$PhysicalNames")
2270 while (line !=
"@f$EndPhysicalNames");
2275 if (line ==
"@f$Entities")
2277 unsigned long n_points, n_curves, n_surfaces, n_volumes;
2279 in >> n_points >> n_curves >> n_surfaces >> n_volumes;
2280 for (
unsigned int i = 0; i < n_points; ++i)
2284 unsigned int n_physicals;
2285 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2289 if (gmsh_file_format > 40)
2291 in >> tag >> box_min_x >> box_min_y >> box_min_z >>
2293 box_max_x = box_min_x;
2294 box_max_y = box_min_y;
2295 box_max_z = box_min_z;
2299 in >> tag >> box_min_x >> box_min_y >> box_min_z >>
2300 box_max_x >> box_max_y >> box_max_z >> n_physicals;
2305 ExcMessage(
"More than one tag is not supported!"));
2307 int physical_tag = 0;
2308 for (
unsigned int j = 0; j < n_physicals; ++j)
2310 tag_maps[0][tag] = physical_tag;
2312 for (
unsigned int i = 0; i < n_curves; ++i)
2316 unsigned int n_physicals;
2317 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2321 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2322 box_max_y >> box_max_z >> n_physicals;
2326 ExcMessage(
"More than one tag is not supported!"));
2328 int physical_tag = 0;
2329 for (
unsigned int j = 0; j < n_physicals; ++j)
2331 tag_maps[1][tag] = physical_tag;
2336 for (
unsigned int j = 0; j < n_points; ++j)
2340 for (
unsigned int i = 0; i < n_surfaces; ++i)
2344 unsigned int n_physicals;
2345 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2349 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2350 box_max_y >> box_max_z >> n_physicals;
2354 ExcMessage(
"More than one tag is not supported!"));
2356 int physical_tag = 0;
2357 for (
unsigned int j = 0; j < n_physicals; ++j)
2359 tag_maps[2][tag] = physical_tag;
2364 for (
unsigned int j = 0; j < n_curves; ++j)
2367 for (
unsigned int i = 0; i < n_volumes; ++i)
2371 unsigned int n_physicals;
2372 double box_min_x, box_min_y, box_min_z, box_max_x, box_max_y,
2376 in >> tag >> box_min_x >> box_min_y >> box_min_z >> box_max_x >>
2377 box_max_y >> box_max_z >> n_physicals;
2381 ExcMessage(
"More than one tag is not supported!"));
2383 int physical_tag = 0;
2384 for (
unsigned int j = 0; j < n_physicals; ++j)
2386 tag_maps[3][tag] = physical_tag;
2391 for (
unsigned int j = 0; j < n_surfaces; ++j)
2400 if (line ==
"@f$PartitionedEntities")
2406 while (line !=
"@f$EndPartitionedEntities");
2417 int n_entity_blocks = 1;
2418 if (gmsh_file_format > 40)
2422 in >> n_entity_blocks >> n_vertices >> min_node_tag >> max_node_tag;
2424 else if (gmsh_file_format == 40)
2426 in >> n_entity_blocks >> n_vertices;
2430 std::vector<Point<spacedim>> vertices(n_vertices);
2434 std::map<int, int> vertex_indices;
2437 unsigned int global_vertex = 0;
2438 for (
int entity_block = 0; entity_block < n_entity_blocks; ++entity_block)
2441 unsigned long numNodes;
2443 if (gmsh_file_format < 40)
2445 numNodes = n_vertices;
2452 int tagEntity, dimEntity;
2453 in >> tagEntity >> dimEntity >> parametric >> numNodes;
2456 std::vector<int> vertex_numbers;
2458 if (gmsh_file_format > 40)
2459 for (
unsigned long vertex_per_entity = 0;
2460 vertex_per_entity < numNodes;
2461 ++vertex_per_entity)
2463 in >> vertex_number;
2464 vertex_numbers.push_back(vertex_number);
2467 for (
unsigned long vertex_per_entity = 0; vertex_per_entity < numNodes;
2468 ++vertex_per_entity, ++global_vertex)
2474 if (gmsh_file_format > 40)
2476 vertex_number = vertex_numbers[vertex_per_entity];
2477 in >> x[0] >> x[1] >> x[2];
2480 in >> vertex_number >> x[0] >> x[1] >> x[2];
2483 global_vertex < n_vertices,
2485 "The Gmsh file lists more nodes than were declared in the "
2486 "header of the @f$Nodes section."));
2488 for (
unsigned int d = 0; d < spacedim; ++d)
2489 vertices[global_vertex][d] = x[d];
2491 vertex_indices[vertex_number] = global_vertex;
2494 if (parametric != 0)
2509 const std::array<std::string, 2> end_nodes_marker{{
"@f$ENDNOD",
"@f$EndNodes"}};
2510 AssertThrow(line == end_nodes_marker[gmsh_file_format == 10 ? 0 : 1],
2515 const std::array<std::string, 2> begin_elements_marker{{
"@f$ELM",
"@f$Elements"}};
2516 AssertThrow(line == begin_elements_marker[gmsh_file_format == 10 ? 0 : 1],
2520 if (gmsh_file_format > 40)
2524 in >> n_entity_blocks >> n_cells >> min_node_tag >> max_node_tag;
2526 else if (gmsh_file_format == 40)
2528 in >> n_entity_blocks >> n_cells;
2532 n_entity_blocks = 1;
2539 std::vector<CellData<dim>> cells;
2541 std::map<unsigned int, types::boundary_id> boundary_ids_1d;
2547 std::map<unsigned int, unsigned int> vertex_counts;
2550 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
2551 {0, 1, 5, 4, 2, 3, 7, 6}};
2552 unsigned int global_cell = 0;
2553 for (
int entity_block = 0; entity_block < n_entity_blocks; ++entity_block)
2555 unsigned int material_id;
2556 unsigned long numElements;
2559 if (gmsh_file_format < 40)
2563 numElements = n_cells;
2565 else if (gmsh_file_format == 40)
2567 int tagEntity, dimEntity;
2568 in >> tagEntity >> dimEntity >> cell_type >> numElements;
2569 material_id = tag_maps[dimEntity][tagEntity];
2574 int tagEntity, dimEntity;
2575 in >> dimEntity >> tagEntity >> cell_type >> numElements;
2576 material_id = tag_maps[dimEntity][tagEntity];
2579 for (
unsigned int cell_per_entity = 0; cell_per_entity < numElements;
2580 ++cell_per_entity, ++global_cell)
2589 unsigned int nod_num;
2610 unsigned int elm_number = 0;
2611 if (gmsh_file_format < 40)
2617 if (gmsh_file_format < 20)
2623 else if (gmsh_file_format < 40)
2628 unsigned int n_tags;
2635 for (
unsigned int i = 1; i < n_tags; ++i)
2640 else if (cell_type == 2)
2642 else if (cell_type == 3)
2644 else if (cell_type == 4)
2646 else if (cell_type == 5)
2657 else if (cell_type == 2)
2659 else if (cell_type == 3)
2661 else if (cell_type == 4)
2663 else if (cell_type == 5)
2689 if (((cell_type == 1) && (dim == 1)) ||
2690 ((cell_type == 2) && (dim == 2)) ||
2691 ((cell_type == 3) && (dim == 2)) ||
2692 ((cell_type == 4) && (dim == 3)) ||
2693 ((cell_type == 5) && (dim == 3)))
2699 else if (cell_type == 2)
2701 else if (cell_type == 3)
2703 else if (cell_type == 4)
2705 else if (cell_type == 5)
2710 "Number of nodes does not coincide with the "
2711 "number required for this object"));
2714 cells.emplace_back();
2723 local_vertex_numbering[i] :
2731 std::numeric_limits<types::material_id>::max(),
2735 std::numeric_limits<types::material_id>::max()));
2749 vertex_indices.end(),
2754 const auto vertex = vertex_indices[cell.
vertices[i]];
2756 vertex_counts[vertex] += 1u;
2760 else if ((cell_type == 1) &&
2761 ((dim == 2) || (dim == 3)))
2770 std::numeric_limits<types::boundary_id>::max(),
2774 std::numeric_limits<types::boundary_id>::max()));
2787 for (
unsigned int &vertex :
2789 if (vertex_indices.find(vertex) != vertex_indices.end())
2791 vertex = vertex_indices[vertex];
2801 else if ((cell_type == 2 || cell_type == 3) &&
2809 else if (cell_type == 3)
2823 std::numeric_limits<types::boundary_id>::max(),
2827 std::numeric_limits<types::boundary_id>::max()));
2840 for (
unsigned int &vertex :
2842 if (vertex_indices.find(vertex) != vertex_indices.end())
2844 vertex = vertex_indices[vertex];
2854 else if (cell_type == 15)
2857 unsigned int node_index = 0;
2858 if (gmsh_file_format < 20)
2874 boundary_ids_1d[vertex_indices[node_index]] = material_id;
2886 const std::array<std::string, 2> end_elements_marker{
2887 {
"@f$ENDELM",
"@f$EndElements"}};
2888 AssertThrow(line == end_elements_marker[gmsh_file_format == 10 ? 0 : 1],
2902 for (
const auto &pair : vertex_counts)
2903 if (pair.second == 1u)
2904 boundary_id_pairs.emplace_back(vertices[pair.first],
2905 boundary_ids_1d[pair.first]);
2907 apply_grid_fixup_functions(vertices, cells, subcelldata);
2908 tria->create_triangulation(vertices, cells, subcelldata);
2913 assign_1d_boundary_ids(boundary_id_pairs, *
tria);
2918template <
int dim,
int spacedim>
2922#ifdef DEAL_II_GMSH_WITH_API
2925 const std::map<int, std::uint8_t> gmsh_to_dealii_type = {
2926 {{15, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {7, 5}, {6, 6}, {5, 7}}};
2929 const std::array<std::vector<unsigned int>, 8> gmsh_to_dealii = {
2936 {{0, 1, 2, 3, 4, 5}},
2937 {{0, 1, 3, 2, 4, 5, 7, 6}}}};
2939 std::vector<Point<spacedim>> vertices;
2940 std::vector<CellData<dim>> cells;
2942 std::map<unsigned int, types::boundary_id> boundary_ids_1d;
2948 std::map<unsigned int, unsigned int> vertex_counts;
2950# if DEAL_II_GMSH_WITH_API_VERSION_GTE(4, 9, 4)
2952 ExcMessage(
"The GMSH API may only be called after GMSH is "
2953 "initialized, e.g., via the InitFinalize or "
2954 "MPI_InitFinalize classes or the gmsh::initialize() "
2957 gmsh::option::setNumber(
"General.Verbosity", 0);
2962 ExcMessage(
"You are trying to read a gmsh file with dimension " +
2963 std::to_string(gmsh::model::getDimension()) +
2964 " into a grid of dimension " + std::to_string(dim)));
2969 gmsh::model::mesh::removeDuplicateNodes();
2970 gmsh::model::mesh::renumberNodes();
2971 std::vector<std::size_t> node_tags;
2972 std::vector<double> coord;
2973 std::vector<double> parametricCoord;
2974 gmsh::model::mesh::getNodes(
2975 node_tags, coord, parametricCoord, -1, -1,
false,
false);
2976 vertices.resize(node_tags.size());
2977 for (
unsigned int i = 0; i < node_tags.size(); ++i)
2981 for (
unsigned int d = 0; d < spacedim; ++d)
2982 vertices[i][d] = coord[i * 3 + d];
2986 for (
unsigned int d = spacedim; d < 3; ++d)
2989 "The grid you are reading contains nodes that are "
2990 "nonzero in the coordinate with index " +
2992 ", but you are trying to save "
2993 "it on a grid embedded in a " +
2994 std::to_string(spacedim) +
" dimensional space."));
3001 std::vector<std::pair<int, int>> entities;
3002 gmsh::model::getEntities(entities);
3004 for (
const auto &[entity_dim, entity_tag] : entities)
3013 std::vector<int> physical_tags;
3014 gmsh::model::getPhysicalGroupsForEntity(entity_dim,
3019 if (physical_tags.size())
3020 for (
auto physical_tag : physical_tags)
3023 gmsh::model::getPhysicalName(entity_dim, physical_tag, name);
3030 std::map<std::string, int> id_names;
3032 bool found_unrecognized_tag =
false;
3033 bool found_boundary_id =
false;
3036 for (
const auto &[name,
id] : id_names)
3038 if (entity_dim == dim && name ==
"MaterialID")
3041 found_boundary_id =
true;
3043 else if (entity_dim < dim && name ==
"BoundaryID")
3046 found_boundary_id =
true;
3048 else if (name ==
"ManifoldID")
3054 found_unrecognized_tag =
true;
3059 if (found_unrecognized_tag && !found_boundary_id)
3060 boundary_id = physical_tag;
3068 boundary_id = physical_tag;
3074 std::vector<int> element_types;
3075 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3076 gmsh::model::mesh::getElements(
3077 element_types, element_ids, element_nodes, entity_dim, entity_tag);
3079 for (
unsigned int i = 0; i < element_types.size(); ++i)
3081 const auto &type = gmsh_to_dealii_type.at(element_types[i]);
3082 const auto n_vertices = gmsh_to_dealii[type].size();
3083 const auto &elements = element_ids[i];
3084 const auto &nodes = element_nodes[i];
3085 for (
unsigned int j = 0; j < elements.size(); ++j)
3087 if (entity_dim == dim)
3089 cells.emplace_back(n_vertices);
3090 auto &cell = cells.back();
3091 for (
unsigned int v = 0; v < n_vertices; ++v)
3094 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3096 vertex_counts[cell.vertices[v]] += 1u;
3098 cell.manifold_id = manifold_id;
3099 cell.material_id = boundary_id;
3101 else if (entity_dim == 2)
3105 for (
unsigned int v = 0; v < n_vertices; ++v)
3107 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3109 face.manifold_id = manifold_id;
3110 face.boundary_id = boundary_id;
3112 else if (entity_dim == 1)
3116 for (
unsigned int v = 0; v < n_vertices; ++v)
3118 nodes[n_vertices * j + gmsh_to_dealii[type][v]] - 1;
3120 line.manifold_id = manifold_id;
3121 line.boundary_id = boundary_id;
3123 else if (entity_dim == 0)
3127 for (
unsigned int j = 0; j < elements.size(); ++j)
3128 boundary_ids_1d[nodes[j] - 1] = boundary_id;
3139 for (
const auto &pair : vertex_counts)
3140 if (pair.second == 1u)
3141 boundary_id_pairs.emplace_back(vertices[pair.first],
3142 boundary_ids_1d[pair.first]);
3144 apply_grid_fixup_functions(vertices, cells, subcelldata);
3145 tria->create_triangulation(vertices, cells, subcelldata);
3150 assign_1d_boundary_ids(boundary_id_pairs, *
tria);
3161template <
int dim,
int spacedim>
3164 const std::string &file_suffix)
3166#ifdef DEAL_II_GMSH_WITH_API
3167 auto *parallel_tria =
3173 ExcMessage(
"Triangulation is not fully distributed!"));
3176 MPI_Comm mpi_comm = parallel_tria->get_communicator();
3182 file_prefix +
"_" + std::to_string(rank + 1) +
"." + file_suffix;
3186 fname = file_prefix +
"." + file_suffix;
3193 for (
unsigned int i = 1; i <= nprocs; ++i)
3195 const std::string check_fname =
3196 file_prefix +
"_" + std::to_string(i) +
"." + file_suffix;
3199 ExcMessage(
"Missing mesh file: " + check_fname));
3202 const std::string extra_fname =
3203 file_prefix +
"_" + std::to_string(nprocs + 1) +
"." + file_suffix;
3204 AssertThrow(!std::filesystem::exists(extra_fname),
3205 ExcMessage(
"Expected " + std::to_string(nprocs) +
3206 " mesh files, but found extra: " + extra_fname));
3209 const std::map<int, std::uint8_t> gmsh_to_dealii_type = {
3210 {15, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {7, 5}, {6, 6}, {5, 7}};
3212 const std::array<std::vector<unsigned int>, 8> gmsh_to_dealii = {
3220 {0, 1, 3, 2, 4, 5, 7, 6}}};
3222# if DEAL_II_GMSH_WITH_API_VERSION_GTE(4, 9, 4)
3224 ExcMessage(
"The GMSH API may only be called after GMSH is "
3225 "initialized, e.g., via the InitFinalize or "
3226 "MPI_InitFinalize classes or the gmsh::initialize() "
3229 gmsh::option::setNumber(
"General.Verbosity", 0);
3233 std::map<unsigned long, unsigned int> ghost_map;
3235 std::vector<std::pair<int, int>> entities;
3236 gmsh::model::getEntities(entities);
3238 for (
const auto &e : entities)
3240 const int entity_dim = e.first;
3241 const int entity_tag = e.second;
3243 if (entity_dim == dim)
3245 std::vector<std::size_t> element_tags;
3246 std::vector<int> partitions;
3248 gmsh::model::mesh::getGhostElements(entity_dim,
3253 for (std::size_t i = 0; i < element_tags.size(); ++i)
3254 ghost_map[element_tags[i]] =
3255 static_cast<unsigned int>(partitions[i] - 1);
3259 std::vector<std::size_t> node_tags;
3260 std::vector<double> coords, parametric_coords;
3261 gmsh::model::mesh::getNodes(node_tags, coords, parametric_coords);
3264 triangulation_description;
3265 triangulation_description.
comm = mpi_comm;
3267 triangulation_description.
cell_infos.resize(1);
3271 std::map<std::size_t, unsigned int> node_tag_to_index;
3272 for (
unsigned int i = 0; i < node_tags.size(); ++i)
3274 node_tag_to_index[node_tags[i]] = i;
3275 for (
unsigned int d = 0; d < spacedim; ++d)
3285 std::vector<std::pair<int, int>> physical_groups;
3286 gmsh::model::getPhysicalGroups(physical_groups);
3288 for (
const auto &[physical_dim, physical_tag] : physical_groups)
3290 std::vector<int> physical_entities;
3291 gmsh::model::getEntitiesForPhysicalGroup(physical_dim,
3295 for (
const int ent : physical_entities)
3298 if (physical_dim == dim - 1)
3299 entity_to_boundary[{physical_dim, ent}] = physical_tag;
3300 if (physical_dim == dim)
3301 entity_to_material[{physical_dim, ent}] = physical_tag;
3310 for (
const auto &e : entities)
3311 if (e.first == dim - 1)
3312 if (
auto it = entity_to_boundary.find({e.first, e.second});
3313 it != entity_to_boundary.end())
3317 std::vector<int> element_types;
3318 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3321 gmsh::model::mesh::getElements(
3322 element_types, element_ids, element_nodes, e.first, e.second);
3324 for (
unsigned int i = 0; i < element_types.size(); ++i)
3326 if (element_ids[i].empty())
3329 const unsigned int n_nodes_per_elem =
3330 element_nodes[i].size() / element_ids[i].size();
3332 for (
unsigned int j = 0; j < element_ids[i].size(); ++j)
3334 std::set<unsigned int> face_vertices;
3335 for (
unsigned int k = 0; k < n_nodes_per_elem; ++k)
3337 std::size_t node_tag =
3338 element_nodes[i][j * n_nodes_per_elem + k];
3339 face_vertices.insert(node_tag_to_index[node_tag]);
3344 boundary_face_map[face_vertices] = boundary_id;
3352 std::size_t total_volume_elements = 0;
3353 for (
const auto &[entity_dim, entity_tag] : entities)
3355 if (entity_dim == dim)
3357 std::vector<int> count_element_types;
3358 std::vector<std::vector<std::size_t>> count_element_ids,
3359 count_element_nodes;
3361 gmsh::model::mesh::getElements(count_element_types,
3363 count_element_nodes,
3367 for (
const auto &count_element_id : count_element_ids)
3368 total_volume_elements += count_element_id.size();
3373 triangulation_description.
coarse_cells.reserve(total_volume_elements);
3375 total_volume_elements);
3376 triangulation_description.
cell_infos[0].reserve(total_volume_elements);
3378 for (
const auto &[entity_dim, entity_tag] : entities)
3380 if (entity_dim == dim)
3382 std::vector<int> element_types;
3383 std::vector<std::vector<std::size_t>> element_ids, element_nodes;
3385 gmsh::model::mesh::getElements(
3386 element_types, element_ids, element_nodes, entity_dim, entity_tag);
3388 for (
unsigned int i = 0; i < element_types.size(); ++i)
3390 if (element_ids[i].empty())
3393 const unsigned int n_vertices =
3394 element_nodes[i].size() / element_ids[i].size();
3396 for (
unsigned int j = 0; j < element_ids[i].size(); ++j)
3401 if (
auto it = entity_to_material.find({dim, entity_tag});
3402 it != entity_to_material.end())
3405 const auto &type = gmsh_to_dealii_type.at(element_types[i]);
3407 for (
unsigned int v = 0; v < n_vertices; ++v)
3409 const std::size_t node_tag =
3411 [j * n_vertices + gmsh_to_dealii[type][v]];
3413 node_tag_to_index.end(),
3415 std::to_string(node_tag) +
3416 " not found in node list!"));
3417 cell.
vertices[v] = node_tag_to_index[node_tag];
3422 CellId(element_ids[i][j], {}).
template to_binary<dim>();
3424 auto it = ghost_map.find(element_ids[i][j]);
3425 if (it != ghost_map.end())
3434 if constexpr (dim > 0)
3442 const unsigned int n_faces = ref_cell.
n_faces();
3444 for (
unsigned int f = 0; f < n_faces; ++f)
3446 std::set<unsigned int> face_vertices;
3448 if constexpr (dim == 1)
3451 face_vertices.insert(cell.
vertices[f]);
3453 else if constexpr (dim == 2)
3460 face_vertices.insert(cell.
vertices[f]);
3461 face_vertices.insert(
3464 else if (ref_cell ==
3467 const unsigned int n_face_vertices =
3470 for (
unsigned int fv = 0;
3471 fv < n_face_vertices;
3474 const unsigned int vertex_index =
3479 default_geometric_orientation);
3480 face_vertices.insert(
3485 else if constexpr (dim == 3)
3488 const unsigned int n_face_vertices =
3490 for (
unsigned int fv = 0; fv < n_face_vertices;
3493 const unsigned int vertex_index =
3498 face_vertices.insert(
3504 if (
auto it = boundary_face_map.find(face_vertices);
3505 it != boundary_face_map.end())
3510 triangulation_description.
coarse_cells.push_back(cell);
3512 .push_back(element_ids[i][j]);
3513 triangulation_description.
cell_infos[0].push_back(cell_info);
3519 triangulation_description.
settings =
3522 parallel_tria->create_triangulation(triangulation_description);
3525# ifdef DEAL_II_WITH_MPI
3526 const int mpi_ierr = MPI_Barrier(mpi_comm);
3539template <
int dim,
int spacedim>
3542 std::string &header,
3543 std::vector<unsigned int> &tecplot2deal,
3544 unsigned int &n_vars,
3545 unsigned int &n_vertices,
3546 unsigned int &n_cells,
3547 std::vector<unsigned int> &IJK,
3572 std::transform(header.begin(),
3575 static_cast<int (*)(
int)
>(std::toupper));
3579 std::replace(header.begin(), header.end(),
'\t',
' ');
3580 std::replace(header.begin(), header.end(),
',',
' ');
3581 std::replace(header.begin(), header.end(),
'\n',
' ');
3585 std::string::size_type pos = header.find(
'=');
3587 while (pos !=
static_cast<std::string::size_type
>(std::string::npos))
3588 if (header[pos + 1] ==
' ')
3589 header.erase(pos + 1, 1);
3590 else if (header[pos - 1] ==
' ')
3592 header.erase(pos - 1, 1);
3596 pos = header.find(
'=', ++pos);
3599 std::vector<std::string> entries =
3603 for (
unsigned int i = 0; i < entries.size(); ++i)
3612 tecplot2deal[0] = 0;
3615 while (entries[i][0] ==
'"')
3617 if (entries[i] ==
"\"X\"")
3618 tecplot2deal[0] = n_vars;
3619 else if (entries[i] ==
"\"Y\"")
3625 tecplot2deal[1] = n_vars;
3627 else if (entries[i] ==
"\"Z\"")
3633 tecplot2deal[2] = n_vars;
3645 "Tecplot file must contain at least one variable for each dimension"));
3646 for (
unsigned int d = 1; d < dim; ++d)
3648 tecplot2deal[d] > 0,
3650 "Tecplot file must contain at least one variable for each dimension."));
3655 "ZONETYPE=FELINESEG") &&
3659 "ZONETYPE=FEQUADRILATERAL") &&
3663 "ZONETYPE=FEBRICK") &&
3671 "The tecplot file contains an unsupported ZONETYPE."));
3674 "DATAPACKING=POINT"))
3677 "DATAPACKING=BLOCK"))
3700 "ET=QUADRILATERAL") &&
3712 "The tecplot file contains an unsupported ElementType."));
3720 dim > 1 || IJK[1] == 1,
3722 "Parameter 'J=' found in tecplot, although this is only possible for dimensions greater than 1."));
3728 dim > 2 || IJK[2] == 1,
3730 "Parameter 'K=' found in tecplot, although this is only possible for dimensions greater than 2."));
3745 for (
unsigned int d = 0; d < dim; ++d)
3750 "Tecplot file does not contain a complete and consistent set of parameters"));
3751 n_vertices *= IJK[d];
3752 n_cells *= (IJK[d] - 1);
3760 "Tecplot file does not contain a complete and consistent set of parameters"));
3766 n_cells = *std::max_element(IJK.begin(), IJK.end());
3770 "Tecplot file does not contain a complete and consistent set of parameters"));
3780 const unsigned int dim = 2;
3781 const unsigned int spacedim = 2;
3789 std::string line, header;
3796 std::string letters =
"abcdfghijklmnopqrstuvwxyzABCDFGHIJKLMNOPQRSTUVWXYZ";
3799 while (line.find_first_of(letters) != std::string::npos)
3801 header +=
" " + line;
3808 std::vector<unsigned int> tecplot2deal(dim);
3809 std::vector<unsigned int> IJK(dim);
3810 unsigned int n_vars, n_vertices, n_cells;
3811 bool structured, blocked;
3828 std::vector<Point<spacedim>> vertices(n_vertices + 1);
3831 std::vector<CellData<dim>> cells(n_cells);
3847 unsigned int next_index = 0;
3851 if (tecplot2deal[0] == 0)
3855 std::vector<std::string> first_var =
3858 for (
unsigned int i = 1; i < first_var.size() + 1; ++i)
3859 vertices[i][0] = std::strtod(first_var[i - 1].c_str(), &endptr);
3864 for (
unsigned int j = first_var.size() + 1; j < n_vertices + 1; ++j)
3865 in >> vertices[j][next_index];
3872 for (
unsigned int i = 1; i < n_vars; ++i)
3881 if (next_index == dim && structured)
3884 if ((next_index < dim) && (i == tecplot2deal[next_index]))
3887 for (
unsigned int j = 1; j < n_vertices + 1; ++j)
3888 in >> vertices[j][next_index];
3895 for (
unsigned int j = 1; j < n_vertices + 1; ++j)
3907 std::vector<double> vars(n_vars);
3912 std::vector<std::string> first_vertex =
3915 for (
unsigned int d = 0; d < dim; ++d)
3917 std::strtod(first_vertex[tecplot2deal[d]].c_str(), &endptr);
3921 for (
unsigned int v = 2; v < n_vertices + 1; ++v)
3923 for (
unsigned int i = 0; i < n_vars; ++i)
3929 for (
unsigned int i = 0; i < dim; ++i)
3930 vertices[v][i] = vars[tecplot2deal[i]];
3938 unsigned int I = IJK[0], J = IJK[1];
3940 unsigned int cell = 0;
3942 for (
unsigned int j = 0; j < J - 1; ++j)
3943 for (
unsigned int i = 1; i < I; ++i)
3945 cells[cell].vertices[0] = i + j * I;
3946 cells[cell].vertices[1] = i + 1 + j * I;
3947 cells[cell].vertices[2] = i + (j + 1) * I;
3948 cells[cell].vertices[3] = i + 1 + (j + 1) * I;
3952 std::vector<unsigned int> boundary_vertices(2 * I + 2 * J - 4);
3954 for (
unsigned int i = 1; i < I + 1; ++i)
3956 boundary_vertices[k] = i;
3958 boundary_vertices[k] = i + (J - 1) * I;
3961 for (
unsigned int j = 1; j < J - 1; ++j)
3963 boundary_vertices[k] = 1 + j * I;
3965 boundary_vertices[k] = I + j * I;
3984 for (
unsigned int i = 0; i < n_cells; ++i)
4001 apply_grid_fixup_functions(vertices, cells, subcelldata);
4002 tria->create_triangulation(vertices, cells, subcelldata);
4007template <
int dim,
int spacedim>
4016template <
int dim,
int spacedim>
4019 const unsigned int mesh_index,
4020 const bool remove_duplicates,
4022 const bool ignore_unsupported_types)
4024#ifdef DEAL_II_WITH_ASSIMP
4029 Assimp::Importer importer;
4032 const aiScene *scene =
4033 importer.ReadFile(filename.c_str(),
4034 aiProcess_RemoveComponent |
4035 aiProcess_JoinIdenticalVertices |
4036 aiProcess_ImproveCacheLocality | aiProcess_SortByPType |
4037 aiProcess_OptimizeGraph | aiProcess_OptimizeMeshes);
4043 ExcMessage(
"Input file contains no meshes."));
4046 (mesh_index < scene->mNumMeshes),
4049 unsigned int start_mesh =
4051 unsigned int end_mesh =
4056 std::vector<Point<spacedim>> vertices;
4057 std::vector<CellData<dim>> cells;
4061 unsigned int v_offset = 0;
4062 unsigned int c_offset = 0;
4064 constexpr std::array<unsigned int, 8> local_vertex_numbering = {
4065 {0, 1, 5, 4, 2, 3, 7, 6}};
4067 for (
unsigned int m = start_mesh; m < end_mesh; ++m)
4069 const aiMesh *mesh = scene->mMeshes[m];
4073 if ((dim == 2) && mesh->mPrimitiveTypes != aiPrimitiveType_POLYGON)
4076 ExcMessage(
"Incompatible mesh " + std::to_string(m) +
4077 "/" + std::to_string(scene->mNumMeshes)));
4080 else if ((dim == 1) && mesh->mPrimitiveTypes != aiPrimitiveType_LINE)
4083 ExcMessage(
"Incompatible mesh " + std::to_string(m) +
4084 "/" + std::to_string(scene->mNumMeshes)));
4088 const unsigned int n_vertices = mesh->mNumVertices;
4089 const aiVector3D *mVertices = mesh->mVertices;
4092 const unsigned int n_faces = mesh->mNumFaces;
4093 const aiFace *mFaces = mesh->mFaces;
4095 vertices.resize(v_offset + n_vertices);
4096 cells.resize(c_offset + n_faces);
4098 for (
unsigned int i = 0; i < n_vertices; ++i)
4099 for (
unsigned int d = 0; d < spacedim; ++d)
4100 vertices[i + v_offset][d] = mVertices[i][d];
4102 unsigned int valid_cell = c_offset;
4103 for (
unsigned int i = 0; i < n_faces; ++i)
4110 .vertices[dim == 3 ? local_vertex_numbering[f] :
4112 mFaces[i].mIndices[f] + v_offset;
4114 cells[valid_cell].material_id = m;
4120 ExcMessage(
"Face " + std::to_string(i) +
" of mesh " +
4121 std::to_string(m) +
" has " +
4122 std::to_string(mFaces[i].mNumIndices) +
4123 " vertices. We expected only " +
4128 cells.resize(valid_cell);
4133 v_offset += n_vertices;
4134 c_offset = valid_cell;
4141 if (remove_duplicates)
4146 unsigned int n_verts = 0;
4147 while (n_verts != vertices.size())
4149 n_verts = vertices.size();
4150 std::vector<unsigned int> considered_vertices;
4152 vertices, cells, subcelldata, considered_vertices, tol);
4156 apply_grid_fixup_functions(vertices, cells, subcelldata);
4157 tria->create_triangulation(vertices, cells, subcelldata);
4162 (void)remove_duplicates;
4164 (void)ignore_unsupported_types;
4171template <
int dim,
int spacedim>
4176 ExcMessage(
"The ugrid format reader currently supports only 2- and "
4177 "3-dimensional meshes."));
4185 unsigned int n_nodes, n_tris, n_quads, n_tets, n_pyramids, n_wedges, n_hexes;
4186 in >> n_nodes >> n_tris >> n_quads >> n_tets >> n_pyramids >> n_wedges >>
4190 n_tris + n_quads > 0,
4192 "When reading a 2-dimensional triangulation, "
4193 "there need to be more than zero triangles or quadrilaterals."));
4195 AssertThrow(n_tets + n_pyramids + n_wedges + n_hexes > 0,
4196 ExcMessage(
"When reading a 3-dimensional triangulation, "
4197 "there need to be more than zero tetrahedra, "
4198 "pyramids, wedges, or hexahedra."));
4201 std::vector<Point<spacedim>> vertices(n_nodes);
4208 for (
unsigned int d = spacedim; d < 3; ++d)
4215 "You are reading a mesh in spacedim=" + std::to_string(spacedim) +
4216 " but some of the vertex positions have trailing coordinates "
4217 "that are not zero."));
4222 std::vector<CellData<2>> objects_2d;
4223 objects_2d.reserve(n_tris + n_quads);
4224 for (
unsigned int i = 0; i < n_tris; ++i)
4230 for (
unsigned int &vertex_index :
object.vertices)
4235 objects_2d.emplace_back(
object);
4237 for (
unsigned int i = 0; i < n_quads; ++i)
4242 "Reading quadrilaterals is not currently implemented by the ugrid "
4243 "reader because we do not know the order of vertices and have no example "
4244 "to look at. If you have a test file, please contact us and/or help us "
4245 "implement this missing case."));
4252 for (
auto &
object : objects_2d)
4254 in >>
object.material_id;
4256 in >>
object.boundary_id;
4260 std::vector<CellData<3>> objects_3d;
4261 objects_3d.reserve(n_tets + n_pyramids + n_wedges + n_hexes);
4262 for (
unsigned int i = 0; i < n_tets; ++i)
4267 "Reading tetrahedra is not currently implemented by the ugrid "
4268 "reader because we do not know the order of vertices and have no example "
4269 "to look at. If you have a test file, please contact us and/or help us "
4270 "implement this missing case."));
4272 for (
unsigned int i = 0; i < n_pyramids; ++i)
4277 "Reading pyramids is not currently implemented by the ugrid "
4278 "reader because we do not know the order of vertices and have no example "
4279 "to look at. If you have a test file, please contact us and/or help us "
4280 "implement this missing case."));
4282 for (
unsigned int i = 0; i < n_wedges; ++i)
4287 "Reading wedges is not currently implemented by the ugrid "
4288 "reader because we do not know the order of vertices and have no example "
4289 "to look at. If you have a test file, please contact us and/or help us "
4290 "implement this missing case."));
4292 for (
unsigned int i = 0; i < n_hexes; ++i)
4297 "Reading hexahdrea is not currently implemented by the ugrid "
4298 "reader because we do not know the order of vertices and have no example "
4299 "to look at. If you have a test file, please contact us and/or help us "
4300 "implement this missing case."));
4323 unsigned int n_lines;
4325 std::vector<CellData<1>> objects_1d(n_lines);
4328 line.vertices.resize(2);
4331 for (
unsigned int &vertex_index : line.vertices)
4338 in >> line.boundary_id;
4342 if constexpr (dim == 2)
4346 tria->create_triangulation(vertices, objects_2d, face_data);
4354#ifdef DEAL_II_TRILINOS_WITH_SEACAS
4363 exodusii_name_to_type(
const std::string &type_name,
4364 const int n_nodes_per_element)
4370 std::string type_name_2 = type_name;
4371 std::transform(type_name_2.begin(),
4373 type_name_2.begin(),
4374 static_cast<int (*)(
int)
>(std::toupper));
4375 const std::string
numbers =
"0123456789";
4376 type_name_2.erase(std::find_first_of(type_name_2.begin(),
4383 if constexpr (dim == 1)
4385 if (type_name_2 ==
"BAR" || type_name_2 ==
"BEAM" ||
4386 type_name_2 ==
"EDGE" || type_name_2 ==
"TRUSS")
4389 else if constexpr (dim == 2)
4391 if (type_name_2 ==
"TRI" || type_name_2 ==
"TRIANGLE")
4393 else if (type_name_2 ==
"QUAD" || type_name_2 ==
"QUADRILATERAL")
4395 else if (type_name_2 ==
"SHELL")
4397 if (n_nodes_per_element == 3)
4403 else if constexpr (dim == 3)
4405 if (type_name_2 ==
"TET" || type_name_2 ==
"TETRA" ||
4406 type_name_2 ==
"TETRAHEDRON")
4408 else if (type_name_2 ==
"PYRA" || type_name_2 ==
"PYRAMID")
4410 else if (type_name_2 ==
"WEDGE")
4412 else if (type_name_2 ==
"HEX" || type_name_2 ==
"HEXAHEDRON")
4422 template <
int dim,
int spacedim = dim>
4423 std::pair<SubCellData, std::vector<std::vector<int>>>
4424 read_exodusii_sidesets(
const int ex_id,
4425 const int n_sidesets,
4427 const bool apply_all_indicators_to_manifolds)
4430 std::vector<std::vector<int>> b_or_m_id_to_sideset_ids;
4432 b_or_m_id_to_sideset_ids.emplace_back();
4438 if (dim == spacedim && n_sidesets > 0)
4440 std::vector<int> sideset_ids(n_sidesets);
4441 int ierr = ex_get_ids(ex_id, EX_SIDE_SET, sideset_ids.data());
4443 std::sort(sideset_ids.begin(), sideset_ids.end());
4450 std::size_t n_total_sides = 0;
4451 for (
const int &sideset_id : sideset_ids)
4454 int n_distribution_factors = -1;
4456 ierr = ex_get_set_param(ex_id,
4460 &n_distribution_factors);
4463 n_total_sides += std::size_t(n_sides);
4465 std::vector<std::pair<std::size_t, int>> face_sidesets;
4466 face_sidesets.reserve(n_total_sides);
4468 for (
const int &sideset_id : sideset_ids)
4471 int n_distribution_factors = -1;
4473 ierr = ex_get_set_param(ex_id,
4477 &n_distribution_factors);
4481 std::vector<int> elements(n_sides);
4482 std::vector<int> faces(n_sides);
4483 ierr = ex_get_set(ex_id,
4496 for (
int side_n = 0; side_n < n_sides; ++side_n)
4498 const long cell_n = elements[side_n] - 1;
4500 const long face_n = faces[side_n] - 1;
4502 const std::size_t face_id =
4504 face_sidesets.emplace_back(face_id, sideset_id);
4509 std::sort(face_sidesets.begin(), face_sidesets.end());
4514 std::deque<ArrayView<std::pair<std::size_t, int>>>
4515 face_id_to_sideset_ids;
4516 if (face_sidesets.size() > 0)
4518 auto start = face_sidesets.begin();
4519 for (
auto it = face_sidesets.begin() + 1; it < face_sidesets.end();
4521 if (start->first != it->first)
4523 face_id_to_sideset_ids.emplace_back(
4527 face_id_to_sideset_ids.emplace_back(
4534 std::stable_sort(face_id_to_sideset_ids.begin(),
4535 face_id_to_sideset_ids.end(),
4536 [](
const auto &a,
const auto &b) {
4537 return std::lexicographical_compare(
4542 [](const auto &c, const auto &d) {
4543 return c.second < d.second;
4548 subcelldata.
boundary_lines.reserve(face_id_to_sideset_ids.size());
4550 subcelldata.
boundary_quads.reserve(face_id_to_sideset_ids.size());
4552 std::vector<int> face_sideset_ids;
4553 for (
const auto &pairs : face_id_to_sideset_ids)
4555 const std::size_t face_id = pairs[0].first;
4556 Assert(std::all_of(pairs.begin(),
4558 [&](
const auto &a) {
4559 return a.first == face_id;
4562 face_sideset_ids.resize(pairs.size());
4563 for (std::size_t i = 0; i < pairs.size(); ++i)
4564 face_sideset_ids[i] = pairs[i].second;
4566 if (face_sideset_ids != b_or_m_id_to_sideset_ids.back())
4571 Assert(std::find(b_or_m_id_to_sideset_ids.begin(),
4572 b_or_m_id_to_sideset_ids.end(),
4573 face_sideset_ids) ==
4574 b_or_m_id_to_sideset_ids.end(),
4576 ++current_b_or_m_id;
4577 b_or_m_id_to_sideset_ids.emplace_back(face_sideset_ids.begin(),
4578 face_sideset_ids.end());
4579 Assert(current_b_or_m_id == b_or_m_id_to_sideset_ids.size() - 1,
4583 const unsigned int local_face_n =
4590 const unsigned int deal_face_n =
4592 const auto face_reference_cell =
4600 CellData<1> boundary_line(face_reference_cell.n_vertices());
4601 if (apply_all_indicators_to_manifolds)
4602 boundary_line.manifold_id = current_b_or_m_id;
4604 boundary_line.boundary_id = current_b_or_m_id;
4605 for (
unsigned int j = 0; j < face_reference_cell.n_vertices();
4607 boundary_line.vertices[j] =
4609 deal_face_n, j, 0)];
4615 CellData<2> boundary_quad(face_reference_cell.n_vertices());
4616 if (apply_all_indicators_to_manifolds)
4617 boundary_quad.manifold_id = current_b_or_m_id;
4619 boundary_quad.boundary_id = current_b_or_m_id;
4620 for (
unsigned int j = 0; j < face_reference_cell.n_vertices();
4622 boundary_quad.vertices[j] =
4624 deal_face_n, j, 0)];
4631 return std::make_pair(std::move(subcelldata),
4632 std::move(b_or_m_id_to_sideset_ids));
4637template <
int dim,
int spacedim>
4640 const std::string &filename,
4641 const bool apply_all_indicators_to_manifolds)
4643#ifdef DEAL_II_TRILINOS_WITH_SEACAS
4645 int component_word_size =
sizeof(double);
4647 int floating_point_word_size = 0;
4648 float ex_version = 0.0;
4650 const int ex_id = ex_open(filename.c_str(),
4652 &component_word_size,
4653 &floating_point_word_size,
4656 ExcMessage(
"ExodusII failed to open the specified input file."));
4659 std::vector<char> string_temp(MAX_LINE_LENGTH + 1,
'\0');
4660 int mesh_dimension = 0;
4663 int n_element_blocks = 0;
4667 int ierr = ex_get_init(ex_id,
4686 std::vector<Point<spacedim>> vertices;
4687 vertices.reserve(n_nodes);
4689 std::vector<double> xs(n_nodes);
4690 std::vector<double> ys(n_nodes);
4691 std::vector<double> zs(n_nodes);
4693 ierr = ex_get_coord(ex_id, xs.data(), ys.data(), zs.data());
4696 for (
int vertex_n = 0; vertex_n < n_nodes; ++vertex_n)
4701 vertices.emplace_back(xs[vertex_n]);
4704 vertices.emplace_back(xs[vertex_n], ys[vertex_n]);
4707 vertices.emplace_back(xs[vertex_n], ys[vertex_n], zs[vertex_n]);
4715 std::vector<int> element_block_ids(n_element_blocks);
4716 ierr = ex_get_ids(ex_id, EX_ELEM_BLOCK, element_block_ids.data());
4719 std::vector<CellData<dim>> cells;
4720 cells.reserve(n_elements);
4724 for (
const int element_block_id : element_block_ids)
4726 std::fill(string_temp.begin(), string_temp.end(),
'\0');
4727 int n_block_elements = 0;
4728 int n_nodes_per_element = 0;
4729 int n_edges_per_element = 0;
4730 int n_faces_per_element = 0;
4731 int n_attributes_per_element = 0;
4734 ierr = ex_get_block(ex_id,
4739 &n_nodes_per_element,
4740 &n_edges_per_element,
4741 &n_faces_per_element,
4742 &n_attributes_per_element);
4745 exodusii_name_to_type<dim>(string_temp.data(), n_nodes_per_element);
4748 "The ExodusII block " + std::to_string(element_block_id) +
4749 " with element type " + std::string(string_temp.data()) +
4750 " does not have a corresponding ReferenceCell<dim> with a"
4751 " dimension matching the topological mesh dimension " +
4752 std::to_string(dim) +
"."));
4759 std::vector<int> connection(n_nodes_per_element * n_block_elements);
4760 ierr = ex_get_conn(ex_id,
4768 for (
unsigned int elem_n = 0; elem_n < connection.size();
4769 elem_n += n_nodes_per_element)
4772 for (
const unsigned int i : type.vertex_indices())
4774 cell.
vertices[type.exodusii_vertex_to_deal_vertex(i)] =
4775 connection[elem_n + i] - 1;
4778 cells.push_back(std::move(cell));
4783 auto pair = read_exodusii_sidesets<dim, spacedim>(
4784 ex_id, n_sidesets, cells, apply_all_indicators_to_manifolds);
4785 ierr = ex_close(ex_id);
4788 apply_grid_fixup_functions(vertices, cells, pair.first);
4789 tria->create_triangulation(vertices, cells, pair.first);
4795 (void)apply_all_indicators_to_manifolds;
4802template <
int dim,
int spacedim>
4816 if (std::find_if(line.begin(), line.end(), [](
const char c) {
4821 for (
int i = line.size() - 1; i >= 0; --i)
4822 in.putback(line[i]);
4832template <
int dim,
int spacedim>
4835 const char comment_start)
4840 while (in.get(c) && c == comment_start)
4843 while (in.get() !=
'\n')
4858template <
int dim,
int spacedim>
4873 const std::vector<
Point<2>> &vertices,
4876 double min_x = vertices[cells[0].
vertices[0]][0],
4877 max_x = vertices[cells[0].
vertices[0]][0],
4878 min_y = vertices[cells[0].
vertices[0]][1],
4879 max_y = vertices[cells[0].
vertices[0]][1];
4881 for (
unsigned int i = 0; i < cells.size(); ++i)
4883 for (
const auto vertex : cells[i].vertices)
4885 const Point<2> &p = vertices[vertex];
4897 out <<
"# cell " << i << std::endl;
4899 for (
const auto vertex : cells[i].vertices)
4900 center += vertices[vertex];
4903 out <<
"set label \"" << i <<
"\" at " << center[0] <<
',' << center[1]
4904 <<
" center" << std::endl;
4907 for (
unsigned int f = 0; f < 2; ++f)
4908 out <<
"set arrow from " << vertices[cells[i].vertices[f]][0] <<
','
4909 << vertices[cells[i].vertices[f]][1] <<
" to "
4910 << vertices[cells[i].vertices[(f + 1) % 4]][0] <<
','
4911 << vertices[cells[i].
vertices[(f + 1) % 4]][1] << std::endl;
4913 for (
unsigned int f = 2; f < 4; ++f)
4914 out <<
"set arrow from " << vertices[cells[i].vertices[(f + 1) % 4]][0]
4915 <<
',' << vertices[cells[i].
vertices[(f + 1) % 4]][1] <<
" to "
4916 << vertices[cells[i].vertices[f]][0] <<
','
4917 << vertices[cells[i].vertices[f]][1] << std::endl;
4923 <<
"set nokey" << std::endl
4924 <<
"pl [" << min_x <<
':' << max_x <<
"][" << min_y <<
':' << max_y
4925 <<
"] " << min_y << std::endl
4926 <<
"pause -1" << std::endl;
4934 const std::vector<
Point<3>> &vertices,
4937 for (
const auto &cell : cells)
4940 out << vertices[cell.
vertices[0]] << std::endl
4941 << vertices[cell.
vertices[1]] << std::endl
4945 out << vertices[cell.
vertices[1]] << std::endl
4946 << vertices[cell.
vertices[2]] << std::endl
4950 out << vertices[cell.
vertices[3]] << std::endl
4951 << vertices[cell.
vertices[2]] << std::endl
4955 out << vertices[cell.
vertices[0]] << std::endl
4956 << vertices[cell.
vertices[3]] << std::endl
4960 out << vertices[cell.
vertices[4]] << std::endl
4961 << vertices[cell.
vertices[5]] << std::endl
4965 out << vertices[cell.
vertices[5]] << std::endl
4966 << vertices[cell.
vertices[6]] << std::endl
4970 out << vertices[cell.
vertices[7]] << std::endl
4971 << vertices[cell.
vertices[6]] << std::endl
4975 out << vertices[cell.
vertices[4]] << std::endl
4976 << vertices[cell.
vertices[7]] << std::endl
4980 out << vertices[cell.
vertices[0]] << std::endl
4981 << vertices[cell.
vertices[4]] << std::endl
4985 out << vertices[cell.
vertices[1]] << std::endl
4986 << vertices[cell.
vertices[5]] << std::endl
4990 out << vertices[cell.
vertices[2]] << std::endl
4991 << vertices[cell.
vertices[6]] << std::endl
4995 out << vertices[cell.
vertices[3]] << std::endl
4996 << vertices[cell.
vertices[7]] << std::endl
5004template <
int dim,
int spacedim>
5013 const std::string::size_type slashpos = filename.find_last_of(
'/');
5014 const std::string::size_type dotpos = filename.find_last_of(
'.');
5015 if (dotpos < filename.size() &&
5016 (dotpos > slashpos || slashpos == std::string::npos))
5018 std::string ext = filename.substr(dotpos + 1);
5033 std::ifstream in(filename);
5039template <
int dim,
int spacedim>
5090 ExcMessage(
"There is no read_assimp(istream &) function. "
5091 "Use the read_assimp(string &filename, ...) "
5092 "functions, instead."));
5097 ExcMessage(
"There is no read_exodusii(istream &) function. "
5098 "Use the read_exodusii(string &filename, ...) "
5099 "function, instead."));
5110template <
int dim,
int spacedim>
5141 return ".unknown_format";
5147template <
int dim,
int spacedim>
5151 if (format_name ==
"dbmesh")
5154 if (format_name ==
"exodusii")
5157 if (format_name ==
"msh")
5160 if (format_name ==
"unv")
5163 if (format_name ==
"vtk")
5166 if (format_name ==
"vtu")
5170 if (format_name ==
"inp")
5173 if (format_name ==
"ucd")
5176 if (format_name ==
"xda")
5179 if (format_name ==
"tecplot")
5182 if (format_name ==
"dat")
5185 if (format_name ==
"ugrid")
5188 if (format_name ==
"plt")
5207template <
int dim,
int spacedim>
5211 return "dbmesh|exodusii|msh|unv|vtk|vtu|ucd|abaqus|xda|tecplot|assimp|ugrid";
5218 template <
int dim,
int spacedim>
5219 Abaqus_to_UCD<dim, spacedim>::Abaqus_to_UCD()
5232 from_string(T &t,
const std::string &s, std::ios_base &(*f)(std::ios_base &))
5234 std::istringstream iss(s);
5235 return !(iss >> f >> t).fail();
5242 extract_int(
const std::string &s)
5245 for (
const char c : s)
5247 if (std::isdigit(c) != 0)
5254 from_string(number, tmp, std::dec);
5260 template <
int dim,
int spacedim>
5262 Abaqus_to_UCD<dim, spacedim>::read_in_abaqus(std::istream &input_stream)
5271 while (std::getline(input_stream, line))
5274 std::transform(line.begin(),
5277 static_cast<int (*)(
int)
>(std::toupper));
5279 if (line.compare(
"*HEADING") == 0 || line.compare(0, 2,
"**") == 0 ||
5280 line.compare(0, 5,
"*PART") == 0)
5283 while (std::getline(input_stream, line))
5289 else if (line.compare(0, 5,
"*NODE") == 0)
5298 while (std::getline(input_stream, line))
5303 std::vector<double> node(spacedim + 1);
5305 std::istringstream iss(line);
5307 for (
unsigned int i = 0; i < spacedim + 1; ++i)
5308 iss >> node[i] >> comma;
5310 node_list.push_back(node);
5313 else if (line.compare(0, 8,
"*ELEMENT") == 0)
5328 const std::string before_material =
"ELSET=EB";
5329 const std::size_t idx = line.find(before_material);
5330 if (idx != std::string::npos)
5332 from_string(material,
5333 line.substr(idx + before_material.size()),
5339 while (std::getline(input_stream, line))
5344 std::istringstream iss(line);
5350 const unsigned int n_data_per_cell =
5352 std::vector<double> cell(n_data_per_cell);
5353 for (
unsigned int i = 0; i < n_data_per_cell; ++i)
5354 iss >> cell[i] >> comma;
5357 cell[0] =
static_cast<double>(material);
5358 cell_list.push_back(cell);
5361 else if (line.compare(0, 8,
"*SURFACE") == 0)
5372 const std::string name_key =
"NAME=";
5373 const std::size_t name_idx_start =
5374 line.find(name_key) + name_key.size();
5375 std::size_t name_idx_end = line.find(
',', name_idx_start);
5376 if (name_idx_end == std::string::npos)
5378 name_idx_end = line.size();
5380 const int b_indicator = extract_int(
5381 line.substr(name_idx_start, name_idx_end - name_idx_start));
5388 while (std::getline(input_stream, line))
5394 std::transform(line.begin(),
5397 static_cast<int (*)(
int)
>(std::toupper));
5402 std::istringstream iss(line);
5409 std::vector<double> quad_node_list;
5410 const std::string elset_name = line.substr(0, line.find(
','));
5411 if (elsets_list.count(elset_name) != 0)
5415 iss >> stmp >> temp >> face_number;
5417 const std::vector<int> cells = elsets_list[elset_name];
5418 for (
const int cell : cells)
5422 get_global_node_numbers(el_idx, face_number);
5423 quad_node_list.insert(quad_node_list.begin(),
5426 face_list.push_back(quad_node_list);
5433 iss >> el_idx >> comma >> temp >> face_number;
5435 get_global_node_numbers(el_idx, face_number);
5436 quad_node_list.insert(quad_node_list.begin(), b_indicator);
5438 face_list.push_back(quad_node_list);
5442 else if (line.compare(0, 6,
"*ELSET") == 0)
5446 std::string elset_name;
5448 const std::string elset_key =
"*ELSET, ELSET=";
5449 const std::size_t idx = line.find(elset_key);
5450 if (idx != std::string::npos)
5452 const std::string comma =
",";
5453 const std::size_t first_comma = line.find(comma);
5454 const std::size_t second_comma =
5455 line.find(comma, first_comma + 1);
5456 const std::size_t elset_name_start =
5457 line.find(elset_key) + elset_key.size();
5458 elset_name = line.substr(elset_name_start,
5459 second_comma - elset_name_start);
5469 std::vector<int> elements;
5470 const std::size_t generate_idx = line.find(
"GENERATE");
5471 if (generate_idx != std::string::npos)
5474 std::getline(input_stream, line);
5475 std::istringstream iss(line);
5485 iss >> elid_start >> comma >> elid_end;
5489 "While reading an ABAQUS file, the reader "
5490 "expected a comma but found a <") +
5491 comma +
"> in the line <" + line +
">."));
5493 elid_start <= elid_end,
5496 "While reading an ABAQUS file, the reader encountered "
5497 "a GENERATE statement in which the upper bound <") +
5499 "> for the element numbers is not larger or equal "
5500 "than the lower bound <" +
5504 if (iss.rdbuf()->in_avail() != 0)
5505 iss >> comma >> elis_step;
5509 "While reading an ABAQUS file, the reader "
5510 "expected a comma but found a <") +
5511 comma +
"> in the line <" + line +
">."));
5513 for (
int i = elid_start; i <= elid_end; i += elis_step)
5514 elements.push_back(i);
5515 elsets_list[elset_name] = elements;
5517 std::getline(input_stream, line);
5522 while (std::getline(input_stream, line))
5527 std::istringstream iss(line);
5532 iss >> elid >> comma;
5537 "While reading an ABAQUS file, the reader "
5538 "expected a comma but found a <") +
5539 comma +
"> in the line <" + line +
">."));
5541 elements.push_back(elid);
5545 elsets_list[elset_name] = elements;
5550 else if (line.compare(0, 5,
"*NSET") == 0)
5553 while (std::getline(input_stream, line))
5559 else if (line.compare(0, 14,
"*SOLID SECTION") == 0)
5563 const std::string elset_key =
"ELSET=";
5564 const std::size_t elset_start =
5565 line.find(
"ELSET=") + elset_key.size();
5566 const std::size_t elset_end = line.find(
',', elset_start + 1);
5567 const std::string elset_name =
5568 line.substr(elset_start, elset_end - elset_start);
5573 const std::string material_key =
"MATERIAL=";
5574 const std::size_t last_equal =
5575 line.find(
"MATERIAL=") + material_key.size();
5576 const std::size_t material_id_start = line.find(
'-', last_equal);
5578 from_string(material_id,
5579 line.substr(material_id_start + 1),
5583 const std::vector<int> &elset_cells = elsets_list[elset_name];
5584 for (
const int elset_cell : elset_cells)
5586 const int cell_id = elset_cell - 1;
5594 template <
int dim,
int spacedim>
5596 Abaqus_to_UCD<dim, spacedim>::get_global_node_numbers(
5597 const int face_cell_no,
5598 const int face_cell_face_no)
const
5603 Assert((face_cell_no >= 1) &&
5604 (
static_cast<typename decltype(cell_list)::
size_type>(
5605 face_cell_no) <= cell_list.size()),
5614 if (face_cell_face_no == 1)
5616 quad_node_list[0] = cell_list[face_cell_no - 1][1];
5617 quad_node_list[1] = cell_list[face_cell_no - 1][2];
5619 else if (face_cell_face_no == 2)
5621 quad_node_list[0] = cell_list[face_cell_no - 1][2];
5622 quad_node_list[1] = cell_list[face_cell_no - 1][3];
5624 else if (face_cell_face_no == 3)
5626 quad_node_list[0] = cell_list[face_cell_no - 1][3];
5627 quad_node_list[1] = cell_list[face_cell_no - 1][4];
5629 else if (face_cell_face_no == 4)
5631 quad_node_list[0] = cell_list[face_cell_no - 1][4];
5632 quad_node_list[1] = cell_list[face_cell_no - 1][1];
5642 if (face_cell_face_no == 1)
5644 quad_node_list[0] = cell_list[face_cell_no - 1][1];
5645 quad_node_list[1] = cell_list[face_cell_no - 1][4];
5646 quad_node_list[2] = cell_list[face_cell_no - 1][3];
5647 quad_node_list[3] = cell_list[face_cell_no - 1][2];
5649 else if (face_cell_face_no == 2)
5651 quad_node_list[0] = cell_list[face_cell_no - 1][5];
5652 quad_node_list[1] = cell_list[face_cell_no - 1][8];
5653 quad_node_list[2] = cell_list[face_cell_no - 1][7];
5654 quad_node_list[3] = cell_list[face_cell_no - 1][6];
5656 else if (face_cell_face_no == 3)
5658 quad_node_list[0] = cell_list[face_cell_no - 1][1];
5659 quad_node_list[1] = cell_list[face_cell_no - 1][2];
5660 quad_node_list[2] = cell_list[face_cell_no - 1][6];
5661 quad_node_list[3] = cell_list[face_cell_no - 1][5];
5663 else if (face_cell_face_no == 4)
5665 quad_node_list[0] = cell_list[face_cell_no - 1][2];
5666 quad_node_list[1] = cell_list[face_cell_no - 1][3];
5667 quad_node_list[2] = cell_list[face_cell_no - 1][7];
5668 quad_node_list[3] = cell_list[face_cell_no - 1][6];
5670 else if (face_cell_face_no == 5)
5672 quad_node_list[0] = cell_list[face_cell_no - 1][3];
5673 quad_node_list[1] = cell_list[face_cell_no - 1][4];
5674 quad_node_list[2] = cell_list[face_cell_no - 1][8];
5675 quad_node_list[3] = cell_list[face_cell_no - 1][7];
5677 else if (face_cell_face_no == 6)
5679 quad_node_list[0] = cell_list[face_cell_no - 1][1];
5680 quad_node_list[1] = cell_list[face_cell_no - 1][5];
5681 quad_node_list[2] = cell_list[face_cell_no - 1][8];
5682 quad_node_list[3] = cell_list[face_cell_no - 1][4];
5695 return quad_node_list;
5698 template <
int dim,
int spacedim>
5700 Abaqus_to_UCD<dim, spacedim>::write_out_avs_ucd(std::ostream &output)
const
5709 const boost::io::ios_base_all_saver formatting_saver(output);
5713 output <<
"# Abaqus to UCD mesh conversion" << std::endl;
5714 output <<
"# Mesh type: AVS UCD" << std::endl;
5743 output << node_list.size() <<
"\t" << (cell_list.size() + face_list.size())
5744 <<
"\t0\t0\t0" << std::endl;
5747 output.precision(8);
5751 for (
const auto &node : node_list)
5754 output << node[0] <<
"\t";
5757 output.setf(std::ios::scientific, std::ios::floatfield);
5758 for (
unsigned int jj = 1; jj < spacedim + 1; ++jj)
5761 if (
std::abs(node[jj]) > tolerance)
5762 output << static_cast<double>(node[jj]) <<
"\t";
5764 output << 0.0 <<
"\t";
5767 output << 0.0 <<
"\t";
5769 output << std::endl;
5770 output.unsetf(std::ios::floatfield);
5774 for (
unsigned int ii = 0; ii < cell_list.size(); ++ii)
5776 output << ii + 1 <<
"\t" << cell_list[ii][0] <<
"\t"
5777 << (dim == 2 ?
"quad" :
"hex") <<
"\t";
5778 for (
unsigned int jj = 1; jj < GeometryInfo<dim>::vertices_per_cell + 1;
5780 output << cell_list[ii][jj] <<
"\t";
5782 output << std::endl;
5786 for (
unsigned int ii = 0; ii < face_list.size(); ++ii)
5788 output << ii + 1 <<
"\t" << face_list[ii][0] <<
"\t"
5789 << (dim == 2 ?
"line" :
"quad") <<
"\t";
5790 for (
unsigned int jj = 1; jj < GeometryInfo<dim>::vertices_per_face + 1;
5792 output << face_list[ii][jj] <<
"\t";
5794 output << std::endl;
5801#include "grid/grid_in.inst"
ArrayView< std::remove_reference_t< typename std::iterator_traits< Iterator >::reference >, MemorySpaceType > make_array_view(const Iterator begin, const Iterator end)
@ Default
Use GridIn::default_format stored in this object.
@ tecplot
Use read_tecplot().
@ dbmesh
Use read_dbmesh().
@ abaqus
Use read_abaqus().
@ assimp
Use read_assimp().
@ exodusii
Use read_exodusii().
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)
std::map< std::string, Vector< double > > cell_data
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)
ObserverPointer< Triangulation< dim, spacedim >, GridIn< dim, spacedim > > tria
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 size_type size() const noexcept
#define DEAL_II_NAMESPACE_OPEN
constexpr bool running_in_debug_mode()
#define DEAL_II_NAMESPACE_CLOSE
#define DEAL_II_FALLTHROUGH
const unsigned int DoFAccessor< structdim, dim, spacedim, level_dof_access >::dimension
#define DEAL_II_ASSERT_UNREACHABLE()
#define DEAL_II_NOT_IMPLEMENTED()
constexpr unsigned int GeometryInfo< dim >::vertices_per_cell
IteratorRange< active_cell_iterator > active_cell_iterators() const
static ::ExceptionBase & ExcIO()
static ::ExceptionBase & ExcInvalidDBMeshFormat()
static ::ExceptionBase & ExcFileNotOpen(std::string arg1)
static ::ExceptionBase & ExcNeedsAssimp()
static ::ExceptionBase & ExcUnknownIdentifier(std::string arg1)
static ::ExceptionBase & ExcInvalidGMSHInput(std::string arg1)
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcInvalidDBMESHInput(std::string arg1)
static ::ExceptionBase & ExcDBMESHWrongDimension(int arg1)
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
static ::ExceptionBase & ExcInvalidVertexIndex(int arg1, int arg2)
static ::ExceptionBase & ExcNeedsGMSHAPI()
static ::ExceptionBase & ExcNeedsExodusII()
static ::ExceptionBase & ExcNoTriangulationSelected()
#define AssertDimension(dim1, dim2)
#define AssertThrowMPI(error_code)
static ::ExceptionBase & ExcUnknownElementType(int arg1)
#define AssertThrowExodusII(error_code)
static ::ExceptionBase & ExcGmshNoCellInformation(unsigned int arg1, unsigned int arg2)
static ::ExceptionBase & ExcInvalidVertexIndexGmsh(int arg1, int arg2, int arg3)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcUnknownSectionType(int arg1)
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)
static ::ExceptionBase & ExcGmshUnsupportedGeometry(int arg1)
#define AssertThrow(cond, exc)
void consistently_order_cells(std::vector< CellData< dim > > &cells)
types::global_dof_index size_type
void reference_cell(Triangulation< dim, spacedim > &tria, const ReferenceCell< dim > &reference_cell)
constexpr ReferenceCell< 3 > Hexahedron
constexpr ReferenceCell< 2 > Quadrilateral
ReferenceCell< dim > n_vertices_to_reference_cell(const unsigned int n_vertices)
constexpr ReferenceCell< 1 > Line
constexpr ReferenceCell< 2 > Triangle
constexpr unsigned int max_n_vertices()
constexpr ReferenceCell< 3 > Tetrahedron
constexpr unsigned int max_n_faces()
constexpr ReferenceCell< dim > Invalid
constexpr ReferenceCell< 3 > Pyramid
constexpr const ReferenceCell< dim > & get_hypercube()
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 constexpr unsigned int vertices_per_cell
static constexpr std::array< unsigned int, vertices_per_cell > ucd_to_deal
static constexpr unsigned int vertices_per_face
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
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